method

Go中方法是作用在指定的數(shù)據(jù)類型上的,即必須和指定的數(shù)據(jù)類型綁定,因此自定義類型都可以具有方法,而不僅僅是結(jié)構(gòu)體。

方法聲明與調(diào)用

方法的定義

func (receiver type) methodName (argument_list) (return_value_list) {
  // method body
  return value
}
元素 描述
argument_list 參數(shù)列表,表示方法的輸入。
receiver type 表示方法和指定的type類型進行綁定,該方法作用于type類型。type可以是結(jié)構(gòu)體也可以是自定義類型。
receiver type類似的一個實例變量
return_value_list 返回值列表,表示返回的值,可以為多個。
method_body 方法體,為實現(xiàn)某功能的代碼塊。
return return語句不是必須的
type User struct {
    Id int
}
// 為User類型綁定TableName方法
func (t User) TableName() string {
    fmt.Printf("%+v\n", t)
    return "users"
}

func main() {
    u := User{1}
    name := u.TableName()
    fmt.Println(name)
}

語法說明

  • func (t User) TableName(){}表示User類型具有一個方法,方法名稱為TableName
  • (t User)體現(xiàn)了TableName方法是和User類型綁定的
  • TableName()方法只能通過User類型的變量來調(diào)用,而不能直接調(diào)用,也不能使用其它類型變量來調(diào)用。
  • (t User)中的t變量表示哪個User變量調(diào)用,這個t就是它的副本,類似函數(shù)傳參。
  • 若需要傳入引用類型而不采用副本的方式可使用(t *User)的方式
  • t這個名字由開發(fā)人員自行指定,不是固定的。

方法的調(diào)用和傳參機制

方法的調(diào)用和傳參機制和函數(shù)基本一致,不同之處在于方法調(diào)用時會將調(diào)用方法的變量作為實參也傳遞給方法,若變量是值類型則進行值拷貝,若變量是引用類型,則進行地址拷貝。

type Circle struct {
    radius float64
}

func (t Circle) area() float64 {
    return 3.14 * t.radius * t.radius
}

func main() {
    var c Circle
    c.radius = 4.0
    res := c.area()
    fmt.Println(res) // 50.24
}

由于采用值拷貝的方式效率較低,建議采用傳遞指針的方式以提升效率。

注意事項

  • 結(jié)構(gòu)體類型是值類型,方法調(diào)用中遵守值類型的傳遞機制,即值類型采用的是值拷貝傳遞的方式。
  • 若希望在方法中修改結(jié)構(gòu)體變量的值可通過結(jié)構(gòu)體指針的方式來處理
  • Go中方法的作用是在指定的數(shù)據(jù)類型上(和指定的數(shù)據(jù)類型綁定),因此自定義類型都可以有方法,而不僅僅是結(jié)構(gòu)體,基本類型也可以擁有方法。
  • 方法的訪問范圍控制的規(guī)則和函數(shù)一樣,方法名首字母小寫只能在本包訪問,首字母大寫可以在本包和其它包訪問。
  • 若某個變量實現(xiàn)了String()方法則fmt.Println()默認會調(diào)用此變量的String()方法進行輸出。
type User struct {
    Id   int
    Name string
}

func (t *User) String() string {
    str := fmt.Sprintf("id:%d, name:%s\n", t.Id, t.Name)
    return str
}

func main() {
    u := User{1, "alice"}
    fmt.Println(&u)
}

方法與函數(shù)

方法和函數(shù)的區(qū)別

區(qū)別 函數(shù) 方法
調(diào)用方式 函數(shù)名(實參列表) 變量.方法名(實參列表)
接收值類型時 不能將指針類型的數(shù)據(jù)直接傳遞 可直接使用指針類型的變量調(diào)用方法
type User struct {
    Id   int
    Name string
}

func (t *User) Print() {
    fmt.Printf("id:%d, name:%s\n", t.Id, t.Name)
}

func main() {
    u := User{1, "alice"}
    u.Print()
    (&u).Print()
}

注意:從形式上看(&u)是傳入地址,但本質(zhì)仍然是值拷貝。

type User struct {
    Id   int
    Name string
}

func (t User) Print() {
    t.Id = 2
    fmt.Printf("id:%d, name:%s\n", t.Id, t.Name)
}

func main() {
    u := User{1, "alice"}
    u.Print()                                    // id:2, name:alice
    (&u).Print()                                 // id:2, name:alice
    fmt.Printf("id:%d, name:%s\n", u.Id, u.Name) // id:1, name:alice
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容