无需检入`||`,`!a || a.method`不能用多个变量完成

时间:2018-02-05 05:28:24

标签: crystal-lang

例如,如果我们要检查数组是nil还是空,我们可以写如下:

if !a || a.empty?
    puts "nil or empty!"
end
#-> OK

但是,如果我们想以相同的方式检查两个数组,则会发生错误:

if !a || !b || a.empty? || b.empty?
    puts "nil or empty!"
end
#-> Error, `undefined method 'empty?' for Nil`
#          in the expression `a.empty?`

交换!ba.empty?的位置并没有帮助,但不同的地方被指向为错误:

if !a || a.empty? || !b || b.empty?
    puts "nil or empty!"
end
#-> Still error, `undefined method 'empty?' for Nil`
#                but this error is in the expression `b.empty?`

为什么在这个(多个变量' s)案例编译器无法推断aba.empty?b.empty?是非零的分别被称为?

完整的可重复代码如下。

def foo (flag)
    if flag
        [] of Int32
    else
        nil
    end
end

# note, foo returns `Array(T) | Nil`
a = foo(true)
b = foo(true)

if !a || a.empty?
    puts "nil or empty!"
end
#-> OK

if !a || !b || a.empty? || b.empty?
    puts "nil or empty!"
end
#-> Error, `undefined method 'empty?' for Nil`
#          in the expression `a.empty?`

if !a || a.empty? || !b || b.empty?
    puts "nil or empty!"
end
#-> Still error, `undefined method 'empty?' for Nil`
#                but this error is in the expression `b.empty?`

2 个答案:

答案 0 :(得分:3)

这不是一个错误。

a || b || c || d

被解析为:

(((a || b) || c) || d)

所以在你的例子中你有:

!a || !b || a.empty? || b.empty?

这意味着它是

(((!a || !b) || a.empty?) || b.empty?)

所以来自:

!a || !b

您无法推断出有关ab的任何内容。

如果你添加括号,它会起作用:

if !a || (!b || (a.empty? || b.empty?))

答案 1 :(得分:-1)

这似乎是一个编译器错误。

但是您可以将条件放在括号中以使其有效:(!a || a.empty?) || (!b || b.empty?)