# 结构体方法

结构体方法就是附加给结构体的函数。

{% tabs %}
{% tab title="Go" %}
```go
package main

import (
	"fmt"
)

type User struct {
	name string
}

func (u User) Name() string {
	return u.name
}

func (u *User) SetName(newName string) {
	u.name = newName
}

func main() {
	var me User

	me.SetName("Slim Shady")
	fmt.Println("My name is", me.Name())
}
```
{% endtab %}

{% tab title="Output" %}
```
My name is Slim Shady
```
{% endtab %}
{% endtabs %}

:point\_right: [点击此处](https://play.golang.org/p/BB7casjt17p) :point\_left: 亲自在编程操场修改和执行上述代码。

为结构体定义方法，跟定义一个函数的唯一区别就是在`func`关键字和函数名之间增加了方法接受者(receiver)，如上例中的`(u *User)`。

方法接受者可以被声明为类型的实例或者是类型的实例的指针。

上例中，因为`SetName()`会修改实例的属性值，所以需要传递指针，以实现永久修改。

{% hint style="warning" %}
#### 译者注

一般的，为结构体添加方法时，总是推荐传递实例的指针而非实例。

其一是因为Go语言总是值传递，会新增一份拷贝，从而多占内存；其二是我们往往需要修改实例的属性值，而不仅仅是读取它。

当然，推荐做法并非一成不变的教条，如果某种时候传递实例(需要一份拷贝)是更好的选择，那么应该打破这些“经验之谈”。
{% endhint %}

{% hint style="info" %}
#### 译者注

关于上述提示中提到的“Go语言总是值传递”可能有人不解(不服)，请自己动手多做观察，或者复习结构体复制一节。可以发现，即便是引用类型的传递，也是复制了第一级指针所指向的值(指针值)，而非直接传递原指针。
{% endhint %}
