方法
Go没有类,方法跟函数的区别就是多了一个接收器Receiver
指针接收器,接收到的变量是指针形式的,意味着可以修改原变量。pointer receivers比value receivers更加常见。
函数的参数为指针必须显式传入一个指针,但如果是方法,Go解释器会隐式地将对象的指针传入,不需要显式取地址。同样的情况也发生在参数为值value的情况下,方法依然会进行隐式转换。
1 2 3 4 5
| var v Vertex ScaleFunc(v, 5) ScaleFunc(&v, 5) v.Scale(5) (&v).Scale(5)
|
指针接收器优点: 1.可以改变原变量;2.避免了传值拷贝
接口
接口也是一种type。没有类,感觉像是在type上去实现方法。可以看成(value, type)的元组。
接口内的值就算是nil,也可以调用它的方法,不会报空指针异常。但是如果是nil接口,就会报错。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| func (t *T) M() {} var t *T t.M()
var i I i.M()
type I interface { M() } type F float64 func (f F) M() {} var i I = F(1.2) i.M()
func describe(i interface{}) { fmt.Printf("(%v, %T)\n", i, i) }
t, ok := i.(T)
|
Error处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| type ErrNegativeSqrt float64
func (e ErrNegativeSqrt) Error() string { return fmt.Sprintf("cannot Sqrt negative number: %v", float64(e)) }
func Sqrt(x float64) (float64, error) { if x > 0 { z := 1.0 for last_z := z; math.Abs(last_z-z) > 0.00001; last_z = z { z -= (z*z - x) / (2*z) } return z, nil } return 0, ErrNegativeSqrt(x) }
func main() { fmt.Println(Sqrt(2)) fmt.Println(Sqrt(-2)) }
type MyReader struct{}
func (m MyReader) Read(bytes []byte) (n int, e error) { for i:=0; i<len(bytes); i++ { bytes[i]='A' } return len(bytes), nil }
|
在io.Reader上包装,实现rot13算法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| package main
import ( "io" "os" "strings" )
type rot13Reader struct { r io.Reader }
func transform(b byte) (bb byte) { if (b >= 65 && b < 78) || (b >= 97 && b < 110) { bb = b+13 } else if (b >= 78 && b < 91) || (b >= 110 && b < 123) { bb = b-13 } return bb }
func (rot rot13Reader) Read(b []byte) (int, error) { n, e := rot.r.Read(b) for i:=0; i<n; i++ { b[i] = transform(b[i]) } return n, e }
func main() { s := strings.NewReader("Lbh penpxrq gur pbqr!") r := rot13Reader{s} io.Copy(os.Stdout, &r) }
|
实现Image接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| package main
import ( "golang.org/x/tour/pic" "image/color" "image" )
type Image struct{ w int h int }
func (img Image) ColorModel() color.Model { return color.RGBAModel }
func (img Image) Bounds() image.Rectangle { return image.Rect(0, 0, img.w, img.h) }
func (img Image) At(x, y int) color.Color { v := uint8(x^y) return color.RGBA{v, v, 255, 255} }
func main() { m := Image{w:200, h:200} pic.ShowImage(m) }
|