方法
十五、方法
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