Golang 没有类,只有结构体。不过Golang可以在结构体类型上定义方法,其实就是配合结构体的函数。方法和之前讲过的函数是有些小区别的——对应的结构体信息(也叫“方法接受者”),出现在方法定义中。
猫哥语:有Golang特色的方法。
1. 结构体方法的定义格式:
func (var *Struct_Name) FuncName( var0, var1... ) return type { }
来看个最简单的例子:
package main
import "fmt"
type Rectangle struct {
x, y float32
}
func (v *Rectangle) Area() float32 {
return v.x * v.y
}
func (v *Rectangle) Circle() float32 {
return (v.x + v.y) * 2
}
func main() {
v := &Rectangle {3.5, 4.5}
fmt.Println(v.Area())
fmt.Println(v.Circle())
}
# 输出
15.75
16
2. 可以对任何type define的类型绑定方法
来看这个例子:
package main
import "fmt"
type myInteger int
func (i myInteger) Abs() int {
if i < 0 {
return int(-i)
}
return int(i)
}
func main() {
var inx myInteger
inx = -100
fmt.Println(inx.Abs())
}
# 输出:
100
3. 方法可以与命名类型或命名类型的指针关联。
刚刚看到的两个例子中的方法。一个是在*Rectangle指针类型上,而另一个在 myInteger 值类型上。
有两个原因需要使用指针接收者:
首先,避免在每个方法调用中拷贝值(如果值类型是大的结构体的话会更有效率);
其次,方法可以修改接收者指向的值。
来看下面这个对比的例子,就明白了。
package main
import (
"fmt"
"math"
)
type Vertex struct {
X, Y float64
}
func (v *Vertex) Belarger(f float64) {
v.X = v.X * f
v.Y = v.Y * f
}
func (v Vertex) Belarger1(f float64) {
v.X = v.X * f
v.Y = v.Y * f
}
func (v *Vertex) Distance() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
func main() {
v := &Vertex{3.0, 4.0}
fmt.Println("Original: ", v, v.Distance())
fmt.Println("----------------------------")
v.Belarger1(5.0)
fmt.Println("After no pointer method: ",v, v.Distance())
fmt.Println("----------------------------")
v.Belarger(5.0)
fmt.Println("After pointer method: ", v, v.Distance())
fmt.Println("----------------------------")
}
# 输出:
Original: &{3 4} 5
----------------------------
After no pointer method: &{3 4} 5
----------------------------
After pointer method: &{15 20} 25
Belarger用的指针的,所以结构体里的值改变了;与之对比的Belarger1用的类型的,没用指针,结构体里的值没有跟着变。