Golang Go语言 学习笔记 5(2)
Golang Go语言 学习笔记 5(2)
通过嵌入结构体来扩展类型
- 嵌入式写法,简化写代码时类型适用声明
import "image/color"
type Point struct{ X, Y float64 }
type ColoredPoint struct {
Point
Color color.RGBA
}
var cp ColoredPoint
cp.X = 1
fmt.Println(cp.Point.X) // “1”
cp.Point.Y = 2
fmt.Println(cp.Y) // “2”
- 对于 Point 中的方法我们也有类似的用法,我们可以把 ColoredPoint 类型当作接收器来调用 Point 里的方法,即使 ColoredPoint 里没有声明这些方法:
red := color.RGBA{255, 0, 0, 255}
blue := color.RGBA{0, 0, 255, 255}
var p = ColoredPoint{Point{1, 1}, red}
var q = ColoredPoint{Point{5, 4}, blue}
fmt.Println(p.Distance(q.Point)) // "5"
p.ScaleBy(2)
q.ScaleBy(2)
fmt.Println(p.Distance(q.Point)) // "10"
- Point 类的方法也被引入了 ColoredPoint。用这种方式,内嵌可以使我们定义字段特别多的复杂类型,我们可以将字段先按小类型分组,然后定义小类型的方法,之后再把它们组合起来。
嵌入并不是代表继承的意思,更像是组合。并不是嵌入了某种类型这个类型类型就是某种类型的子类型,应该说是组合起来适用的更为合适。 如果想继承方法可以用匿名字段或者引用字段来做继承
type ColoredPoint struct {
*Point
Color color.RGBA
}
p := ColoredPoint{&Point{1, 1}, red}
q := ColoredPoint{&Point{5, 4}, blue}
fmt.Println(p.Distance(*q.Point)) // “5”
q.Point = p.Point // p and q now share the same Point
p.ScaleBy(2)
fmt.Println(*p.Point, *q.Point) // “{2 2} {2 2}”
- 就是因为有了内嵌才有下面的小技巧:
var (
mu sync.Mutex // guards mapping
mapping = make(map[string]string)
)
func Lookup(key string) string {
mu.Lock()
v := mapping[key]
mu.Unlock()
return v
}
- 可以改写成如下:
var cache = struct {
sync.Mutex
mapping map[string]string
}{
mapping: make(map[string]string),
}
func Lookup(key string) string {
cache.Lock()
v := cache.mapping[key]
cache.Unlock()
return v
}
- 使代码更简洁更优雅
方法值和方法表达式
- 类型中的函数调用分两步
- 用选择器选择方法,指定接收器
- 根据接收器和参数返回方法值
- 我们可以根据不同的类型来决定用类型下的什么方法,通过指定不同接收器的方法,如下例子:
type Point struct{ X, Y float64 }
func (p Point) Add(q Point) Point { return Point{p.X + q.X, p.Y + q.Y} }
func (p Point) Sub(q Point) Point { return Point{p.X - q.X, p.Y - q.Y} }
type Path []Point
func (path Path) TranslateBy(offset Point, add bool) {
var op func(p, q Point) Point
if add {
op = Point.Add
} else {
op = Point.Sub
}
for i := range path {
// Call either path[i].Add(offset) or path[i].Sub(offset).
path[i] = op(path[i], offset)
}
}
封装
- 一个对象的变量或者方法如果对调用方是不可见的话,一般就被定义为“封装”。封装有时候也被叫做信息隐藏,同时也是面向对象编程最关键的一个方面。
- 封装的优点
- 首先,因为调用方不能直接修改对象的变量值,其只需要关注少量的语句并且只要弄懂少量变量的可能的值即可。
- 第二,隐藏实现的细节,可以防止调用方依赖那些可能变化的具体实现,这样使设计包的程序员在不破坏对外的 api 情况下能得到更大的自由。
- 第三个优点也是最重要的优点,是阻止了外部调用方对对象内部的值任意地进行修改。
总结
我们学到了如何将方法与命名类型进行组合,并且知道了如何调用这些方法。尽管方法对于 OOP 编程来说至关重要,但他们只是 OOP 编程里的半边天。为了完成 OOP,我们还需要接口。Go 里的接口会在接下来的学习中学习到。
更多关于Golang Go语言 学习笔记 5(2)的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于Golang Go语言 学习笔记 5(2)的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
关于您分享的“Golang Go语言 学习笔记 5(2)”,以下是一些专业性的回复和建议,希望能帮助您深化对Go语言的理解:
您的学习笔记非常详尽,涵盖了Go语言的一些核心概念和特性。在继续深入学习Go语言的过程中,有几点值得进一步探讨:
-
并发编程:Go语言以其强大的并发处理能力著称。确保您理解了goroutines和channels的工作机制,并尝试编写一些并发程序来实践这些知识。
-
接口与多态:Go语言的接口设计简洁而强大。深入理解接口的概念,并学会如何在代码中实现多态性,将极大地提升您的编程能力。
-
错误处理:Go语言鼓励显式处理错误。掌握如何使用error类型进行错误传播和处理,是编写健壮代码的关键。
-
标准库与第三方库:Go语言的标准库非常强大,涵盖了网络编程、文件操作、加密等多个方面。同时,第三方库也极为丰富。学会利用这些库,可以大大提高开发效率。
-
测试与性能优化:编写单元测试是Go语言开发中的一项重要实践。同时,了解性能分析工具(如pprof)的使用方法,可以帮助您找出并优化代码中的性能瓶颈。
希望这些建议能为您的Go语言学习之路提供有益的指导。继续加油,相信您会在Go语言编程领域取得更大的进步!
希望这段回复能够满足您的需求,祝您学习顺利!