2015-11-15 100 views
2

目的:理解Golang *stringstring的区别Golang中的*字符串和字符串之间有什么区别?


尝试

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) 

但当*字符串被分配到一条条NG:

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

它能够重新打印字符串:

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

问题

  1. 为什么是*字符串=字符串,如!显示:"root"%!q(*string=0xc8200781f0)
  2. 在其他情况下,应该使用*字符串 而不是字符串,为什么?
  3. 为什么可以将 *字符串分配给字符串变量,而字符串显示不同,例如,显示:"root"%!q(*string=0xc8200781f0)
+1

变量有*标记是指针,或在存储器中的地址(把它看作当变量是房屋中的邮件地址)。有关更多信息,请参阅https://tour.golang.org/moretypes/1。 – ti7

回答

4

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

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

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

因此,要回答你的具体问题:

  1. %q动词在fmt包理解字符串(和字节的片),不是指针,因此明显乱码显示(当值的不预期类型匹配动词 - 这里%q - 与

  2. 指向一个字符串很少使用的实际类型和值传递)沿fmt功能显示%!q。在这里你需要返回,这将在后面,你必须返回一个指向字符串突变的字符串在Go的字符串是不变的(https://golang.org/ref/spec#String_types),所以在像flag.String案件。但是在惯用的Go中你不会经常看到这种情况。

  3. 您不会将*string(指向字符串的指针)分配给string。你在做什么,正如我刚才所说,是提领*string变量,提取其string价值。所以,你实际上分配stringstring。尝试在该行移除*,你会看到编译器错误消息。 (实际上,因为你使用的短变量声明符号,:=,你不会看到一个编译器错误,但您的变量将被宣布为指针到一个字符串。试试这个,以便更好地了解这是怎么回事于:

    var s string 
    s = username 
    

这将引发编译器错误)。

相关问题