Go 18.0 专业五


03. 方法集

<h1>1. 方法集</h1> <p>Golang方法集 :每个类型都有与之关联的方法集,这会影响到接口实现规则。</p> <pre><code> • 类型 T 方法集包含全部 receiver T 方法。 • 类型 *T 方法集包含全部 receiver T + *T 方法。 • 如类型 S 包含匿名字段 T,则 S 和 *S 方法集包含 T 方法。 • 如类型 S 包含匿名字段 *T,则 S 和 *S 方法集包含 T + *T 方法。 • 不管嵌入 T 或 *T,*S 方法集总是包含 T + *T 方法。</code></pre> <p>用实例 value 和 pointer 调用方法 (含匿名字段) 不受方法集约束,编译器总是查找全部方法,并自动转换 receiver 实参。</p> <p>Go 语言中内部类型方法集提升的规则:</p> <p>类型 T 方法集包含全部 receiver T 方法。</p> <pre><code>package main import ( "fmt" ) type T struct { int } func (t T) test() { fmt.Println("类型 T 方法集包含全部 receiver T 方法。") } func main() { t1 := T{1} fmt.Printf("t1 is : %v\n", t1) t1.test() }</code></pre> <p>输出结果:</p> <pre><code> t1 is : {1} 类型 T 方法集包含全部 receiver T 方法。</code></pre> <p>类型 <code>*T</code> 方法集包含全部 <code>receiver T + *T</code> 方法。</p> <pre><code>package main import ( "fmt" ) type T struct { int } func (t T) testT() { fmt.Println("类型 *T 方法集包含全部 receiver T 方法。") } func (t *T) testP() { fmt.Println("类型 *T 方法集包含全部 receiver *T 方法。") } func main() { t1 := T{1} t2 := &amp;t1 fmt.Printf("t2 is : %v\n", t2) t2.testT() t2.testP() }</code></pre> <p>输出结果:</p> <pre><code> t2 is : &amp;{1} 类型 *T 方法集包含全部 receiver T 方法。 类型 *T 方法集包含全部 receiver *T 方法。</code></pre> <p>给定一个结构体类型 S 和一个命名为 T 的类型,方法提升像下面规定的这样被包含在结构体方法集中:</p> <p>如类型 S 包含匿名字段 T,则 S 和 <code>*S</code> 方法集包含 T 方法。</p> <p>这条规则说的是当我们嵌入一个类型,嵌入类型的接受者为值类型的方法将被提升,可以被外部类型的值和指针调用。</p> <pre><code>package main import ( "fmt" ) type S struct { T } type T struct { int } func (t T) testT() { fmt.Println("如类型 S 包含匿名字段 T,则 S 和 *S 方法集包含 T 方法。") } func main() { s1 := S{T{1}} s2 := &amp;s1 fmt.Printf("s1 is : %v\n", s1) s1.testT() fmt.Printf("s2 is : %v\n", s2) s2.testT() }</code></pre> <p>输出结果:</p> <pre><code> s1 is : {{1}} 如类型 S 包含匿名字段 T,则 S 和 *S 方法集包含 T 方法。 s2 is : &amp;{{1}} 如类型 S 包含匿名字段 T,则 S 和 *S 方法集包含 T 方法。</code></pre> <p>如类型 S 包含匿名字段 <code>*T</code>,则 S 和 <code>*S</code> 方法集包含 <code>T + *T</code> 方法。</p> <p>这条规则说的是当我们嵌入一个类型的指针,嵌入类型的接受者为值类型或指针类型的方法将被提升,可以被外部类型的值或者指针调用。</p> <pre><code>package main import ( "fmt" ) type S struct { T } type T struct { int } func (t T) testT() { fmt.Println("如类型 S 包含匿名字段 *T,则 S 和 *S 方法集包含 T 方法") } func (t *T) testP() { fmt.Println("如类型 S 包含匿名字段 *T,则 S 和 *S 方法集包含 *T 方法") } func main() { s1 := S{T{1}} s2 := &amp;s1 fmt.Printf("s1 is : %v\n", s1) s1.testT() s1.testP() fmt.Printf("s2 is : %v\n", s2) s2.testT() s2.testP() }</code></pre> <p>输出结果:</p> <pre><code> s1 is : {{1}} 如类型 S 包含匿名字段 *T,则 S 和 *S 方法集包含 T 方法 如类型 S 包含匿名字段 *T,则 S 和 *S 方法集包含 *T 方法 s2 is : &amp;{{1}} 如类型 S 包含匿名字段 *T,则 S 和 *S 方法集包含 T 方法 如类型 S 包含匿名字段 *T,则 S 和 *S 方法集包含 *T 方法</code></pre>

页面列表

ITEM_HTML