Golang 方法
优质
小牛编辑
153浏览
2023-12-01
Go 语言中的方法其实就是一个特殊函数,只不过这个函数是和某种属性类型绑定在一起的而已
Go 语言中的方法 一般用于
将 函数和结构体绑定在一起
,让结构体除了能够保存数据外还能具备某些行为
将函数和数据类型绑定的格式
只需要在函数名称前面加上(接收者 数据类型),即可将函数和某种数据类型绑定在一起
func (接收者 数据类型)方法名称(形参列表)(返回值列表){ 方法体 }
示例:给结构体添加一个方法,此时结构体除了可以保存数据,还具备说出自己名字和年龄的行为
package main import "fmt" // 1.定义一个结构体 type Person struct { name string age int } // 2.定义一个函数, 并将这个函数和Person结构体绑定在一起 func (p Person)say() { fmt.Println("my name is", p.name, "my age is", p.age) } func main() { // 3.创建一个结构体变量 per := Person{"lnj", 33} // 4.利用结构体变量调用和结构体绑定的方法 // 调用时会自动将调用者(per)传递给方法的接收者(p) // 所以可以在方法内部通过p方法结构体变量的属性 per.say() }
方法和函数异同
方法的数据类型也是函数类型,所以也可以定义变量保存(作为参数返回值等)
package main import "fmt" type Person struct { name string age int } // 定义一个方法 func (p Person)say() { fmt.Println("say方法") } // 定义一个函数 func say() { fmt.Println("say函数") } func main() { p := Person{"lnj", 33} fmt.Printf("%T\n", p.say) // func() fmt.Printf("%T\n", say) // func() // 定义一个保存没有形参没有返回值的函数类型变量 var fn func() // 利用函数类型变量保存一个方法 fn = p.say // 利用函数类型变量调用一个方法 fn() // 利用函数类型变量保存一个函数 fn = say // 利用函数类型变量调用一个函数 fn() }
方法只能通过绑定类型的变量调用,函数可以直接调用
package main import "fmt" type Person struct { name string age int } // 定义一个方法 func (p Person)say() { fmt.Println("my name is", p.name, "my age is", p.age) } // 定义一个函数 func test() { fmt.Println("test") } func main() { per := Person{"lnj", 33} per.say() // 方法只能通过绑定类型的变量调用 //say() // 编译报错, 不能直接调用 test() // 编译通过, 可以直接调用 }
方法的接收者可以看做就是函数的一个形参
package main import "fmt" type Person struct { name string age int } // 定义一个方法 func (p Person)say() { fmt.Println("my name is", p.name, "my age is", p.age) } // 定义一个函数 func test(p Person) { fmt.Println("my name is", p.name, "my age is", p.age) } func main() { per := Person{"lnj", 33} per.say() // my name is lnj my age is 33 test(per) // my name is lnj my age is 33 }
既然可以看做形参,那么自然也具备形参的特点(值传递和地址传递)
package main import "fmt" type Person struct { name string age int } // 接收者是一个变量 func (p Person)setName(name string) { p.name = name } // 接收者是一个指针 func (p *Person)setAge(age int) { p.age = age } func main() { per := Person{"lnj", 33} fmt.Println(per) // {lnj 33} // 值传递, 方法内部修改不会影响方法外部 per.setName("zs") fmt.Println(per) // {lnj 33} p := &per // 地址传递, 方法内部修改会影响方法外部 (*p).setAge(18) fmt.Println(per) // {lnj 18} }
地址传递的几种调用方式
package main import "fmt" type Person struct { name string age int } // 接收者是一个变量 func (p Person)setName(name string) { p.name = name } // 接收者是一个指针 func (p *Person)setAge(age int) { p.age = age } func main() { per := Person{"lnj", 33} // 方式一: 先拿到指针,然后再通过指针调用 p := &per (*p).setAge(18) fmt.Println(per) // {lnj 18} // 方式二: 直接利用变量调用, 底层会自动获取变量地址传递给接收者 per.setAge(66) fmt.Println(per) // {lnj 66} }