1. 程式人生 > 遊戲 >《漫威蜘蛛俠》將推出《蜘蛛俠:英雄無歸》兩件新套裝 僅限重製版

《漫威蜘蛛俠》將推出《蜘蛛俠:英雄無歸》兩件新套裝 僅限重製版

十五、方法

1 方法定義

go語言中同時有函式和方法。一個方法就是一個包含了接收器的函式,接收器一般是結構體型別中的欄位,也可以是非結構體。它的定義如下:

func (variable_name variable_data_type) function_name() [return_type]{
   /* 函式體*/
}

通俗來說就是定義一個函式,指定一個接收器來接收這個函式。

通過一個示例學習方法的使用:

type Book struct {
	title string
	price int
}

func (book Book) printprice() {
	fmt.Println(book.price)
	book.price += 2
}
func main() {
	book := Book{
		title: "紅樓夢",
		price: 58,
	}
	book.printprice()
	fmt.Println(book.price)
}

在上面的示例中,我們定義一個結構體含兩個欄位;然後定義一個函式,指定接收器為book,此時相當於在Book型別上綁定了一個方法。我們在main函式中可以通過.操作符呼叫這個方法。

2 值接收器和指標接收器

在上面的示例中我們發現,printprice方法想讓price自增2,但實際上原結構體並不會被改變,這是因為我們使用了值接收器。

我們如果想要在方法內更改欄位並使得它對呼叫者可見,需要使用指標接收器。比如下面的例子:

type Book struct {
	title string
	price int
}

func (book *Book) printprice() {
	fmt.Println(book.price)
	// 這裡傳遞的是指標,但是我們仍然可以取到欄位。這是go內部自動轉化的結果,如果在c或c++中,你需要先對指標解引用
	fmt.Println((*book).price)
	book.price += 2
}
func main() {
	book := Book{
		title: "紅樓夢",
		price: 58,
	}
	book.printprice()
	fmt.Println(book.price)
}

使用指標接收器後,在 printprice 方法中對 Book 結構體的欄位 price 所做的改變對呼叫者是可見的,換句話說在方法內修改值,原來的值也會隨之改變。

另外補充一點,如果你有c程式設計的經驗,你可能注意到,在操作結構體的欄位時,如果在c或c++中,需要先對指標解引用;而在go中不同,指標直接使用.操作符就可以取到欄位。

另外,go可以直接使用指標操作,而c/c++不可以,對比c++程式碼來理解:

struct Book {
    string title;
    int price;
};
void printprice(Book* book){
    (*book).price +=2; // c 解引用
    cout <<book->price<<endl;// c++ 解引用
}
int main() {
    Book book = {"紅樓夢",58};
    printprice(&book);
    return 0;
}

那麼該如何選擇值接收器與指標接收器?如果你想要方法所做的改變對呼叫者可見,那麼就使用指標接收器;否則就使用值接收器。另外,值接收器需要對原結構體拷貝,如果結構體欄位很大,那麼付出的記憶體消耗也大。

3 欄位方法提升

和結構體的欄位提升一樣,接收器是匿名欄位的結構體,可以直接在外部使用它的方法。

type Book struct {
	title string
	price int
	Author
}

type Author struct {
	name string
	age  int
}

func (a Author) getage() {
	// 接收器為Author
	fmt.Println(a.age)
}

func main() {
	book := Book{
		title: "紅樓夢",
		price: 58,
		Author: Author{
			name: "曹雪芹",
			age:  20,
		},
	}
	book.getage() // 可以直接訪問Author的繫結方法
	fmt.Println(book.price)
}

本文來自部落格園,作者:yyyz,轉載請註明原文連結:https://www.cnblogs.com/yyyzyyyz/p/15672540.html