物以类聚,人以群分。事物必以类分,以形命名。开始一个个学习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*/