xuguiyi00 2020-04-22
func main() { // 指针地址,指针类型,指针取值 // &取地址,*根据地址取值 a := 10 b := &a fmt.Println(*b) //指针类型 *int *unit *float *string *array *struct 等 // 指针的定义 // var 变量名 指针类型 var p1 *int //定义空指针 p1 = &1 }
func main() { arr := [4] int{1, 2, 3, 4} fmt.Println(arr) // 定义一个数组指针 var p1 *[4] int fmt.Println(p1) // nil 空指针 fmt.Ptintf("%T\n", p1) // *[4] int p1 = &arr1 fmt.Println(p1) fmt.Printf("%p\n", p1) fmt.Printf("%p\n", &p1) // 通过数组指针操作数组 (*p1)[0] = 100 // 可以简写为 // p1[0] = 200 fmt.Println(arr) // [100 2 3 4] }
func main() { a := 1 b := 2 c := 3 d := 4 arr1 := [4] int{a, b, c, d} arr2 := [4] *int{&a, &b, &c, &4} fmt.Println(arr1) fmt.Println(arr2) // 操作数组与指针数组的区别 //arr1[0] = 100 //fmt.Println(a) //fmt.Println(arr1, &arr1[0]) // 值类型,将a,b,c,d的值拷贝过来放到数组中,修改的是数组空间内的数据,与a,b,c,d没有关系 //fmt.Println(arr2) *arr2[0] = 1000 fmt.Println(a) fmt.Println(arr1, &arr1[0]) fmt.Println(arr2, *arr2[0]) // 通过指针数组中的内存地址,修改了a,b,c,d的值,类似于Python列表 b = 2000 fmt.Println(b) fmt.Println(arr1, &arr1[1]) fmt.Println(arr2, *arr2[1]) }
总结:
数组是值类型,将值拷贝了一份放到数内存中,二者相互独立,互不影响,修改数组后数组内存中的值改变,不会影响拷贝的源数据,源数据改变,也不会影响数组
Go中切片是对原数组的引用,二者互相关联,修改切片元素的值后,与之关联的底层数组的也会受到影响,同理,底层数组的改变也会影响切片的值
Python中的列表是引用类型,基于指针数组,修改可变元素后(可变类型与不可变类型),引用的源数据也会受到影响---
// 函数指针 // Go中函数默认就是一个指针类型,不需要* func main() { var a func() a = func1 a() } func func1() { fmt.Println("这是func1()") } // 指针函数 // 返回值为指针的函数 func main() { // arr1是数组,值传递,将func1中返回的arr的值拷贝到arr1中,当func1调用结束,arr被销毁 arr1 := func1() fmt.Printf("arr1的类型:%T,内存地址:%p,值:%v\n",arr1, &arr1, arr1) // arr2是指针类型,值传递,将func2中返回的arr的内存地址保存到arr2中,arr不会随着func2的结束而销毁(和闭包一样改变了变量的生命周期?) arr2 := func2() fmt.Printf("arr2的类型:%T,内存地址:%p,值:%v\n",arr2, &arr2, arr2) } // 这是普通函数 func func1() { arr := [4] int{1, 2, 3, 4} return arr } // 这是指针函数 func func2() *[4] int { arr := [4] int{1, 2, 3, 4} return &arr }
func main() { /* 指针作为参数 参数:值传递和引用传递 总结:值传递,拷贝一份,不会影响原数据,但消耗内存 引用传递通过指针操作数据,会改变原数据,但节省内存(拷贝的数据可能很大) */ n := 10 // 值传递,func1改变不会影响n,a随着func1结束而被销毁 func1(n) fmt.Println(n) // 引用传递,将n的内存地址拷贝到a中,通过*a更改了n,a也会随着func2的结束而被销毁,但n已经改变 func2(&n) fmt.Println(n) } func func1(a int) { a = 100 fmt.Println(a) } func func1(a *int) { *a = 100 fmt.Println(*a)