golang里面表示指针的*和&符号有什么区别?

&a和星号a都表示指针,有什么区别?什么时候该用星号,什么时候该用&?

已邀请:

xbgxwh - 后端

赞同来自: qichengzx duanquanyong josjonah fuckshit

指针,或者说pointer是一串指向某个内存地址的字符串,所谓指向是指这串字符串的内容是内存地址的值

&表示取地址,例如你有一个变量a那么&a就是变量a在内存中的地址,对于golang,指针也是有类型的,比如如果a是一个string那么&a是一个string的指针类型,在go里面叫&string

所以你看到b := &a,a,b是两个不同的变量,a是string类型,b是&string类型,你用fmt去打印b,你会发现它是一串内存地址,而非a的值

所以为了拿到a的值,有个操作*,用来取出指针对应内存地址里存的值,所以当你fmt打印一下*b它会跟a一模一样

a := "123"
b := &a
fmt.Println(a)
fmt.Println(b)
fmt.Println(*b)

xkey - go

赞同来自: Body cholerae Hawken

这个问题个人觉得没法解释,就是指针操作,不会指针解释再多也白搭

Bekcpear

赞同来自: duanquanyong

这是一个很基础但是用起来可以变得很复杂的问题,我单从 Go 来说一个简单例子,不参考别的什么语言。

指针,顾名思义就是指向一个变量的值,看下面这段代码:

package main

import "fmt"

func reverse(p *[]int) {
    for i, j := 0, len(*p)-1; i < len(*p)/2; i, j = i+1, j-1 {
        (*p)[i], (*p)[j] = (*p)[j], (*p)[i]
    }
}

func main() {
    v := []int{1, 2, 3, 4}
    reverse(&v)
    fmt.Println(v)
}

这段代码你可以直接运行,其效果就是反转了 v 这个切片的内容,且并没有需要 reverse 函数返回修改好的切片,这就是指针的作用之一,下面我来解释。

主要从代码第 13 行 reverse(&v) 开始看, & 操作符生成了其操作数 v 的地址,地址类型为 *[]int (一个指针类型),于是我的 reverse 函数得到了这个指针。

接着来看 reverse 函数,在 Go 里面是没有指针运算的,但通过 * 操作符可以取得指针所对应的基本值然后进行操作。所以 *p 又变成了切片类型,然后通过一个循环就反转了切面所存储值的顺序。

简单总结:

  • & 仅用于生成其操作数对应的地址,也就是用于生成指针
  • * 会出现在两个内容上:
    • 一个是类型, * Type 这样的格式代表了一个指针类型
    • 一个是指针, * Pointer 这样的格式用于获取指针所对应的基本值

最后再来看这段代码用指针的好处。当给一个函数传参时其实是会在内存空间复制一份后传递的,那么如果单纯使用切片类型传递的话,最后在 reverse 函数下处理后的切片和在 main 函数下的切片 v 是两个完全不同的,所以最后往往需要在 reverse 函数下返回处理好的切片给主函数。而像上述这种直接传递其指针,虽然也是会复制一份指针类型的变量后传递,但是却可以在 reverse 函数下通过传递过来的指针(地址)获取到原始的切片,并直接修改其内容。那么在数据内容很大的情况下就起到了节约程序开销的作用。

koala

赞同来自:

&取地址 *解引用

LockingCoder - 80后

赞同来自:

*主要用在指针类型声明和取地址上实际值。 &用于取地址

type demo struct {
    Value string
}
var pt *demo //*用作指针类型声明
pt = &demo{Value: "val"} //&取值地址
d1 := *pt //*用作取地址指向的实际值

changjixiong - 时常做白日梦的程序员

赞同来自:

楼主可能需要先阅读《the c program language》

要回复问题请先登录注册