【问题标题】:coercing nil into a number将 nil 强制转换为数字
【发布时间】:2010-02-24 09:57:33
【问题描述】:

这里发生了什么??

irb(main):001:0> a= nil
=> nil
irb(main):002:0> b = nil
=> nil
irb(main):003:0> a
=> nil
irb(main):004:0> a+b
NoMethodError: undefined method `+' for nil:NilClass
    from (irb):4
    from :0
irb(main):005:0> if a.nil? or b.nil?; a,b=0;end;
irb(main):006:0* c = a+b
TypeError: nil can't be coerced into Fixnum
    from (irb):6:in `+'
    from (irb):6
    from :0
irb(main):007:0>

如何通过将 nil 转换为数字来安全地执行算术运算?

【问题讨论】:

    标签: ruby coercion


    【解决方案1】:

    根据为什么有 nil 而不是数字,您可以决定将 nil 视为 0 对您有好处;在这种情况下,您可以执行以下操作:

    c = (a || 0) + (b || 0)
    

    当然,这只有在您知道为什么您使用 nil 而不是数字时才有意义...

    【讨论】:

    • 我个人更喜欢or 而不是||,它对很多人来说更容易阅读(即使我已经完成了足够多的编程,我最终将|| 阅读为“或”无论如何:P)。
    • @Dav:@foo ||= ... 语法呢?我经常使用它,为什么不总是使用||?实际上我只是在合理化:我只是更喜欢|| 而不是or :)
    • || 也优先于 or,因此两者并不总是可以互换的。
    • 这个优先级实际上是我喜欢它的原因,Jimmy - 在我看来,|| 在大多数情况下更适合实际逻辑操作;保留or 用于实际的“我有时想要实际的第二个值”的情况。
    【解决方案2】:

    为什么要添加nil?它专门设计为表示缺少值的东西(注意:nil 不是 0)。

    如果你真正想要做的是将两个值都设置为0,如果其中一个是当前 nil,那么你真正想要的是:

    if a.nil? or b.nil?; a,b=0,0; end
    

    您在上面的代码中的错误是a,b=0 部分,它仅将a 的值设置为0 - 它将b 设置为nil,因为左侧正在寻找两个值,并且右边只提供了一个(所以其他的假设是nil)。

    【讨论】:

      【解决方案3】:

      您的并行赋值 (a, b = 0) 导致 a=0b=nil,即它将 0 分配给 anil 分配给 b,因为右侧只有一个值一边。

      你想要的是: 如果a.nil?或 b.nil? a = b = 0;结尾 c = a + b

      显然代码仍然存在问题,因为当 ab 为 nil 时,您将 ab 的任何非 nil 值覆盖为 0。

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-23
      相关资源
      最近更新 更多