注:本章的主要内容来自于: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
String() string
}
通过这个接口可以用来自定义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)
}
}