在golang中,&和*之间有什么区别

tyo*_*nne 13 go

有人可以解释GO lang中&和*之间的区别吗?并举例说明何时使用&和*来说明差异?根据我的阅读,它们都与访问变量内存位置有关,但我不知道何时使用&或*.

Aka*_*all 19

这是一个非常简单的例子,说明了如何使用&*使用.注意,*可以用于两个不同的事情1)将变量声明为指针2)以取消引用指针.

package main

import "fmt"

func main() {
    b := 6 

    var b_ptr *int // *int is used delcare variable
                   // b_ptr to be a pointer to an int

    b_ptr = &b     // b_ptr is assigned value that is the address
                       // of where variable b is stored

    // Shorhand for the above two lines is:
    // b_ptr := &b

    fmt.Printf("address of b_ptr: %p\n", b_ptr)

    // We can use *b_ptr get the value that is stored
    // at address b_ptr, or dereference the pointer 
    fmt.Printf("value stored at b_ptr: %d\n", *b_ptr)

}
Run Code Online (Sandbox Code Playgroud)

结果:

address of b_ptr: 0xc82007c1f0
value stored at b_ptr: 6
Run Code Online (Sandbox Code Playgroud)


Com*_*ode 15

这有助于我更好地理解,您可以在操场上运行代码并稍微玩一下以查看它的行为链接:https : //play.golang.org/p/c7jxLJkdRDd(如果将来链接失效,只需复制粘贴代码如下)

package main

import (
    "fmt"
)

func main() {

    var a = 5
    var p = &a // copy by reference
    var x = a  // copy by value

    fmt.Println("a = ", a)   // a =  5
    fmt.Println("p = ", p)   // p =  0x10414020
    fmt.Println("*p = ", *p) // *p =  5
    fmt.Println("&p = ", &p) // &p =  0x1040c128
    fmt.Println("x = ", x)   // x =  5

    fmt.Println("\n Change *p = 3")
    *p = 3
    fmt.Println("a = ", a)   // a =  3
    fmt.Println("p = ", p)   // p =  0x10414020
    fmt.Println("*p = ", *p) // *p =  3
    fmt.Println("&p = ", &p) // &p =  0x1040c128
    fmt.Println("x = ", x)   // x =  5

    fmt.Println("\n Change a = 888")
    a = 888
    fmt.Println("a = ", a)   // a =  888
    fmt.Println("p = ", p)   // p =  0x10414020
    fmt.Println("*p = ", *p) // *p =  888
    fmt.Println("&p = ", &p) // &p =  0x1040c128
    fmt.Println("x = ", x)   // x =  5

    fmt.Println("\n Change x = 1")
    x = 1
    fmt.Println("a = ", a)   // a =  888
    fmt.Println("p = ", p)   // p =  0x10414020
    fmt.Println("*p = ", *p) // *p =  888
    fmt.Println("&p = ", &p) // &p =  0x1040c128
    fmt.Println("x = ", x)   // x =  1

    &p = 3 // error: Cannot assign to &p because this is the address of variable a
}
Run Code Online (Sandbox Code Playgroud)


eva*_*nal 7

&是运营商的地址。*在某些情况下表示一个指针,在其他情况下它被用作“取消引用运算符”。

所以基本上,如果你p := &SometType{}使用运算符的地址来返回使用复合文字语句创建的对象的地址,SomeType{}如果我要删除它,我将不再拥有引用,而是直接将值分配给p. 在这种情况下p将是 a*SomeType因为那是我采用的地址类型。如果我*在它前面声明一个类型,我将它指定为指向该类型的指针。

现在剩下的最后一个用途是作为尊重运算符,根据我的经验,您在 Go 中不会使用这么多,但它在 C 和 C++ 中非常常见。这用于返回实际值,而不是它最常用于分配的杠杆。因为就像如果我有p并且它是一个*SomeType并且在本地我想分配给一个实例,SomeType那么我将需要以下语句,someType := *p以便将值分配给我的值类型。

希望这个解释有帮助。这不是最技术性的,而是我的目标是提供对常见用途的理解。


rua*_*akh 6

他们是相反的.如规范的"地址运算符"部分所述:

对于x类型的操作数T,地址操作&x生成类型*T为to 的指针x.[...]

一个操作数x指针类型*T,指针间接*x表示类型的变量T指向x.如果xnil,尝试评估*x将导致运行时恐慌.

换句话说:&接受一个变量(或其他可寻址的实体)并返回指向它*的指针,然后接受一个指针并返回它指向的东西(除非它是nil,意味着它不指向任何东西).


Vat*_*ine 6

& 从变量创建一个指针。

* “获取”存储在指针指向的值。

对于类型,var *type表示“*var 是类型类型”(如果没有变量,它仅表示“指向某种类型的指针”。