物以类聚,人以群分。事物必以类分,以形命名。开始一个个学习Go语言中有哪些数据类型,以及这些类型的特点。
Go语言中的方法是函数之外一个特别的概念。在Go语言的参考中说:
A type may have a method set associated with it (§Interface types, §Method declarations).
The method set of an interface type is its interface.
The method set of any other type T consists of all methods with receiver type T.
The method set of the corresponding pointer type *T is the set of all methods with receiver *T or T (that is, it also contains the method set of T).
Any other type has an empty method set.
In a method set, each method must have a unique method name.
意即,可以为所有自己定义的数据类型定义和该类型相关的方法。在Go里面没有严格的对象的概念,却有方法的概念。两个特殊的地方是:
1. interface是一个抽象的数据类型,它本身就是一个方法集。
2. 要注意type *T和type T不一样。实践中发现区别只在于指针上,type *T的方法操作原数据,type T的方法操作原数据的一个拷贝。type *T和type T定义的方法能互相用,不能重名。
3. 所有方法必需有单独的名字,并且不能动态重载。要完成动态重载可以用interface。
下面这个例子给自定义的浮点数建立Abs()方法:
package main
import (
"fmt"
"math"
)
type MyFloat float64
func (f MyFloat) Abs() float64 {
if f < 0 {
return float64( -f)
}
return float64(f)
}
func main() {
f : = MyFloat( -math.Sqrt2)
fmt.Println(f.Abs())
}
下面这个例子给结构体和结构体指针定义两个方法:
package main
import (
"fmt"
"math"
)
type Vertex1 struct {
X, Y float64
}
func (v Vertex1) Scale(f float64) {
v.X = v.X * f
v.Y = v.Y * f
}
func (v Vertex1) Abs() float64 {
return math.Sqrt(v.X *v.X + v.Y *v.Y)
}
//不能再定义方法(v *Vertex1) Abs() float64
type Vertex2 struct {
X, Y float64
}
func (v *Vertex2) Scale(f float64) {
v.X = v.X * f
v.Y = v.Y * f
}
func (v *Vertex2) Abs() float64 {
return math.Sqrt(v.X *v.X + v.Y *v.Y)
}
func main() {
v1 : = Vertex1{ 3, 4}
v1.Scale( 5)
fmt.Println(v1, v1.Abs())
pv1 : = &Vertex1{ 3, 4}
pv1.Scale( 5)
fmt.Println(pv1, pv1.Abs())
v2 : = Vertex2{ 3, 4}
v2.Scale( 5)
fmt.Println(v2, v2.Abs())
pv2 : = &Vertex2{ 3, 4}
pv2.Scale( 5)
fmt.Println(pv2, pv2.Abs())
}
/*
will out put:
{3, 4} 5
&{3, 4} 5
{15, 20} 25
&{15, 20} 25
*/