Golang中* string和字符串之间有什么区别?

时间:2015-11-15 17:29:10

标签: string go

目标:了解Golang中*stringstring之间的区别

尝试

func passArguments() {
    username := flag.String("user", "root", "Username for this server")
    flag.Parse()
    fmt.Printf("Your username is %q.", *username)
    fmt.Printf("Your username is %q.", username)
}

结果:

Your username is "root".Your username is %!q(*string=0xc820072200)

但是当*字符串被分配给字符串时:

bla:=*username
fmt.Printf("Your username is %q.", bla)

它能够再次打印字符串:

Your username is "root".Your username is %!q(*string=0xc8200781f0).Your username is "root".

问题

  1. 为什么是* string!= string,例如显示:"root" vs. %!q(*string=0xc8200781f0)
  2. 在其他情况下应该是*字符串 用而不是字符串,为什么?
  3. 为什么可以指定一个 *字符串到字符串变量,而字符串的显示不同,例如显示:"root" vs. %!q(*string=0xc8200781f0)

1 个答案:

答案 0 :(得分:5)

*string是指向字符串的指针。如果你不熟悉指针,那么我们只是说它是一个保存另一个值的地址的值,而不是值本身(它是一个间接的级别)。 / p>

当在类型中使用*时,它表示指向该类型的指针。 *int是指向整数的指针。 ***bool是指向指向bool的指针的指针。

flag.String返回一个指向字符串的指针,因为它可以修改字符串值(在调用flag.Parse之后),并且您可以使用取消引用运算符检索该值 - 也就是说,当对变量使用*时,它解除引用,或者检索指向的值而不是变量本身的值(在指针的情况下,它只是一个内存地址) )。

所以回答你的具体问题:

  1. %q包中的fmt动词理解字符串(和字节切片),而不是指针,因此显示明显的乱码(当值不是预期的类型时)匹配动词 - 此处%q - fmt函数显示%!q以及传递的实际类型和值)

  2. 很少使用指向字符串的指针。 Go中的字符串是不可变的(https://golang.org/ref/spec#String_types)所以在像flag.String这样的情况下,你需要返回一个稍后将被改变的字符串,你必须返回一个指向字符串的指针。但是,你不会经常在惯用的Go中看到它。

  3. 您没有将*string(指向字符串的指针)分配给string。正如我之前提到的,您正在做的是取消引用 *string变量,提取其string值。因此,您实际上正在为string分配string。尝试删除该行上的*,您将看到编译器错误消息。 (实际上,因为您使用了短变量声明符号:=,所以您不会看到编译器错误,但您的变量将被声明为指向字符串的指针。相反,为了更好地理解发生了什么:

    var s string
    s = username
    
  4. 这会引起编译错误。)