Go语言之面向对象-方法
Posted 程序彤
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Go语言之面向对象-方法相关的知识,希望对你有一定的参考价值。
golang的方法
作用在指定数据类型上,和指定的数据类型绑定,因此自定义类型都可以有方法,而不仅仅是struct
声明和调用
type A struct{
Num int
}
func (a A) test{
fmt.Println(a.Num)
}表示A结构体的方法为test()
package main
import(
"fmt"
"encoding/json"
)
func main(){
monster1 := Monster{"李威彤",21}
fmt.Println(monster1)
jsonString,_:=json.Marshal(monster1)
// 实际场景,字段首字母为小写。如何解决,字段使用标签``,即反射机制
fmt.Println("服务端将会收到json格式的字符串=>",string(jsonString))
monster1.Name = "小怪兽"
monster1.shout()
fmt.Println(monster1) // 由于结构体是值传递,故无用兽不可能在main()中打印出现
}
type Monster struct{
Name string `json:"name"` // 返回的json格式的字符串中的首字母小写name
age int `json:"age"`
}
func (m Monster) shout(){ // 结构体Monster的大叫方法
fmt.Println(m.Name,"叫了一声shout()...")
m.Name = "无用兽"
fmt.Println("方法shout()中的:",m)
}
再次表明,结构体为值传递。
结构体指针(原生)
package main
import(
"fmt"
"encoding/json"
)
func main(){
monster1 := Monster{"李威彤1",21}
fmt.Println(monster1)
jsonString,_:=json.Marshal(monster1)
// 实际场景,字段首字母为小写。如何解决,字段使用标签``,即反射机制
fmt.Println("服务端将会收到json格式的字符串=>",string(jsonString))
monster1.Name = "小怪兽"
monster1.shout()
fmt.Println(monster1) // 由于结构体是值传递,故无用兽不可能在main()中打印出现
monster2 := Monster{"李威彤2",21}
(&monster2).cry()
fmt.Println("main()中的cry()",monster2)
}
type Monster struct{
Name string `json:"name"` // 返回的json格式的字符串中的首字母小写name
age int `json:"age"`
}
func (m Monster) shout(){ // 结构体Monster的大叫方法
fmt.Println(m.Name,"叫了一声shout()...")
m.Name = "无用兽"
fmt.Println("方法shout()中的:",m)
}
func (m *Monster) cry(){
fmt.Println(m.Name,"哭了cry()!")
(*m).Name="引用-哭哭兽"
fmt.Println("方法cry()中的 m.Name",m.Name)
fmt.Println("方法cry()中的 (*m).Name",(*m).Name)
}
go简化结构体指针之后(简便写法)
即main()中的:
(&m).cry() 等价于 m.cry()
结构体指针的cry()方法中:
(*m).Name 等价于 m.Name
package main
import(
"fmt"
"encoding/json"
)
func main(){
monster1 := Monster{"李威彤1",21}
fmt.Println(monster1)
jsonString,_:=json.Marshal(monster1)
// 实际场景,字段首字母为小写。如何解决,字段使用标签``,即反射机制
fmt.Println("服务端将会收到json格式的字符串=>",string(jsonString))
monster1.Name = "小怪兽"
monster1.shout()
fmt.Println(monster1) // 由于结构体是值传递,故无用兽不可能在main()中打印出现
monster2 := Monster{"李威彤2",21}
(&monster2).cry()
monster2.cry()
fmt.Println("main()中的cry()",monster2)
}
type Monster struct{
Name string `json:"name"` // 返回的json格式的字符串中的首字母小写name
age int `json:"age"`
}
func (m Monster) shout(){ // 结构体Monster的大叫方法
fmt.Println(m.Name,"叫了一声shout()...")
m.Name = "无用兽"
fmt.Println("方法shout()中的:",m)
}
func (m *Monster) cry(){
fmt.Println(m.Name,"哭了cry()!")
(*m).Name="引用-哭哭兽"
m.Name = "引用--哭哭兽"
fmt.Println("方法cry()中的 m.Name",m.Name)
fmt.Println("方法cry()中的 (*m).Name",(*m).Name)
}
go方法和函数的区别
对于普通函数,接受者为值类型,不能将指针类型的数据直接传递,反之亦然
对于方法,接受者为值类型,可以直接用指针类型的变量调用方法,反之不然!!
总结:
- 不管调用形式如何,那只是一种表现形式。真正决定是值拷贝还是地址拷贝,看这个方法和哪个类型绑定。
- 如果是和值类型,比如p Person,结构体是值拷贝。如果是*p Person,则是结构体指针地址拷贝。
package main
import(
"fmt"
)
type Person struct{
Name string
}
func test01(p Person){
fmt.Println(p.Name)
}
func test02(p *Person){
fmt.Println(p.Name)
}
func (p Person) test03(){
p.Name = "郑"
fmt.Println("test03()=",p.Name)
}
func (p *Person) test04(){
p.Name = "郑my"
fmt.Println("test04()*=",p.Name)
}
func main(){
p:= Person{"李"}
// 对于函数,接受值类型时,不能将地址类型数据直接传递。反之亦然
test01(p) // testt01(&p)将报错
test02(&p) // testt02(p)将报错
p.test03() // 标准
fmt.Println("main()=",p.Name)
(&p).test03() // 不标准。test03()本身就是值拷贝传递,你即便使用&p也毫无作用,go做了优化
fmt.Println("main()=",p.Name)
(&p).test04() // 标准
fmt.Println("main()=",p.Name)
p.test04() // go优化处理,不标准但优雅
fmt.Println("main()=",p.Name)
}
以上是关于Go语言之面向对象-方法的主要内容,如果未能解决你的问题,请参考以下文章