go里基本数据、结构体、map、数组中值传递与地址传递分析
2017-12-11 11:47
597 查看
int类型的值传递与地值传递的两段代码:
打印结果为:
1
6
打印的结果如下:
原地址:
0xc04203c1d0
值传递地址:
0xc04203c1d8
指针传递地址:
0xc04203c1d0
结合两个例子打印的值与地址信息,可以看出int类型在值传递的时候是重新分配一个值过去,并不会改变原有的值,地址传递时是直接把当前的地址传过去,可以直接改变原有的值。
结构体类型的值传递与地值传递的两段代码:
结果是:
值传递之前的信息:
{15 jerry}
值传递之后的信息:
{15 jerry}
地址传递之前的信息:
{16 dalianmao}
地址传递之后的信息:
{21 taoqi}
结果是:
值传递之前的地址为:0xc042042400
值传递的地址为:0xc042042460
地址传递的地址为:0xc042042400
结合两个例子打印的值与地址信息,可见结构体类型值传递并不能改变结构体的信息,只有地址传递过可以,说明即便是结构体在值传递的时候也是复制一份传递过去。
结果是:
[1]
[1]
[1 3]
结合两个例子打印的值与地址信息,可见数组在值传递时使用的也是重新复制一个数组传过去,而地址传递的时候直接把地址传了过去。
map的值传递与地址传递
打印结果是:
map[b:B a:A]
map[c:C a:A b:B]
打印结果是:
原地址是:0xc042004028
值传递的原地址是:0xc042004038
地址传递的地址是:0xc042004028
结合两个例子打印的值与地址信息,可见map在值传递时原来的值改变了,但是地址信息也改变了说明map在值传递时是重新分配了一个指针指向原来的值。
通过以上的例子可以看出,基本数据类型,结构体,数组在值传递的时候都是重新复制一份传递,而map在值值传递时则是重新分配了一个地址指向原来的值。如果想要提升效率使用地址传递,尤其在多属性的结构体与数组中,因为值传递需要把所有的信息都复制一份来使用;如果只想使用一下其值的信息但并不想改变原有的内容则可以使用值传递。
原文地址
package main import ( "fmt" ) func main() { age := 15 fmt.Println("原地址:") fmt.Println(&age) fmt.Println("值传递地址:") method(age) fmt.Println("指针传递地址:") method1(&age) } func method(age int) { fmt.Println(&age) } func method1(age *int) { fmt.Println(age) }
打印结果为:
1
6
package main import ( "fmt" ) func main() { age := 15 fmt.Println("原地址:") fmt.Println(&age) fmt.Println("值传递地址:") method(age) fmt.Println("指针传递地址:") method1(&age) } func method(age int) { fmt.Println(&age) } func method1(age *int) { fmt.Println(age) }
打印的结果如下:
原地址:
0xc04203c1d0
值传递地址:
0xc04203c1d8
指针传递地址:
0xc04203c1d0
结合两个例子打印的值与地址信息,可以看出int类型在值传递的时候是重新分配一个值过去,并不会改变原有的值,地址传递时是直接把当前的地址传过去,可以直接改变原有的值。
结构体类型的值传递与地值传递的两段代码:
package main import ( "fmt" ) type person struct { age int name string } func main() { per := person{ age: 15, name: "jerry", } fmt.Println("值传递之前的信息:") fmt.Println(per) struct_method(per) fmt.Println("值传递之后的信息:") fmt.Println(per) per2 := person{ age: 16, name: "dalianmao", } fmt.Println("地址传递之前的信息:") fmt.Println(per2) struct_method1(&per2) fmt.Println("地址传递之后的信息:") fmt.Println(per2) } func struct_method1(per *person) { per.age = 21 per.name = "taoqi" } func struct_method(per person) { per.age = 20 per.name = "tom" }
结果是:
值传递之前的信息:
{15 jerry}
值传递之后的信息:
{15 jerry}
地址传递之前的信息:
{16 dalianmao}
地址传递之后的信息:
{21 taoqi}
package main import ( "fmt" ) type person struct { age int name string } func main() { per := person{ age: 15, name: "jerry", } fmt.Println(fmt.Sprintf("值传递之前的地址为:%p", &per)) dizhi(per) dizhi1(&per) } func dizhi(per person) { fmt.Println(fmt.Sprintf("值传递的地址为:%p", &per)) } func dizhi1(per *person) { fmt.Println(fmt.Sprintf("地址传递的地址为:%p", per)) }
结果是:
值传递之前的地址为:0xc042042400
值传递的地址为:0xc042042460
地址传递的地址为:0xc042042400
结合两个例子打印的值与地址信息,可见结构体类型值传递并不能改变结构体的信息,只有地址传递过可以,说明即便是结构体在值传递的时候也是复制一份传递过去。
package main import ( "fmt" ) func main() { array := []int{1} fmt.Println(array) methodArrayValue(array) fmt.Println(array) methodArrayValue1(&array) fmt.Println(array) } func methodArrayValue(array []int) { array = append(array, 2) } func methodArrayValue1(array *[]int) { *array = append(*array, 3) }
结果是:
[1]
[1]
[1 3]
package main import ( "fmt" ) func main() { array := []int{1} fmt.Println(fmt.Sprintf("传递之前的地址为:%p", &array)) methodArrayValue(array) methodArrayValue1(&array) } func methodArrayValue(array []int) { fmt.Println(fmt.Sprintf("值传传递的地址为:%p", &array)) } func methodArrayValue1(array *[]int) { fmt.Println(fmt.Sprintf("地址传递的地址为:%p", array)) }
结合两个例子打印的值与地址信息,可见数组在值传递时使用的也是重新复制一个数组传过去,而地址传递的时候直接把地址传了过去。
map的值传递与地址传递
package main import ( "fmt" ) func main() { infos := map[string]string{ "a": "A", } methodArrayValue(infos) fmt.Println(infos) methodArrayValue1(&infos) fmt.Println(infos) } func methodArrayValue(infos map[string]string) { infos["b"] = "B" } func methodArrayValue1(infos *map[string]string) { (*infos)["c"] = "C" }
打印结果是:
map[b:B a:A]
map[c:C a:A b:B]
package main import ( "fmt" ) func main() { infos := map[string]string{ "a": "A", } fmt.Println(fmt.Sprintf("原地址是:%p", &infos)) methodArrayValue(infos) methodArrayValue1(&infos) } func methodArrayValue(infos map[string]string) { fmt.Println(fmt.Sprintf("值传递的原地址是:%p", &infos)) } func methodArrayValue1(infos *map[string]string) { fmt.Println(fmt.Sprintf("地址传递的地址是:%p", infos)) }
打印结果是:
原地址是:0xc042004028
值传递的原地址是:0xc042004038
地址传递的地址是:0xc042004028
结合两个例子打印的值与地址信息,可见map在值传递时原来的值改变了,但是地址信息也改变了说明map在值传递时是重新分配了一个指针指向原来的值。
通过以上的例子可以看出,基本数据类型,结构体,数组在值传递的时候都是重新复制一份传递,而map在值值传递时则是重新分配了一个地址指向原来的值。如果想要提升效率使用地址传递,尤其在多属性的结构体与数组中,因为值传递需要把所有的信息都复制一份来使用;如果只想使用一下其值的信息但并不想改变原有的内容则可以使用值传递。
原文地址
相关文章推荐
- JNI中基本类型数组的传递方法(无需拷贝数据!!!)
- byte数组和流 Seralizable:Android基础 -- Activity之间传递数据(bitmap和map对象)
- Js从头学起(详细分析基本数据类型和引用类型的参数传递)
- PHP 函数传递基本数据类型和数组的内存传递方式
- Js从头学起(基本数据类型和引用类型的参数传递详细分析)
- JS基本数据类型和引用类型的参数传递详细分析
- 基本数据类型、传递数组引用变量 的交换
- Js从头学起(基本数据类型和引用类型的参数传递详细分析)
- JAVA IO分析二:字节数组流、基本数据&对象类型的数据流、打印流
- 使用python向C语言的链接库传递数组、结构体、指针类型的数据
- map技数,数组计数,结构体计数的相关比较与分析(一)
- go 数组(array)、切片(slice)、map、结构体(struct)
- 数组的基本用法(2)——数组元素的地址
- java基本数据类型传递与引用传递区别详解
- performSelector: withObject: afterDelay: 传递基本数据类型参数的bug
- C#调用c++的dll,结构体数组作为引用参数的传递方式
- 数据结构与算法JavaScript - 基本排序算法分析
- 长度为0的数组只用在结构体的最后一个成员,用以做一个地址标记,以后用。
- ASP.NET页面间数据传递方法总结及分析
- 分析Python处理基本数据<三>