go--深拷贝和浅拷贝

package main 
import(
	"fmt"
	// "github.com/mattn/go-runewidth"
	// "net/http"
	// "text/template"
)
// struct 是一个值类型  深拷贝  和浅拷贝   常量声明是要初始化
type Human struct{
	name string
	age  int
	sex  byte
}
type dog struct{
	name string
	age int
	color string
	kind  string 
}
type teacher struct {
	name string
	age  int 
	sex  int 
}
type emp struct {
	name string 
	age int
	sex int
}
func main(){
	//new方法声明初始化一个变量  
	emp1 := new(emp)
	emp1.name = "david2"
	emp1.sex = 333
	emp1.age = 222
	emp2 := emp1
	fmt.Printf("%T,%v,%p \n",emp1,emp1,emp1)//*main.emp,&{david2 222 333},0xc000048400
	fmt.Printf("%T,%v,%p \n",emp2,emp2,emp2)//*main.emp,&{david2 222 333},0xc000048400
	emp2.name = "maike"
	emp2.sex = 4444
	fmt.Printf("%T,%v,%p \n",emp1,emp1,emp1)//*main.emp,&{maike 222 4444},0xc000048400
	fmt.Printf("%T,%v,%p \n",emp2,emp2,emp2)//*main.emp,&{maike 222 4444},0xc000048400
	fmt.Println("----------------------")
	
	//深拷贝   会赋值全部的内容  内容一样但是地址不一样 修改任何一个后地址不一样 内容也会一样
	h1:= Human{name:"聂伟博",age:28,sex:0}
	h2:= h1
	fmt.Printf("h1:%T,%v,%p \n",h1,h1,&h1)  //h1:main.Human,{聂伟博 28 0},0xc0000484c0
	fmt.Printf("h2:%T,%v,%p \n",h2,h2,&h2)  //h2:main.Human,{聂伟博 28 0},0xc0000484e0
	fmt.Println("-----------------------")
	h2.name = "dvid"
	fmt.Printf("h2修改后:%T,%v,%p \n",h2,h2,&h2)  //h2修改后:main.Human,{dvid 28 0},0xc0000484e0
	fmt.Printf("h1:%T,%v,%p \n",h1,h1,&h1)             //h1:main.Human,{聂伟博 28 0},0xc0000484c0
	fmt.Println("------------------------")
	changeName(h1)//对象传到函数里面也是深拷贝
	fmt.Println("------------------------")
	fmt.Printf("h1:%T,%v,%p \n",h1,h1,&h1)
	fmt.Println("---------------------------")

	//浅拷贝
	fmt.Println("浅拷贝")
	d1:=dog{name:"贝贝",age:12,color:"黄色",kind:"二哈"}
	d3:=&d1
	fmt.Printf("d1:%T,%v,%p \n",d1,d1,&d1)  //d1:main.dog,{贝贝 12 黄色 二哈},0xc000034140
	fmt.Printf("d3:%T,%v,%p \n",d3,d3,d3)  //d3:*main.dog,&{贝贝 12 黄色 二哈},0xc000034140
	d3.name = "皮皮"
	d3.color = "白色"
	d3.kind = "萨摩"
	fmt.Printf("d1:%T,%v,%p \n",d1,d1,&d1)  //d1:main.dog,{皮皮 12 白色 萨摩},0xc000034140
	fmt.Printf("d3:%T,%v,%p \n",d3,d3,d3)  //d3:*main.dog,&{皮皮 12 白色 萨摩},0xc000034140
	fmt.Println("---------------------------")

	//new操作浅拷贝   
	fmt.Println("new操作浅拷贝:")
	d4 := new (dog)
	d4.age = 11
	d4.name = "球球"
	d4.color = "棕色"
	d4.kind = "金毛"
	d5 := d4
	fmt.Printf("d4:%T,%v,%p \n",d4,d4,d4)   //d4:*main.dog,&{球球 11 棕色 金毛},0xc00004a340
	fmt.Printf("d5:%T,%v,%p \n",d5,d5,d5)   //d5:*main.dog,&{球球 11 棕色 金毛},0xc00004a340
	d5.name = "本本"
	d5.color = "黑色"
	fmt.Printf("d4:%T,%v,%p \n",d4,d4,d4)   //d4:*main.dog,&{本本 11 黑色 金毛},0xc00004a340
	fmt.Printf("d5:%T,%v,%p \n",d5,d5,d5)   //d5:*main.dog,&{本本 11 黑色 金毛},0xc00004a340
	teache := teacher{
		name:"nieweibo",
		age:23,
		sex:3,
	}
	fmt.Printf("teacher类型:%T",teache)
}  
func changeName(h Human){
	h.name = "danil"
	// h.age = 13
	fmt.Printf("函数体内的修改后h1:%T,%v,%p \n",h,h,h)
}

打印的结果:

*main.emp,&{david2 222 333},0xc000048400
*main.emp,&{david2 222 333},0xc000048400
*main.emp,&{maike 222 4444},0xc000048400
*main.emp,&{maike 222 4444},0xc000048400
----------------------
h1:main.Human,{聂伟博 28 0},0xc0000484c0
h2:main.Human,{聂伟博 28 0},0xc0000484e0
-----------------------
h2修改后:main.Human,{dvid 28 0},0xc0000484e0
h1:main.Human,{聂伟博 28 0},0xc0000484c0
------------------------
函数体内的修改后h1:main.Human,{danil 28 0},%!p(main.Human={danil 28 0})
------------------------
h1:main.Human,{聂伟博 28 0},0xc0000484c0
---------------------------
浅拷贝
d1:main.dog,{贝贝 12 黄色 二哈},0xc00004a100
d3:*main.dog,&{贝贝 12 黄色 二哈},0xc00004a100
d1:main.dog,{皮皮 12 白色 萨摩},0xc00004a100
d3:*main.dog,&{皮皮 12 白色 萨摩},0xc00004a100
---------------------------
new操作浅拷贝:
d4:*main.dog,&{球球 11 棕色 金毛},0xc00004a2c0
d5:*main.dog,&{球球 11 棕色 金毛},0xc00004a2c0
d4:*main.dog,&{本本 11 黑色 金毛},0xc00004a2c0
d5:*main.dog,&{本本 11 黑色 金毛},0xc00004a2c0

总结:凡是%v占位符对应的值前面有&这个符号的说明是指针类型,变量的前面就不用加& 如果没有就需要加&

不打印的话如何知道什么时候加&这个呢?首先如果你定义一个变量val无论这个变量是什么类型,那么这个变量一定要在前面加上&来匹配%p占位符,如果你深拷贝这个值val那么这两个变量都需要加上&,如果浅拷贝val那么浅拷贝只有的变量val2就是一个指针类型  不需要加上&符号。

new(dog)关键字之后  使用 b:=a   咋一看是深拷贝  其实是浅拷贝,b是拷贝了a的内存

下面是个浅显的例子:

b := a 这是深拷贝 会生成两个内存地址,     b:=&a 这是浅拷贝a,b公用a的内存地址,b就是指针类型

    a := 12
    b := & a
    fmt.Printf("a:%T,%v,%p \n",a,a,&a) //a:int,12,0xc00004e090
    fmt.Printf("b:%T,%v,%p \n",b,b,b)   //b:*int,0xc00004e090,0xc00004e090

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值