当前位置: 代码迷 >> 综合 >> golang-方法
  详细解决方案

golang-方法

热度:85   发布时间:2023-10-13 09:19:29.0

go语言中通常是为自定义类型定义方法,同时要求方法的定义和类型的定义必须在同一个包内。(不能为int、bool等预声明类型定义方法,因为他们的作用域是全局)

首先介绍一下c/c++与go语言结构体指针的区别:

#include <iostream>
#include<map>
using namespace std;struct T{
    int a;
};int main(){
    T t=T{
    1};T *p=&t;cout<<p->a<<endl;cout<<(*p).a<<endl;return 0;
}

在c语言中,结构体指针访问结构体字段可以通过p->a或者(*p).a,但是在go语言中没有->

package mainimport "fmt"type T1 struct{
    a int
}
func main(){
    i:=&T1{
    a:100}fmt.Println(i.a)fmt.Println((*i).a)
}

可以看出通过i.a和(*i).a都可以访问,这是因为内部编译器将i.a转换成(*i).a。(隐式间接引用)

方法值和方法表达式

package mainimport "fmt"type T1 struct{
    a int
}
func (t T1)f1(i int){
    fmt.Println(t.a+i)
}
func main(){
    t:=T1{
    1}//1)a、方法值调用f:=t.f1f(1)//1)b、方法值调用t.f1(1)//2)a、方法表达式调用f1:=(T1).f1f1(t,1)//2)b、方法表达式调用(T1).f1(t,1)
}

方法值类似于方法接收者,方法表达式类似于作为函数的第一个默认参数。

方法集

将接受者为值类型T的方法的集合记录为S,将接受者为指针类型T的方法的集合记录为S则:
1)T类型的方法集是S
2)T类型的方法集为S何S

在直接使用类型实例t(t T)调用方法是,无论是值类型还是指针类型,都可以调用类型的所有方法,编译器进行转换。

package mainimport "fmt"type T struct{
    a int
}func(t T) get()int{
    return t.a
}func(t *T)set(i int){
    t.a=i
}func main(){
    var a=10p:=&afmt.Println(p)i:=&T{
    }i1:=T{
    }i.set(10)i1.set(100)fmt.Println(i.get())fmt.Println((*i).get())fmt.Println(i1.get())
}

当通过类型字面量显示的进行方法调用,编译器无法转换

type A struct{
    }
func (A)f1(){
    }
func (*A)f2(){
    }
//*A的方法集是f1和f2
(*A)(&struct{
    }{
    }).f1()
(*A)(&struct{
    }{
    }).f2()//方法值调用
(*A).f1((*A)(&struct{
    }{
    })) //方法表达式调用
//A的方法集是f1
(A)(struct{
    }{
    }).f1()
//(A)(struct{}{})f2() ?方法集不匹配