方法
Go没有类,方法跟函数的区别就是多了一个接收器Receiver
指针接收器,接收到的变量是指针形式的,意味着可以修改原变量。pointer receivers比value receivers更加常见。
函数的参数为指针必须显式传入一个指针,但如果是方法,Go解释器会隐式地将对象的指针传入,不需要显式取地址。同样的情况也发生在参数为值value的情况下,方法依然会进行隐式转换。
| 12
 3
 4
 5
 
 | var v VertexScaleFunc(v, 5)
 ScaleFunc(&v, 5)
 v.Scale(5)
 (&v).Scale(5)
 
 | 
指针接收器优点: 1.可以改变原变量;2.避免了传值拷贝
接口
接口也是一种type。没有类,感觉像是在type上去实现方法。可以看成(value, type)的元组。
接口内的值就算是nil,也可以调用它的方法,不会报空指针异常。但是如果是nil接口,就会报错。
| 12
 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处理
| 12
 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算法
| 12
 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接口
| 12
 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)
 }
 
 
 |