函数和方法的区别
- 函数出传参,值类型就是值类型,引用类型就是引用类型,不可混用,不能把值类型数据传入指针参数中。
- 方法的传参,值类型和引用类型取决于 func ( x x_type ) () {…} —> x_type或者*x_type
- 传入x参数无论是值类型还是指针类型在编译器这儿都能通过并且按照同等方式处理,即 x == &x,举例说明也就是<结构体变量>.<结构体字段> == <&结构体变量>.<结构体字段>,my.Name == (&my).Name
- 前面是结构体变量传入说明,后面具体方法能不能改变初始化字段值取决于方法的x_type类型,这个与函数一致,Mylist类型则函数内字段值赋值不影响main()中初始化字段值的改变,*Mylist类型则函数内字段值赋值影响main()中初始化字段值的改变。
经常面试挖坑就在这儿,下面用程序举例说明
package main
import "fmt"
type Mylist struct {
Name string
Age string
}
func (my Mylist) value_type() {
fmt.Println("都能传,但是到这儿都是值类型")
}
func (my *Mylist) ptr_type() {
my.Name = "zzz"
fmt.Println("都能传,但是到这儿都是引用类型")
}
func ptr1_type(my *Mylist) {
fmt.Println("只能传指针类型")
}
func value1_type(my Mylist) {
fmt.Println("只能传值类型")
}
func main() {
var my Mylist //定义一个结构体实例
my.Name = "lululu" //初始化结构体实例my中的字段Name为"lululu"
my.value_type() //对于方法中,由于编译器优化,传递的结构体变量既可以是值也可以是地址
fmt.Println(my.Name) //无论是my为值还是地址,最终传递给绑定变量的都是值拷贝
(&my).value_type()
fmt.Println((&my).Name)
my.ptr_type() //但是具体的my.Name的值还是要看结构体绑定变量到底是值类型还是指针类型
fmt.Println(my.Name) //结构体变量为值类型,则方法内值的改变不影响main()中初始化变量的值
(&my).ptr_type() //结构体变量若为引用类型,则方法内值的改变影响main()中初始化变量的值
fmt.Println((&my).Name)
value1_type(my) //函数中不存在传入绑定变量,所以和之前一样,值类型只能传值类型,地址类型只能传地址类型,不可my和&my代表一个意思
ptr1_type(&my) //值类型函数内的改变不影响main()初始化变量的值,引用类型函数内的改变影响main()初始化变量的值,
}