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

ruoxqz4g  于 2023-02-06  发布在  Go
关注(0)|答案(7)|浏览(200)

有人能解释一下GO lang ..中&和 * 的区别吗?并举例说明什么时候用&和 * 来说明区别?从我读到的内容来看,它们都与访问变量内存位置有关,但我不确定什么时候用&或 *。

k4aesqcs

k4aesqcs1#

下面是一个非常简单的例子,说明了&*的用法。注意*可以用于两种不同的用途:1)声明一个变量为指针; 2)解引用一个指针。

package main

import "fmt"

func main() {
    b := 6 

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

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

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

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

    // We can use *b_ptr to get the value that is stored
    // at address b_ptr, known as dereferencing the pointer
    fmt.Printf("value stored at b_ptr: %d\n", *b_ptr)
    
}

结果:

address of b_ptr: 0xc82007c1f0
value stored at b_ptr: 6
gt0wga4j

gt0wga4j2#

这帮助我更好地理解,你可以运行代码在操场上玩一下,看看它是如何表现的链接在这里: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
}
zwghvu4y

zwghvu4y3#

它们正好相反,正如规范的"地址操作符"部分所解释的:
对于T类型的操作数x,地址操作&x生成指向x*T类型的指针。
对于指针类型为*T的操作数x,间接指针*x表示x指向的T类型的变量。如果xnil,则尝试计算*x将导致运行时死机。
换句话说:&接受一个变量(或其他可寻址实体)并返回指向它的指针,而*接受一个指针并返回它所指向的东西(除非它是nil,这意味着它不指向任何东西)。

slhcrj9b

slhcrj9b4#

&是操作符的地址。*在某些情况下表示指针,在其他情况下用作“解引用操作符”。
所以基本上,如果你执行p := &SometType{},运算符的地址是用来返回,用复合语句创建的对象的地址,如果我删除了它,我将不再有一个引用,而是直接赋值给p,在这种情况下,p将是一个*SomeType,因为这是我取的类型的地址。如果我声明了一个类型,前面有*,我就把它指定为指向该类型的指针。
最后一个用法是作为一个顺从运算符,根据我的经验,你在Go语言中不会用到这么多,但在C和C++中非常常见,它是用来返回实际值的,它最常用于赋值,因为如果我有一个p,它是一个*SomeType,在本地,我想赋值给SomeType一个示例,那么我“我需要下面的语句someType := *p,以便将值赋给我的值类型。
希望这些解释能有所帮助。这不是最专业的,我的目标是提供对常见用法的理解。

qnzebej0

qnzebej05#

&从变量生成指针。
*“取出”指针指向的存储值。
对于类型,var *type表示“*var的类型为 type”(如果没有变量,则表示“指向 type 的某个对象的指针”)。

csga3l58

csga3l586#

*B int//创建变量
*B = 5//赋值
fmt.Println(*B)//获取值

7nbnzgx9

7nbnzgx97#

&和 * 主要用于以下函数:

package main

import (
    "fmt"
)

type Person struct {
    name     string
    ageYears int
    areDays  int
}

func main() {
    john := Person{name: "John", ageYears: 46}
    toDays(&john)
    fmt.Println(john) //{John 46 16790}
    toDays2(john)
    fmt.Println(john) //{John 46 16790}
}

func toDays(p *Person) {
    p.areDays = p.ageYears * 365
}

func toDays2(p Person) {
    p.areDays = -1
}

相关问题