注:本章的主要内容来自于:http://go-tour-zh.appspot.com/methods/1
方法:
1. Go 没有类。然而,可以在结构体类型上定义方法。例如:
package main import ( "fmt" "math" ) type Vertex struct { X, Y float64 } func (v *Vertex) Abs() float64 { //这里面定义了结构提Vertex这个结构体的方法 return math.Sqrt(v.X*v.X + v.Y*v.Y) } func main() { v := &Vertex{3, 4} fmt.Println(v.Abs()) }
//运行结果是 5
2. 可以对包中的 任意 类型(以type定义的类)定义任意方法,而不仅仅是针对结构体。但是,不能对来自其他包的类型或基础类型定义方法。
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())过这个接口可以用来自定义fmt.Println() }
过这个接口可以用来自定义fmt.Println()
3. 有时候我们需要将接受方法的对象定义为指针,这样可以有两个效果:
1) 可以提高参数传递的效率,不用拷贝。
2) 修改接收者指向的值。
接口:
1. 接口类型是由一种方法定义的集合,接口定义的方式是:type Abser interface { }
例如下面的这段代码
package main import ( "fmt" "math" ) type Abser interface { //这里定义了接口 Abser,具有方法Abs(), 这个方法分别由MyFloat类以及Vertex类调用 Abs() float64 } func main() { var a Abser f := MyFloat(-math.Sqrt2) v := Vertex{3, 4} a = f // a MyFloat 实现了 Abser fmt.Println(a.Abs()) a = &v // a *Vertex 实现了 Abse fmt.Println(a.Abs()) } type MyFloat float64 func (f MyFloat) Abs() float64 { if f < 0 { return float64(-f) } return float64(f) } type Vertex struct { X, Y float64 } func (v *Vertex) Abs() float64 { return math.Sqrt(v.X*v.X + v.Y*v.Y) }
2. 介绍一个特殊的接口, fmt包中定义的Stringer
通过这个接口可以用来自定义fmt.Println(), 例如下面的这个例子
package main import "fmt" type Person struct { Name string Age int } func (p Person) String() string { return fmt.Sprintf("%v (%v years)", p.Name, p.Age) } func main() { a := Person{"Arthur Dent", 42} z := Person{"Zaphod Beeblebrox", 9001} fmt.Println(a, z) } //输出格式是: Arthur Dent (42 years) Zaphod Beeblebrox (9001 years)
3. 与此类似的接口是 error 的一个内建的接口, 可用来自定义error 的格式
type error interface {
Error() string
}
//例如下面:
package main import ( "fmt" "time" ) type MyError struct { When time.Time What string } func (e *MyError) Error() string { return fmt.Sprintf("at %v, %s", e.When, e.What) } func run() error { return &MyError{ time.Now(), "it didn't work", } } func main() { if err := run(); err != nil { fmt.Println(err) } }