2015-11-15 139 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 
    

這將引發編譯器錯誤)。

相關問題