《漫威蜘蛛俠》將推出《蜘蛛俠:英雄無歸》兩件新套裝 僅限重製版
阿新 • • 發佈:2021-12-07
十五、方法
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