老男孩教育专注IT教育10余年,只培养IT技术精英

全国免费咨询电话(渠道合作):400-609-2893

GO语言常用的方法规则!GO培训机构

老男孩IT教育

行业新闻

2021年2月21日 16:04

根据调用者不同,方法分为两种表现形式:方法(method value)、方法表达式(method expression)。

  根据调用者不同,方法分为两种表现形式:方法(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)
}

  老男孩教育专注Linux云计算运维工程师、Python全栈+人工智能、Python自动化运维开发、网络安全、数据分析、新媒体运营、MySQLDBA开发、K8S微服务、Go语言等互联网课程培训。欢迎对it行业感兴趣的朋友们来公司考察及学习。

  推荐阅读:

  Go语言sort包排序!老男孩IT教育

  python常用的工具包含什么?老男孩python线下班

  Python代码区分大小写吗?python学习教程

本文经授权发布,不代表老男孩教育立场。如若转载请联系原作者。