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方法和函数的区别

对于普通函数,接受者为值类型,不能将指针类型的数据直接传递,反之亦然
对于方法,接受者为值类型,可以直接用指针类型的变量调用方法,反之不然!!

总结:

  1. 不管调用形式如何,那只是一种表现形式。真正决定是值拷贝还是地址拷贝,看这个方法和哪个类型绑定。
  2. 如果是和值类型,比如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)

	
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值