• golang function 和method


    go语言作为一种面向对象的语言,并没有提供C++中的“成员函数”这一种说法,而是用method(方法)来表示。

    1、method和function的关系:

           method是特殊的function,定义在某一特定的类型上,通过类型的实例来进行调用,这个实例被叫receiver。(a Go method is a function that acts onvariable of a certain type, called the receiver. So a method is a special kindof function. ---摘自《Go语言程序设计》)。

    2、为普通类型添加method:

           go语言不允许为简单的内置类型添加method,如:

    func (i  int)  adder_int(j  int)(int){

        return  i+j

    }

    这个方法定义会出错,提示如下:

    cannotdefine new methods on non-local type int

           但是通过go语言中的type,我们可以临时定义一个和int具有同样功能的类型(注意,go中用type定义的类型,和C中不一样的一点是,这新定义的类型和原来的类型属于不同的类型,不能直接相互赋值),

    然后对新定义的类型添加方法:

    type Int  int

     

    func (i  Int )adder_int(j  Int)(Int){

        returni+j

    }

    方法是特殊的函数,定义在某一特定的类型上,通过类型的实例来进行调用,这个实例被叫接收者(receiver)。 
    函数将变量作为参数:Function1(recv) 
    方法在变量上被调用:recv.Method1() 
    接收者必须有一个显式的名字,这个名字必须在方法中被使用。 
    receiver_type 叫做 (接收者)基本类型,这个类型必须在和方法同样的包中被声明。

    在 Go 中,(接收者)类型关联的方法不写在类型结构里面,就像类那样;耦合更加宽松;类型和方法之间的关联由接收者来建立。 
    方法没有和数据定义(结构体)混在一起:它们是正交的类型;表示(数据)和行为(方法)是独立的。

    注意: Go语言不允许为简单的内置类型添加方法,

    go 语言不像其它面相对象语言一样可以写个类,然后在类里面写一堆方法,但其实Go语言的方法很巧妙的实现了这种效果:我们只需要在普通函数前面加个接受者(receiver,写在函数名前面的括号里面),这样编译器就知道这个函数(方法)属于哪个struct了。例如:

    type A struct {
        Name string
    }
     
    func (a A)foo()  { //接收者写在函数名前面的括号里面
        fmt.Println("foo")
    }
     
    func main() {
        a := A{}
        a.foo() //foo
    }

    1.对于普通函数,接收者为值类型时,不能将指针类型的数据直接传递,反之亦然。

    2.对于方法(如struct的方法),接收者为值类型时,可以直接用指针类型的变量调用方法,反过来同样也可以。

    以下为简单示例

    package structTest 
       
    //普通函数与方法的区别(在接收者分别为值类型和指针类型的时候) 
    //Date:2014-4-3 10:00:07 
       
    import ( 
        "fmt" 
    ) 
       
    func StructTest06Base() { 
        structTest0601() 
        structTest0602() 
    } 
       
    //1.普通函数 
    //接收值类型参数的函数 
    func valueIntTest(a int) int { 
        return a + 10 
    } 
       
    //接收指针类型参数的函数 
    func pointerIntTest(a *int) int { 
        return *a + 10 
    } 
       
    func structTest0601() { 
        a := 2 
        fmt.Println("valueIntTest:", valueIntTest(a)) 
        //函数的参数为值类型,则不能直接将指针作为参数传递 
        //fmt.Println("valueIntTest:", valueIntTest(&a)) 
        //compile error: cannot use &a (type *int) as type int in function argument 
       
        b := 5 
        fmt.Println("pointerIntTest:", pointerIntTest(&b)) 
        //同样,当函数的参数为指针类型时,也不能直接将值类型作为参数传递 
        //fmt.Println("pointerIntTest:", pointerIntTest(b)) 
        //compile error:cannot use b (type int) as type *int in function argument 
    } 
       
    //2.方法 
    type PersonD struct { 
        id   int 
        name string 
    } 
       
    //接收者为值类型 
    func (p PersonD) valueShowName() { 
        fmt.Println(p.name) 
    } 
       
    //接收者为指针类型 
    func (p *PersonD) pointShowName() { 
        fmt.Println(p.name) 
    } 
       
    func structTest0602() { 
        //值类型调用方法 
        personValue := PersonD{101, "Will Smith"} 
        personValue.valueShowName() 
        personValue.pointShowName() 
       
        //指针类型调用方法 
        personPointer := &PersonD{102, "Paul Tony"} 
        personPointer.valueShowName() 
        personPointer.pointShowName() 
       
        //与普通函数不同,接收者为指针类型和值类型的方法,指针类型和值类型的变量均可相互调用 
    } 

    golang为什么将method写在类外?

     
     https://www.zhihu.com/question/370830450/answer/1022825491
  • 相关阅读:
    更新证书错误Code Sign error: Provisioning profile ‘XXXX'can't be found
    解决Xcode 5下使用SVN出现 The operation couldn’t be completed. (NSURLErrorDomain error -1012.) 问题
    Android模拟器启动不了解决办法
    在AndroidManifest.xml文件中设置Android程序的启动界面方法
    Windows2008+MyEclipse10+Android开发环境搭配
    ADT下载地址整理
    android:inputType常用取值
    VS2010中使用Jquery调用Wcf服务读取数据库记录
    Linux手动安装netcore3.0
    StdOS之运行指示灯
  • 原文地址:https://www.cnblogs.com/youxin/p/15999977.html
Copyright © 2020-2023  润新知