brs*_*slv 3 ruby conditional iterator
在PHP中,这评估为true:
$a = 1
$b = 2
var_dump($a && $b); // true
Run Code Online (Sandbox Code Playgroud)
在ruby中,这评估为2:
a = 1
b = 2
p a && b # 2
Run Code Online (Sandbox Code Playgroud)
为什么ruby返回最后一个语句的值(当第一个为真且第二个为真时)并且不返回布尔值?
我有两个数组,我用外部迭代器迭代它们:
a = [1,2,3].to_enum
b = [5,6,7].to_enum
c = []
begin
while a_next = a.next && b_next = b.next
result = a_next + b_next
p "a[x] + b[x] = c[x] = #{a_next} + #{b_next} = #{result}"
c << result
end
rescue
p c
end
Run Code Online (Sandbox Code Playgroud)
条件:while a_next = a.next && b_next = b.next集合a_next = b_next(我认为第一个问题似乎与此行为有关).但是当我包装两个&&操作数时,它按预期工作:(a_next = a.next) && (b_next = b.next).
Truthy和Falsy与true和false
考虑
3 && 4 #=> 4
3 && false #=> false
nil && 4 #=> nil
false && nil #=> false
3 || 4 #=> 3
3 || false #=> 3
nil || 4 #=> 4
false || nil #=> nil
Run Code Online (Sandbox Code Playgroud)
回想一下,在Ruby中,false并nil以逻辑方式false("falsy")进行评估,其他一切评估为逻辑true("truthy").因此,通常不需要将伪值转换为值false或将truthy值转换为true.我们可以写一下,例如,
3 ? "happy" : "sad"
#=> "happy"
nil ? "happy" : "sad"
#=> "sad"
Run Code Online (Sandbox Code Playgroud)
将Truthy和Falsy转换为true和false
如果你坚持,你可以转换和使用双惊叹技巧truthy和falsey值:truefalse
!!3 => !(!3) => !(false) => true
!!nil => !(!nil) => !(true) => false
Run Code Online (Sandbox Code Playgroud)
随着贸易的技巧&&和||
拥有&&和||定义它们的方式通常非常方便.例如,如果h是哈希,假设我们写
h[k] = (h[k] || []) << 3
Run Code Online (Sandbox Code Playgroud)
如果h没有钥匙k,h[k] #=> nil,所以表达式简化为
h[k] = [] << 3
#=> [3]
Run Code Online (Sandbox Code Playgroud)
另一个例子是对arr整数或者数组的元素求和nil:
arr.reduce(0) { |t,n| t + (n || 0) }
Run Code Online (Sandbox Code Playgroud)
还有许多其他创造性的方法可以在Ruby中使用这两个操作符,如果它们只是返回true或者是不可能的false.
代码段
现在让我们转到您提到的代码段.
首先,你的救援条款有点分散注意力,而且while论证总是正确的,因此有点人为,所以让我们写下你所拥有的内容如下.
a = [1,2,3].to_enum
#=> #<Enumerator: [1, 2, 3]:each>
b = [5,6,7].to_enum
#=> #<Enumerator: [5, 6, 7]:each>
c = []
loop do
a_next = a.next
b_next = b.next
result = a_next + b_next
p "a[x] + b[x] = c[x] = #{a_next} + #{b_next} = #{result}"
c << result
end
# "a[x] + b[x] = c[x] = 1 + 5 = 6"
# "a[x] + b[x] = c[x] = 2 + 6 = 8"
# "a[x] + b[x] = c[x] = 3 + 7 = 10"
p c
#=> [1, 2, 3]
Run Code Online (Sandbox Code Playgroud)
在枚举a.next所有元素之后执行时a,它将引发StopIteration异常(参见Enumerator#next).我选择的理由内核#环比while是前者的手柄StopIteration通过终止循环的例外.因此,不需要救援.(顺便说一句,如果你做了救援while,你想要rescue StopIteration,而不是拯救所有例外.)
这里有几个方面.
为什么ruby返回最后一个语句的值(当第一个为真且第二个为真时)并且不返回布尔值?
因为这种方式更有用.事实上,这种语义非常有用,PHP 7添加了它(但作为一个新的运算符??).在Ruby中,就像在PHP中一样,所有值都是真实的或虚假的.与PHP不同,Ruby对此有一个更严格的想法:只有false而且nil是假的,其他一切都是真的.这允许您轻松提供默认值:
name = options[:name] || "John Doe"
Run Code Online (Sandbox Code Playgroud)
如果options[:name]没有找到并返回nil,则该部分是假的,并且||将返回右侧; 否则,options[:name]将被退回.
在大多数情况下,您不需要布尔值,因为真实性或虚假性就足够了.如果你真的想要一个布尔值,例如为了不泄露私人信息,这个习惯用法!!value很常见:
def has_name?
!!(self.name || self.nickname)
end
Run Code Online (Sandbox Code Playgroud)
!(否定)的结果总是布尔值; 如果你否定了两次,你就会将真实性转化为true虚假性false.
最后,
那个错误我是在病情的事情
while-while a_next = a.next && b_next = b.next-这样写的,它总是将a_next = b_next(第一个问题似乎与这种行为,我认为).但是,当我包装两个&&操作数时 - 它按预期工作 -(a_next = a.next) && (b_next = b.next) # works ok.
然后你需要包装它们.这是由于运算符优先级,并且在设计上就像这样工作,因为写入更为正常
blue_green = colour == :blue || colour == :green
Run Code Online (Sandbox Code Playgroud)
比
blue_green = (colour == :blue || colour == :green)
Run Code Online (Sandbox Code Playgroud)
还有另一组布尔运算符实际上是按照你的建议工作的,唯一的区别是优先级,所以你可以编写它并让它工作:
while a_next = a.next and b_next = b.next
Run Code Online (Sandbox Code Playgroud)
它完全相同
while (a_next = a.next) && (b_next = b.next)
Run Code Online (Sandbox Code Playgroud)
但是警告:使用and和or运算符代替&&和||不正确是一个常见的错误,许多样式指南直接禁止它们(它们仅在此上下文中有用- 在循环条件内分配 - 而且可以用括号代替).例如:
在
and和or关键字都被禁止.这不值得.总是使用&&而||不是.
| 归档时间: |
|
| 查看次数: |
703 次 |
| 最近记录: |