Golang理解-匿名结构体
结构体嵌套go中使用结构体嵌套来扩展类型 嵌入到结构体中的字段,完全可以当作自己是自己的字段 import "image/color" type Point struct{ X,Y float64 } type ColoredPoint struct { Point Color color.RGBA } ColoredPoint嵌套了Point结构体,从而ColoredPoint就拥有了Point的字段X,Y。 可以直接通过"."操作符来访问; 如果Point拥有自己的方法,那么ColoredPoint也拥有这些方法,而不需要在自己定义 用这种方式,内嵌可以使我们定义字段特别多的复杂类型,我们可以将字段先按小类型分组,然后定义小类型的方法,之后再把它们组合起来。
var p = ColoredPoint{Point{1,1},red} var q = ColoredPoint{Point{5,4},blue} fmt.Println(p.Distance(q.Point)) // "10" p.Distance(q) // compile error: cannot use q (ColoredPoint) as Point 一个ColoredPoint并不是一个Point,但他"has a" Point,并且它有从Point类里引入的Distance和ScaleBy方法。如果你喜欢从实现的角度来考虑问题,内嵌字段会指导编译器去生成额外的包装方法来委托已经声明好的方法,和下面的形式是等价的: func (p ColoredPoint) Distance(q Point) float64 { return p.Point.Distance(q) } func (p *ColoredPoint) ScaleBy(factor float64) { p.Point.ScaleBy(factor) } 当Point.Distance被第一个包装方法调用时,它的接收器值是p.Point,而不是p,当然了,在Point类的方法里,你是访问不到ColoredPoint的任何字段的。 编译器查找方法的顺序:
如果选择器有二义性的话编译器会报错,比如你有一个字段觉Distance,然后一个方法也叫Distance,那么选择器就不知道你想使用的是哪个,编译器就会报错; 匿名结构体匿名结构体就是在嵌入时,不指定名称,这样子会将匿名结果体的所有方法引入到该类型中;这样在使用时有很多便利:例如下面对map的操作; 我们知道map时非线程安全的,会存在读或写竞争,我们需要在对map的操作时进行加锁; package main // 匿名结构提嵌套,可以引入匿名结构体所有的方法 import ( "fmt" "sync" ) type safeMap struct { sync.Mutex mapping map[string]string } // 获取map中元素的值 func (m safeMap) Get(key string) (value string) { // 引入了sync.Mutex的加锁和解锁方法 m.Lock() value = m.mapping[key] m.Unlock() return } func main() { m := map[string]string{ "a" : "alpha","i" : "integer",} cache := safeMap{ mapping: m,} fmt.Println(cache.Get("a")) fmt.Println(cache.Get("i")) } 因为sync.Mutex字段也被嵌入到了这个struct里,其Lock和Unlock方法也就都被引入到了这个匿名结构中了,这让我们能够以一个简单明了的语法来对其进行加锁解锁操作。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |