溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Go中如何聲明方法

發(fā)布時間:2021-09-18 17:45:27 來源:億速云 閱讀:150 作者:小新 欄目:大數(shù)據(jù)

這篇文章將為大家詳細講解有關Go中如何聲明方法,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

方法

Go支持一些面向?qū)ο缶幊烫匦?,方法是這些所支持的特性之一。 

方法聲明

在Go中,我們可以為類型T*T顯式地聲明一個方法,其中類型T必須滿足四個條件:

  1. T必須是一個定義類型;

  2. T必須和此方法聲明定義在同一個代碼包中;

  3. T不能是一個指針類型;

  4. T不能是一個接口類型。

類型T*T稱為它們各自的方法的屬主類型(receiver type)。 類型T被稱作為類型T*T聲明的所有方法的屬主基類型(receiver base type)

如果我們?yōu)槟硞€類型聲明了一個方法,以后我們可以說此類型擁有此方法,一個方法聲明和一個函數(shù)聲明很相似,但是比函數(shù)聲明多了一個額外的參數(shù)聲明部分。 此額外的參數(shù)聲明部分只能含有一個類型為此方法的屬主類型的參數(shù),此參數(shù)稱為此方法聲明的屬主參數(shù)(receiver parameter)。 此屬主參數(shù)聲明必須包裹在一對小括號()之中。 此屬主參數(shù)聲明部分必須處于func關鍵字和方法名之間

下面是一個方法聲明的例子:

// Age和int是兩個不同的類型。我們不能為int和*int
// 類型聲明方法,但是可以為Age和*Age類型聲明方法。
type Age int
func (age Age) LargerThan(a Age) bool {
  return age > a
}
func (age *Age) Increase() {
  *age++
}

// 為自定義的函數(shù)類型FilterFunc聲明方法。
type FilterFunc func(in int) bool
func (ff FilterFunc) Filte(in int) bool {
  return ff(in)
}

// 為自定義的映射類型StringSet聲明方法。
type StringSet map[string]struct{}
func (ss StringSet) Has(key string) bool {
  _, present := ss[key]
  return present
}
func (ss StringSet) Add(key string) {
  ss[key] = struct{}{}
}
func (ss StringSet) Remove(key string) {
  delete(ss, key)
}

// 為自定義的結(jié)構體類型Book和它的指針類型*Book聲明方法。
type Book struct {
  pages int
}
func (b Book) Pages() int {
  return b.pages
}
func (b *Book) SetPages(pages int) {
  b.pages = pages
}

每個方法對應著一個隱式聲明的函數(shù)

對每個方法聲明,編譯器將自動隱式聲明一個相對應的函數(shù)。 比如對于上一節(jié)的例子中為類型Book*Book聲明的兩個方法,編譯器將自動聲明下面的兩個函數(shù):

func Book.Pages(b Book) int {
  return b.pages // 此函數(shù)體和Book類型的Pages方法體一樣
}

func (*Book).SetPages(b *Book, pages int) {
  b.pages = pages // 此函數(shù)體和*Book類型的SetPages方法體一樣
}

在上面的兩個隱式函數(shù)聲明中,它們各自對應的方法聲明的屬主參數(shù)聲明被插入到了普通參數(shù)聲明的第一位。 它們的函數(shù)體和各自對應的顯式方法的方法體是一樣的。

兩個隱式函數(shù)名Book.Pages(*Book).SetPages都是aType.MethodName這種形式的。 我們不能顯式聲明名稱為這種形式的函數(shù),因為這種形式不屬于合法標識符。這樣的函數(shù)只能由編譯器隱式聲明。 但是我們可以在代碼中調(diào)用這些隱式聲明的函數(shù)

方法原型(method prototype)和方法集(method set)

一個方法原型可以看作是一個不帶func關鍵字的函數(shù)原型。 我們可以把每個方法聲明看作是由一個func關鍵字、一個屬主參數(shù)聲明部分、一個方法原型和一個方法體組成

方法值和方法調(diào)用

方法事實上是特殊的函數(shù)。方法也常被稱為成員函數(shù)。 當一個類型擁有一個方法,則此類型的每個值將擁有一個不可修改的函數(shù)類型的成員(類似于結(jié)構體的字段)。 此成員的名稱為此方法名,它的類型和此方法的聲明中不包括屬主部分的函數(shù)聲明的類型一致。 一個值的成員函數(shù)也可以稱為此值的方法。

一個方法調(diào)用其實是調(diào)用了一個值的成員函數(shù)。假設一個值v有一個名為m的方法,則此方法可以用選擇器語法形式v.m來表示。

下面這個例子展示了如何調(diào)用為Book*Book類型聲明的方法:

package main

import "fmt"

type Book struct {
  pages int
}

func (b Book) Pages() int {
  return b.pages
}

func (b *Book) SetPages(pages int) {
  b.pages = pages
}

func main() {
  var book Book

  fmt.Printf("%T \n", book.Pages)       // func() int
  fmt.Printf("%T \n", (&book).SetPages) // func(int)
  // &book值有一個隱式方法Pages。
  fmt.Printf("%T \n", (&book).Pages)    // func() int

  // 調(diào)用這三個方法。
  (&book).SetPages(123)
  book.SetPages(123)           // 等價于上一行
  fmt.Println(book.Pages())    // 123
  fmt.Println((&book).Pages()) // 123
}

和普通參數(shù)傳參一樣,屬主參數(shù)的傳參也是一個值復制過程。 所以,在方法體內(nèi)對屬主參數(shù)的直接部分的修改將不會反映到方法體外

關于“Go中如何聲明方法”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

go
AI