Go语言方法规则
根据调用者不同,方法分为两种表现形式:方法(method value)、方法表达式(method expression)。
两者都可像普通函数那样赋值和传参,区别在于 方法 (method value)绑定了实例,而方法表达式(method expression)必须显式传参。
直接调用
直接调用,类型 T 和 *T 上的方法集是互相继承的。
package main import ( "fmt" ) type T struct { int } func (t T) testT() { fmt.Println("接受者为 T ") } func (t *T) testP() { fmt.Println("接受者为 *T ") } func main() { t1 := T{1} fmt.Printf("t1 is : %vn", t1) t1.testT() t1.testP() t2 := &t1 fmt.Printf("t2 is : %vn", t2) t2.testT() t2.testP() }
直接调用,类型 S 包含匿名字段 *T 或 T ,则 S 和 *S 方法集包含 T 和 *T 上的方法集是互相继承的。
package main import ( "fmt" ) type ST struct { T } type SP struct { *T } type T struct { int } func (t T) testT() { fmt.Println("类型 S 包含匿名字段 *T 或 T ,则 S 和 *S 方法集包含 T 方法") } func (t *T) testP() { fmt.Println("类型 S 包含匿名字段 *T 或 T ,则 S 和 *S 方法集包含 *T 方法") } func main() { st1 := ST{T{1}} st2 := &st1 fmt.Printf("st1 is : %vn", st1) st1.testT() st1.testP() fmt.Printf("st2 is : %vn", st2) st2.testT() st2.testP() sp1 := SP{&T{1}} sp2 := &sp1 fmt.Printf("sp1 is : %vn", sp1) sp1.testT() sp1.testP() fmt.Printf("sp2 is : %vn", sp2) sp2.testT() sp2.testP() }
隐式传递调用
接受者隐式传递,类型 T 和 *T 上的方法集是互相继承的。
package main import ( "fmt" ) type T struct { string } func (t T) testT() { fmt.Println("接受者为 T ") } func (t *T) testP() { fmt.Println("接受者为 *T ") } func main() { t := T{"oldboy"} methodValue1 := t.testT methodValue1() methodValue2 := (&t).testT methodValue2() methodValue3 := t.testP methodValue3() methodValue4 := (&t).testP methodValue4() }
接受者隐式传递,类型 S 包含匿名字段 *T 或 T ,则 S 和 *S 方法集包含 T 和 *T 上的方法集是互相继承的。
package main import ( "fmt" ) type ST struct { T } type SP struct { *T } type T struct { string } func (t T) testT() { fmt.Println("类型 S 包含匿名字段 *T 或 T ,则 S 和 *S 方法集包含 T 方法") } func (t *T) testP() { fmt.Println("类型 S 包含匿名字段 *T 或 T ,则 S 和 *S 方法集包含 *T 方法") } func main() { st1 := ST{T{"oldboy"}} methodValue1 := st1.testT methodValue1() methodValue2 := (&st1).testT methodValue2() methodValue3 := st1.testP methodValue3() methodValue4 := (&st1).testP methodValue4() sp1 := SP{&T{"oldboy"}} methodValue5 := sp1.testT methodValue5() methodValue6 := (&sp1).testT methodValue6() methodValue7 := sp1.testP methodValue7() methodValue8 := (&sp1).testP methodValue8() }
显式传递调用
接受者显示传值,类型 T 的可调用方法集包含接受者为 T 的所有方法,不包含接受者为 *T 的方法。类型 *T 的可调用方法集包含接受者为 *T 或 T 的所有方法集。
package main import ( "fmt" ) type T struct { string } func (t T) testT() { fmt.Println("接受者为 T ") } func (t *T) testP() { fmt.Println("接受者为 *T ") } func main() { t := T{"oldboy"} expression1 := T.testT expression1(t) expression2 := (*T).testT expression2(&t) // expression3 := T.testP // expression3(t) expression4 := (*T).testP expression4(&t) }
接受者显示传值,类型 S 包含匿名字段 *T ,则 S 和 *S 方法集包含 T 和 *T 上的方法集是互相继承的。
类型 S 包含匿名字段 T ,类型 S 的可调用方法集包含接受者为 T 的所有方法,不包含接受者为 *T 的方法。类型 *S 的可调用方法集包含接受者为 *T 或 T 的所有方法集。
package main import ( "fmt" ) type ST struct { T } type SP struct { *T } type T struct { string } func (t T) testT() { fmt.Println("类型 S 包含匿名字段 *T 或 T ,则 S 和 *S 方法集包含 T 方法") } func (t *T) testP() { fmt.Println("类型 S 包含匿名字段 *T 或 T ,则 S 和 *S 方法集包含 *T 方法") } func main() { st1 := ST{T{"oldboy"}} expression1 := ST.testT expression1(st1) expression2 := (*ST).testT expression2(&st1) // expression3 := ST.testP // expression3(st1) expression4 := (*ST).testP expression4(&st1) sp1 := SP{&T{"oldboy"}} expression5 := SP.testT expression5(sp1) expression6 := (*SP).testT expression6(&sp1) expression7 := SP.testP expression7(sp1) expression8 := (*SP).testP expression8(&sp1) }
特别声明:以上文章内容仅代表作者本人观点,不代表变化吧观点或立场。如有关于作品内容、版权或其它问题请于作品发表后的30日内与变化吧联系。
- 赞助本站
- 微信扫一扫
- 加入Q群
- QQ扫一扫
评论