【问题标题】:Why is "nil" value for numbers 0?为什么数字 0 的“nil”值?
【发布时间】:2017-10-14 21:59:21
【问题描述】:

字符串"" 的“nil”值对我来说是有意义的,但0 是一个合法数字。例如,一个房间的人数可以是0,但一个人的名字不能是""。这个约定背后的原因是什么?

(编辑)附加信息:

我想做的是有一种方法来测试是否为数字设置了值。将某人的姓名设置为"" 显然是不正确的,而将整数设置为零可能是合法的。是否有解决这种情况的典型方法?

【问题讨论】:

  • "" 也是一个合法的字符串。在 Go 中,只有指针和接口值可以为 nil,所以真的没有办法让数字为 nil。
  • 也许你的意思是zero value 的号码?
  • nil(或 null/NULL 在其他语言中)不一样,或者替换空字符串或零。它是一个概念,表示没有任何值,一个未知的值或一个在上下文中无关紧要的值。空字符串是无效的人名,但 nil 可能是完全有效的值。这意味着这个名字还不知道。

标签: go


【解决方案1】:

字符串"" 的“nil”值对我来说是有意义的,但0 是一个合法数字。

你的说法有两个明显的问题:

  1. 不存在字符串的nil”值
  2. "" 是一个完全合法的字符串。

您似乎将 Go 的“零值”概念与 nil 混淆了。这些概念几乎完全不相关。

  • 字符串的零值为""
  • 数字的零值为0
  • 指针或接口的零值为nil。这是nil 和“零值”真正相互关联的唯一地方。

在 Go 中,其他字符串、数字和其他具体类型永远不能是 nil。 (指向这些类型的指针可以是,但这显然是不同的)。因此,谈论“字符串的 nil 值”或“数字的 nil 值”甚至没有意义。


针对您的编辑,这个问题已经在各种情况下得到了回答。有关 JSON 解组的示例,请参阅 here。不过,简而言之,您必须使用数字/字符串类型以外的其他内容。使用指针或包装器类型(例如sql.NullInt64)。

【讨论】:

    【解决方案2】:

    必须从类型的有效值集中选择一个指定值。还有什么比zero-value更符合这个职位的条件?

    nil 不是数字类型的有效值(例如intuintint32 等),所以这是不可能的。

    0 的好处是在二进制表示中它是全零。它的名字也符合“零值”

    也许是-1?二进制表示中的-1 是完整的(使用2's complement 表示)。 -1 不再特别。

    那么也许是最小值?如果是int32,则为-1 << 31,即-2147483648。但是如果类型是无符号的,例如uint32,那又是0。此外,采用int 类型,最小值甚至不是常数,因为它取决于目标架构(可能是-1 << 31-1 << 63)。

    如果0 是您使用的值,并且您想区分它是否已经被设置(或者如果该值只是零值),请使用可能具有@ 的指针(例如*int) 987654342@值(零值)表示尚未设置。

    另一种选择是使用第二个变量(可能是bool 类型),它的true 值表示已设置数字。

    还有更多技巧(选择一个巧妙的、未使用的有效值),请查看How do I represent an Optional String in Go?

    【讨论】:

      【解决方案3】:

      对于string,默认值为"";对于bool,默认值为false;对于int,默认值为0

      你可以使用指针。

      var num *int
      if num == nil {
          // num is not set
      } else {
          // num is set
          if *num == 0 {
              // num is set to 0
          } else {
              // num is set to another integer
          }
      }
      

      同样可以判断是否设置了布尔值。

      【讨论】:

        【解决方案4】:

        在 Go 中是否有解决这种情况的典型方法?

        空字符串还是零是有效/无效值取决于应用程序。空名称可能对您的应用程序无效,但在其他情况下可能有效。

        在 Go 中处理此问题的一种方法是创建一个结构,并在其中表示您是否拥有该值。例如:

        type Person struct {
          Name    string
          HasName bool
          Age     int
          HasAge  bool
        }
        

        对于这样一个人为的例子来说,这似乎有点麻烦,但在更复杂的场景中,拥有额外字段的开销是最小的。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-09-30
          • 1970-01-01
          • 2020-02-29
          • 1970-01-01
          • 2018-03-09
          • 1970-01-01
          • 2017-11-25
          相关资源
          最近更新 更多