星号在“Go”中有什么作用?

zphenhs4  于 2023-06-03  发布在  Go
关注(0)|答案(7)|浏览(507)

我一直在浏览并试图理解Go website上的示例,并且在这样的示例中不断遇到特殊的星号字符:

s := "hello"
if s[1] != 'e' {
    os.Exit(1)
}
s = "good bye"
var p *string = &s
*p = "ciao"

还有,我刚刚注意到,&s是怎么回事?它是通过引用赋值的吗(我可能在这里使用PHP)?

pkbketx9

pkbketx91#

附加到类型(*string)的*表示指向该类型的指针。
*附加到赋值中的变量(*v = ...)表示间接赋值。也就是说,更改变量所指向的值。
附加到变量或表达式(*v)的*表示指针解引用。也就是说,取变量所指向的值。
附加到变量或表达式(&v)的&表示引用。也就是说,创建一个指向变量值或字段的指针。

jq6vz3qz

jq6vz3qz2#

我猜它的意思和C中的一样
p is a pointer to a string
语句var p *string = &s将把s对象的地址分配给p
下一行*p = "ciao"将更改s的内容
请参阅语言设计常见问题解答中的此链接
有趣的是,没有指针算术
为什么没有指针算法?安全性。如果没有指针算法,就有可能创建一种语言,它永远不会派生出一个非法的地址,而这个地址会错误地成功。编译器和硬件技术已经发展到使用数组索引的循环可以与使用指针算术的循环一样高效的程度。此外,缺少指针算法可以简化垃圾收集器的实现。

fwzugrvs

fwzugrvs3#

*Go lang * 地址、指针和类型:

s := "hello"      // type string
t := "bye"        // type string
u := 44           // type int
v := [2]int{1, 2} // type array
q := &s           // type pointer

所有这些Go变量都有一个address in memory。它们之间的区别是字符串类型保存字符串值,int类型保存整数值,指针类型保存 * 地址 *。因此,即使是保存地址的变量也有自己的内存地址。

指针:

在变量名计算为它的地址之前添加&。或者想:“这是我的地址,这样你就知道在哪里能找到我。”

// make p type pointer (to string only) and assign value to address of s
var p *string = &s // type *string
// or
q := &s // shorthand, same deal

在指针变量之前添加*会取消引用它所保存的地址的指针。或者想,“把动作传递到我的值所在的地址。”

*p = "ciao"   // change s, not p, the value of p remains the address of s

// j := *s    // error, s is not a pointer type, no address to redirect action to
// p = "ciao" // error, can't change to type string

p = &t        // change p, now points to address of t
//p = &u      // error, can't change to type *int

// make r type pointer (to a pointer which is a pointer to a string) and assign value to address of p
var r **string = &p // shorthand: r := &p

w := (  r == &p) // (  r evaluates to address of p) w = true
w =  ( *r == p ) // ( *r evaluates to value of p [address of t]) w = true
w =  (**r == t ) // (**r evaluates to value of t) w = true

// make n type pointer (to string) and assign value to address of t (deref'd p)
n := &*p
o := *&t // meaningless flip-flop, same as: o := t

// point y to array v
y := &v
z := (*y)[0] // dereference y, get first value of element, assign to z (z == 1)

在这里玩:http://play.golang.org/p/u3sPpYLfz7

xiozqbni

xiozqbni4#

我是这么看的不同的措辞可能有助于人们更好地理解它(您可以复制粘贴代码并检查输出):

package main

import (
    "fmt"
)

func main() {
    // declare a variable of type "int" with the default value "0"
    var y int

    // print the value of y "0"
    fmt.Println(y)

    // print the address of y, something like "0xc42008c0a0"
    fmt.Println(&y)

    // declare a variable of type "int pointer"
    // x may only hold addresses to variables of type "int"
    var x *int

    // y may not simply be assigned to x, like "x = y", because that 
    // would raise an error, since x is of type "int pointer", 
    // but y is of type "int"

    // assign address of y "0xc42008c0a0" as value to x
    x = &y

    // print the value of x "0xc42008c0a0" which is also the address of y
    fmt.Println(x)

    // print the address of x, something like "0xc420030028" 
    // (x and y have different addresses, obviously)
    fmt.Println(&x)

    // x is of type "int pointer" and holds an address to a variable of 
    // type "int" that holds the value "0", something like x -> y -> 0;
    // print the value of y "0" via x (dereference)
    fmt.Println(*x)

    // change the value of y via x
    *x = 1; /* same as */ y = 1

    // print value of y "1"
    fmt.Println(y); /* same as */ fmt.Println(*x)
}
xpszyzbs

xpszyzbs5#

*字符用于在C和Go中定义指针。变量不是一个真实的值,而是一个指向值位置的地址。&运算符用于获取对象的地址。

eivnm1vs

eivnm1vs6#

我不知道Go,但基于语法,它似乎类似于C -这是一个指针。它类似于一个参考,但更低的水平和更强大。它包含所讨论项目的内存地址。&a获取一个变量的内存地址,*a取消引用它,获取内存地址处的值。
此外,声明中的*意味着它是一个指针。
所以是的,这就像PHP中的s的值被改变了,因为p&s指向同一个内存块。

euoag5mw

euoag5mw7#

golang中的 * 作为指针。指针保存值的内存地址。
类型 *T是指向T值的指针。它的零值是nil。

var p *int

&运算符生成指向其操作数的指针。

i := 42
p = &i
  • 运算符表示指针的基础值。
fmt.Println(*p) // read i through the pointer p
*p = 21         // set i through the pointer p

这被称为“解引用”或“定向”。
与C语言不同,Go语言没有指针运算。

package main

import "fmt"

func main() {
    i, j := 42, 2701

    p := &i         // point to i
    fmt.Println(*p) // read i through the pointer
    *p = 21         // set i through the pointer
    fmt.Println(i)  // see the new value of i

    p = &j         // point to j
    *p = *p / 37   // divide j through the pointer
    fmt.Println(j) // see the new value of j
}

相关问题