0
点赞
收藏
分享

微信扫一扫

go语言深拷贝和浅拷贝案例


%T :使用Go语法输出的值的类型

%v:使用默认格式输出的内置或者自定义类型的值,或者是使用其类型的String()方式输出的自定义值,如果该方法存在的话

%p:以十六进制(基数为16)表示的一个值的地址,前缀为0x,字母使用小写的a-f表示

go语言深拷贝和浅拷贝案例_序列化


1、浅复制(1)new()和:=

package main

import "fmt"

type dog struct {
name string
age int
sex int
}

func main() {
dog1 := new(dog)
dog1.name = "dog1"
dog1.age = 11
dog1.sex = -1

dog2 := dog1

fmt.Printf("%T %v %p\n", dog1, dog1, dog1)
fmt.Printf("%T %v %p\n", dog2, dog2, dog2)

dog2.name = "dog2"
dog2.age = 12
dog2.sex = 2
fmt.Printf("%T %v %p\n", dog1, dog1, dog1)
fmt.Printf("%T %v %p\n", dog2, dog2, dog2)
}

go语言深拷贝和浅拷贝案例_深复制_02

2、浅复制(2)结构名{}和 :=&

package main

import "fmt"

type dog struct {
name string
age int
sex int
}

func main() {
dog1 := dog{
name: "dog1",
age: 11,
sex: -1,
}
dog2 := &dog1

fmt.Printf("%T %v %p\n", dog1, dog1, &dog1)
fmt.Printf("%T %v %p\n", dog2, dog2, dog2)

dog2.name = "dog2"
dog2.age = 12
dog2.sex = 2
fmt.Printf("%T %v %p\n", dog1, dog1, &dog1)
fmt.Printf("%T %v %p\n", dog2, dog2, dog2)
}

go语言深拷贝和浅拷贝案例_浅复制_03

3、浅复制(3) 切片

package main

import (
"fmt"
"unsafe"
)

func main() {
slice_test := []int{1, 2, 3, 4, 5}

fmt.Println(unsafe.Sizeof(slice_test))
fmt.Printf("main:%#v,%#v,%#v\n\n", slice_test, len(slice_test), cap(slice_test))

slice_value(slice_test)
fmt.Printf("after slice_test,main:%#v,%#v,%#v\n\n", slice_test, len(slice_test), cap(slice_test))

slice_ptr(&slice_test)
fmt.Printf("after slice_ptr,main:%#v,%#v,%#v\n\n", slice_test, len(slice_test), cap(slice_test))

fmt.Println(unsafe.Sizeof(slice_test))
}

func slice_value(slice_test []int) {
slice_test[1] = 100 // 函数里的slice确实有被修改
slice_test = append(slice_test, 6) // 函数外的不变
fmt.Printf("slice_value:%#v,%#v,%#v\n\n", slice_test, len(slice_test), cap(slice_test))
}

func slice_ptr(slice_test *[]int) { // 这样才能修改函数外的slice
(*slice_test)[1] = 10
*slice_test = append(*slice_test, 7)
fmt.Printf("slice_ptr:%#v,%#v,%#v\n\n", *slice_test, len(*slice_test), cap(*slice_test))
}

go语言深拷贝和浅拷贝案例_序列化_04

​​unsafe.sizeof()​​

4、 深复制(1)结构名{}和:=

package main

import "fmt"

type dog struct {
name string
age int
sex int
}

func main() {
dog1 := dog{
name: "dog1",
age: 11,
sex: -1,
}
dog2 := dog1

fmt.Printf("%T %v %p\n", dog1, dog1, &dog1)
fmt.Printf("%T %v %p\n", dog2, dog2, &dog2)

dog2.name = "dog2"
dog2.age = 12
dog2.sex = 2
fmt.Printf("%T %v %p\n", dog1, dog1, &dog1)
fmt.Printf("%T %v %p\n", dog2, dog2, &dog2)
}

go语言深拷贝和浅拷贝案例_序列化_05

5、深复制(2)指针

package main
import "fmt"

type dog struct {
name string
age int
sex int
}

func main() {
dog1 := &dog{
name: "dog1",
age: 11,
sex: -1,
}
dog1Ptr := *dog1
dog2 := &dog1Ptr

fmt.Printf("%T %v %p\n", dog1, dog1, dog1)
fmt.Printf("%T %v %p\n", dog2, dog2, dog2)

dog2.name = "dog2"
dog2.age = 12
dog2.sex = 2
fmt.Printf("%T %v %p\n", dog1, dog1, dog1)
fmt.Printf("%T %v %p\n", dog2, dog2, dog2)
}

go语言深拷贝和浅拷贝案例_浅复制_06


评论区说的没错,以上只能处理没有指针属性的结构体

golang 完全是按值传递,所以正常的赋值都是值拷贝,当然如果类型里面嵌套的有指针,也是指针值的拷贝,此时就会出现两个类型变量的内部有一部分是共享的。

package main

import "fmt"

type dog struct {
name string
age int
sex int
son *dog
}

func main() {
dogSon := dog{
name :"dogSon1",
age:1,
sex: 1,
son:nil,
}
dog1 := dog{
name: "dog1",
age: 11,
sex: -1,
son:&dogSon,
}
dog2 := dog1
fmt.Printf("Before Change dog2.son's information:\n")
fmt.Printf("do1.son:%T %v %p\n", dog1.son, dog1.son, &dog1.son)
fmt.Printf("dog2.son:%T %v %p\n", dog2.son, dog2.son, &dog2.son)

fmt.Printf("\nAfter Change dog2.son's information:\n")
dog2.son.name = "dogSon2"
dog2.son.age = 2
dog2.son.sex = 2

fmt.Printf("%T %v %p\n", dogSon, dogSon, &dogSon)
fmt.Printf("dog1.son:%T %v %p\n", dog1.son, dog1.son, &dog1.son)
fmt.Printf("dog2.son:%T %v %p\n", dog2.son, dog2.son, &dog2.son)
}

go语言深拷贝和浅拷贝案例_浅复制_07

6、基于序列化和反序列化来实现对象的深度复制

package main

import (
"bytes"
"encoding/gob"
"fmt"
)

type Dog struct { // 结构体序列化时,需要序列化的字段需要首字母大写。
Name string
Age int
Sex int
Son *Dog
}

func deepcopy(dst, src interface{}) error{
var buffer bytes.Buffer //构造缓冲区
// 序列化,生成gob编码器并编码
if err:= gob.NewEncoder(&buffer).Encode(src);err!=nil{
return err
}
// 反序列化,构造gob解码器,解码
return gob.NewDecoder(bytes.NewBuffer(buffer.Bytes())).Decode(dst)
}

func main() {
dogSon := Dog{
Name :"dogSon1",
Age:1,
Sex: 1,
Son:nil,
}
dog1 := Dog{
Name: "dog1",
Age: 11,
Sex: -1,
Son:&dogSon,
}
var dog2 Dog
err := deepcopy(&dog2, &dog1)
if err != nil{
fmt.Println(err)
}else {
fmt.Printf("Before Change dog2.Son's information:\n")
fmt.Printf("do1.Son:%T %v %p\n", dog1.Son, dog1.Son, &dog1.Son)
fmt.Printf("dog2.Son:%T %v %p\n", dog2.Son, dog2.Son, &dog2.Son)

fmt.Printf("\nAfter Change dog2.Son's information:\n")
dog2.Son.Name = "dogSon2"
dog2.Son.Age = 2
dog2.Son.Sex = 2

fmt.Printf("%T %v %p\n", dogSon, dogSon, &dogSon)
fmt.Printf("dog1.Son:%T %v %p\n", dog1.Son, dog1.Son, &dog1.Son)
fmt.Printf("dog2.Son:%T %v %p\n", dog2.Son, dog2.Son, &dog2.Son)
}
}

go语言深拷贝和浅拷贝案例_序列化_08


举报

相关推荐

0 条评论