ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# 方法 * * * * * --: 作者:jsh 时间:2018年9月9日 * * * * * 在 Go 语言中,结构体就像是类的一种简化形式,那么面向对象程序员可能会问:类的方法在哪里呢?在 Go 中有一个概念,它和方法有着同样的名字,并且大体上意思相同:Go 方法是作用在接收者(user)上的一个函数,接收者是某种类型的变量。Go 语言中同时有函数和方法。一个方法就是一个包含了接受者的函数,接受者可以是命名类型或者结构体类型的一个值或者是一个指针 方法能给用户定义的类型添加新的行为。方法实际上也是函数,只是在声明时,在关键字 func和方法名之间增加了一个参数。 ### 方法 定义方法的一般格式如下: ~~~ func (u user) methodName(parameter_list) (return_value_list) { ... } // 使用值接收者方法 func (u *user) methodName(parameter_list) (return_value_list) { ... } // 使用指针接收者方法 ~~~ 案例一:值接收者 ~~~ type user struct { name string, email string, } func (u user) notify() { fmt.Println("Email is %d", u.email) } func main() { jsh := {"jsh", "jsh@163.com"} jsh.notify() } ~~~ 值接收者,是接收者的类型是一个值,是一个副本,方法内部无法对其真正的接收者做更改,上面的代码中我们定义了一个notify方法,notify方法的接收者被声明为user类型的值。如果使用值接收者声明方法,调用时会使用这个值的副本。 案例二:指针接收者 ~~~ type user struct { name string, email string, } func (u *user) changeEmail(email string) { u.email = email } func main() { jsh := {"jsh", "jsh@163.com"} jsh.changeEmail("jsh@163.com") } ~~~ 指针接收者,接收者的类型是一个指针,是接收者的引用,对这个引用的修改之间影响真正的接收者。像上面一样定义方法,将 user 改成 *user 就是指针接收者,changeEmail它是指针接收者方法。可以看到,值接收者方法,接收者是一个副本,无法修改;指针接收者是引用,可以修改。 ### 值类型 所有像int、float、bool和string这些类型都属于值类型,使用这些类型的变量直接指向存在内存中的值,值类型的变量的值存储在栈中。当使用等号=将一个变量的值赋给另一个变量时,如 j = i ,实际上是在内存中将 i 的值进行了拷贝。可以通过&i获取变量 i 的内存地址 ``` package main import "fmt" func main(){ a := [5]int{2, 3, 4, 5, 6} b := a fmt.Println(a,b) b[2] = 77 fmt.Println(a,b) } ``` 定义了一个数组a,它是值类型,复制给b是copy,当b发生变化后a并会不会发生任何变化呢? ### 引用类型 复杂的数据通常会需要使用多个字,这些数据一般使用引用类型保存。一个引用类型的变量a存储的是a的值所在的内存地址(数字),或内存地址中第一个字所在的位置,这个内存地址被称之为指针,这个指针实际上也被存在另外的某一个字中。 ``` package main import "fmt" func main(){ a := []int{2, 3, 4, 5, 6} b := a fmt.Println(a,b) b[2] = 77 fmt.Println(a,b) } ``` 定义一个切片a,然后将切片a复制给b,当修改b的值的时候a会不会发生变化呢?