Go语言方法规则

Posted Go程序员开发

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Go语言方法规则相关的知识,希望对你有一定的参考价值。

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 : %v\n", t1)
    t1.testT()
    t1.testP()

    t2 := &t1
    fmt.Printf("t2 is : %v\n", 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 : %v\n", st1)
    st1.testT()
    st1.testP()
    fmt.Printf("st2 is : %v\n", st2)
    st2.testT()
    st2.testP()

    sp1 := SP{&T{1}}
    sp2 := &sp1
    fmt.Printf("sp1 is : %v\n", sp1)
    sp1.testT()
    sp1.testP()
    fmt.Printf("sp2 is : %v\n", 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)
}

下一篇:

Go语言方法应用------敬请期待!

0基础学Go语言系列:

第一章 环境搭建

   1.1   

   1.2   

   1.3   

第二章 Go语言基础

   2.1   

   2.2   

   2.3   

   2.4   

   2.5   

第三章 Go语言程序结构

   3.1   

   3.2   

   3.3   

   3.4   

第四章 Go语言基本类型

   4.1   

   4.2   

   4.3   

   4.4   

   4.5   

第五章 Go语言引用类型

   5.1   

   5.2   

   5.3   

第六章 自定义类型与指针

   6.1   

   6.2   

   6.3   

第七章 流程控制

   7.1   

   7.2   

   7.3   

   7.4   

   7.5   

   7.6   

第八章 函数

   8.1   

   8.2   

   8.3   

   8.4   

   8.5   

   8.6   

   8.7   

第九章 方法

   9.1   


看完本文有收获?那就分享给更多人吧

以上是关于Go语言方法规则的主要内容,如果未能解决你的问题,请参考以下文章

go语言方法集规则

Go语言接口规则

你知道的Go切片扩容机制可能是错的

Go语言之基准测试

go语言代码规范指南

go语言怎么将二进制转为字符串