Skip to content

Latest commit

 

History

History
65 lines (36 loc) · 2.55 KB

ch6.md

File metadata and controls

65 lines (36 loc) · 2.55 KB

第六章 方法

  • 面向对象就是使用方法来描述每个数据结构的属性和操作

6.1 方法声明

  • 在同一个结构体中,方法和字段来自同一个命名空间。所以不能同名。

  • 可以将方法绑定到任何类型(数字,字符串,slice,map,函数)上,方便的为简单的类型定义附加的行为。

6.2 指针接收者的方法

  • 调用方法时,接收者也会被复制。如果接收者太大或者希望更新接收者,就应该定义指针接收者的方法。

  • 真实的程序中,如果类型的任何一个方法使用指针接收者,那么所有的方法都应该使用指针接收者。

  • 不允许本身是指针的类型进行方法声明。

  • 如果方法定义中的接收者类型和实际调用方法的类型不符,编译器会做隐式转换

    type T struct {}
    
    func (t *T)method() { /*...*/}
    v := T{}
    v.method()   //合法,编译器隐式转换为 &t
    
    func (t T)method2() {/*...*/}
    pv := &T{}
    pv.method2()    // 合法,编译器隐式插入 * 操作符
  • 如果类型T的方法的接收者都是T(非*T),那么复制它的实例是安全的。如果有方法的接收者是指针,应该避免复制T的实例。

  • nil 是一个合法的接收者,在有把 nil 指针接收者方法中,应在方法内检查接收者是否是 nil,避免例如向值为 nil 的map 添加元素。

  • 对于引用类型,例如map,在方法内对 map 变量数据结构的改变,例如键值对的改变,对方法调用者是可见的。但 map 变量自身是副本,对变量本身的改变,例如 m = nil, 对调用者是不可见的

6.3 通过结构体内嵌组成类型

  • 如果结构体有内嵌成员,这个结构体可以直接调用内嵌成员的方法。编译器会生成额外的包装方法调用内嵌成员声明的方法。

6.4 方法变量与表达式

  • 方法也可以通过方法表达式转换为函数来使用。函数只需要提供实参而不需要提供接收者就能够调用。

  • 方法表达式写为 T.f 或者(*T).f,可以赋值给方法变量

  • 调用方法变量时需把接收者作为第一个形参

6.5 示例:位向量

6.6 封装

  • 封装一个对象,必须使用结构体内非导出的字段。

  • 封装提供三个好处

    • 使用方不能直接修改对象的变量,所以不需要更多的语句检查变量的值

    • 隐藏实现细节防止使用方依赖的属性发生改变

    • 防止使用者肆意改变对象内的变量

  • Go中习惯省略方法中的Get,Fetch等冗余动词前缀