zoukankan      html  css  js  c++  java
  • 方法

    Go方法总是绑定对象实例,并隐式将实例作为第一实参。

    • 只能为当前包内命名的类型 定义方法
    • 参数可任意命名,如果方法中未曾使用,可省略参数名
    • 参数类型可以是T或*T,基类型T不能是接口或指针
    • 不支持方法重载
    • 可用实例调用全部方法,编译器自动转换

    一个方法就是一个包含了接受者的函数,接受者可以是命名类型或者结构体类型的一个值或者一个指针。所有给定类型的方法属于该类型的方法集。

    方法定义

    func  (recevier type)  methodName(参数列表)  (返回值列表)  {
        函数体
    }
    参数与返回值,可以省略
    
    // 无参数、无返回值
    func (t Test) method0() {
    }
    
    // 单参数、无返回值
    func (t Test) method1(i int) {
    }
    
    // 多参数、无返回值
    func (t Test) method2(x, y int) {
    }
    
    // 无参数、单返回值
    func (t Test) method3() (i int) {
        return
    }
    
    // 多参数、多返回值
    func (t Test) method4(x, y int) (z int, err error) {
        return
    }
    
    // 无参数、无返回值
    func (t *Test) method5() {
    }
    
    // 单参数、无返回值
    func (t *Test) method6(i int) {
    }
    
    // 多参数、无返回值
    func (t *Test) method7(x, y int) {
    }
    
    // 无参数、单返回值
    func (t *Test) method8() (i int) {
        return
    }
    
    // 多参数、多返回值
    func (t *Test) method9(x, y int) (z int, err error) {
        return
    } 

    结构体类型和该类型的一个方法:

    package main
    
    import (
        "fmt"
    )
    
    //结构体
    type User struct {
        Name  string
        Email string
    }
    
    //方法
    func (u User) Notify() {
        fmt.Printf("%v : %v 
    ", u.Name, u.Email)
    }
    func main() {
        // 值类型调用方法
        u1 := User{"golang", "golang@golang.com"}
        u1.Notify()
        // 指针类型调用方法
        u2 := User{"go", "go@go.com"}
        u3 := &u2
        u3.Notify()
    }
    //  golang : golang@golang.com 
    //  go : go@go.com

    解释:我们首先定义了一个叫做User的结构体类型,然后定义了一个该类型的方法叫做Notify,该方法的接受者是一个User类型的值。要调用Notify方法,我们需要一个User类型的值或指针。

    在这个例子中当我们使用指针时,Go调整和解引用指针使得调用可以被执行。注意,当接受者不是一个指针时,该方法操作对应接受者的值的副本。即使你使用了指针调用函数,但是函数的接受者是值类型,所以函数内部操作还是对副本的操作,而不是指针操作。

    修改Notify方法,让它的接受者使用指针类型。

    package main
    
    import (
        "fmt"
    )
    
    //结构体
    type User struct {
        Name  string
        Email string
    }
    
    //方法
    func (u *User) Notify() {
        fmt.Printf("%v : %v 
    ", u.Name, u.Email)
    }
    func main() {
        // 值类型调用方法
        u1 := User{"golang", "golang@golang.com"}
        u1.Notify()
        // 指针类型调用方法
        u2 := User{"go", "go@go.com"}
        u3 := &u2
        u3.Notify()
    }
    // golang : golang@golang.com 
    // go : go@go.com 

     注意:当接受者是指针时,即使用值类型调用那么函数内部也是对指针的操作。

    方法不过是一种特殊的函数,只需将其还原,就知道receiver 和 *T 的区别。

  • 相关阅读:
    120. Triangle
    Effective C++ 条款36 绝不重新定义继承而来的non-virtual函数
    Effective C++ 条款31 将文件中间的编译依存关系降至最低
    Effective C++ 条款35 考虑virtual函数以外的其他选择
    Effective C++ 条款34 区分接口继承和实现继承
    Effective C++ 条款33 避免遮掩继承而来的名称
    Effective C++ 条款32 确定你的public继承塑模出is-a关系
    Effective C++ 条款30 透彻了解inlining的里里外外
    Effective C++ 条款29 为"异常安全"而努力是值得的
    Effective C++ 条款28 避免返回handles指向对象内部成分
  • 原文地址:https://www.cnblogs.com/yizhixiaowenzi/p/14722648.html
Copyright © 2011-2022 走看看