dtwzwmv87399 2015-11-15 17:29
浏览 2233
已采纳

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

Aim: understanding the difference between *string and string in Golang


Attempt

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)
}

results in:

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

but when the *string is assigned to a string:

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

it is able to print the string again:

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

Questions

  1. Why is a *string != string, e.g. display of: "root" vs. %!q(*string=0xc8200781f0)?
  2. In what other cases should a *string be used instead of a string and why?
  3. Why is it possible to assign a *string to a string variable, while the display of the string is different, e.g. display of: "root" vs. %!q(*string=0xc8200781f0)?
  • 写回答

1条回答 默认 最新

  • dongping2023 2015-11-15 17:58
    关注

    A *string is a pointer to a string. If you're not familiar with pointers, let's just say that it's a value that holds the address of another value, instead of the value itself (it's a level of indirection).

    When a * is used in a type, it denotes a pointer to that type. *int is a pointer to an integer. ***bool is a pointer to a pointer to a pointer to a bool.

    flag.String returns a pointer to a string because it it can then modify the string value (after the call to flag.Parse) and you are able to retrieve that value using the dereference operator - that is, when using * on a variable, it dereferences it, or retrieves the value pointed to instead of the value of the variable itself (which in the case of a pointer would just be a memory address).

    So to answer your specific questions:

    1. the %q verb in the fmt package understands strings (and slices of bytes), not pointers, hence the apparent gibberish displayed (when a value is not of the expected type for the matching verb - here %q - the fmt functions display %!q along with the actual type and value passed)

    2. A pointer to a string is very rarely used. A string in Go is immutable (https://golang.org/ref/spec#String_types) so in cases like flag.String where you need to return a string that will be mutated later on, you have to return a pointer to a string. But you won't see that very often in idiomatic Go.

    3. You are not assigning a *string (pointer to a string) to a string. What you are doing, as I mentioned earlier, is dereferencing the *string variable, extracting its string value. So you are in fact assigning a string to a string. Try removing the * on that line, you'll see the compiler error message. (actually, because you're using the short variable declaration notation, :=, you won't see a compiler error, but your variable will be declared as a pointer-to-a-string. Try this instead, to better understand what's going on:

      var s string
      s = username
      

    That will raise the compiler error).

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 HFSS 中的 H 场图与 MATLAB 中绘制的 B1 场 部分对应不上
  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?