Ruby - Next if与Next unless

jucafojl  于 2023-01-16  发布在  Ruby
关注(0)|答案(3)|浏览(213)

next ifnext unless之间的区别是什么?
我对next if的理解是next only if variable == value,但在下面的代码中,第二个next语句不起作用。next if datastore.id == 5它绕过此语句并继续执行,即使datastore.id == 2datastore.id == 3等,

$evm.vmdb(:ManageIQ_Providers_Vmware_InfraManager_Storage).all.each do |datastore|
  next if datastore.ems_id == provider.id.to_s
  next if datastore.id == 5
  dialog_hash[datastore[:id]] = "#{datastore.name} on #{datastore.ext_management_system.name}"
end

但是如果我把next if改成next unless,那么它就能正常工作。

$evm.vmdb(:ManageIQ_Providers_Vmware_InfraManager_Storage).all.each do |datastore|
  next if datastore.ems_id == provider.id.to_s        # Next if works here
  next unless datastore.id == 5                       # Next unless works here instead of next if
  dialog_hash[datastore[:id]] = "#{datastore.name} on #{datastore.ext_management_system.name}"
end
dojqjjoe

dojqjjoe1#

我将快速解释next以及ruby中ifunless之间的区别,并继续提出一些建议,您可以尝试让代码工作。

如果

如果条件为真,则代码将执行。

除非

如果条件为false,则代码将执行。其工作方式与以下相同:

if !(expression) { ... }

下一个

程序将跳过循环块中的其余代码,并跳到下一次迭代。
在您的示例中,如果在第一行中调用了next,则其余代码将不会运行。

$evm.vmdb(:ManageIQ_Providers_Vmware_InfraManager_Storage).all.each do |datastore|
  next if datastore.ems_id == provider.id.to_s  # if this condition is true, don't run rest of the code in this loop, and go to the next datastore
  next if datastore.id == 5 
  dialog_hash[datastore[:id]] = "#{datastore.name} on #{datastore.ext_management_system.name}"
end

建议

从你的问题中还不清楚你所说的if不起作用,但unless起作用。
从问题中的第一个代码片段开始,代码的最后一行,即,

dialog_hash[datastore[:id]] = "#{datastore.name} on #{datastore.ext_management_system.name}"

仅当上述两个条件都为false时才运行。
通过使用调试器或循环中的一些puts语句调试datastore,可以检查数据出现在何处,或者初始条件是否错误。
一切顺利。

u3r8eeie

u3r8eeie2#

不同的是

  • conditiontrue时,next if condition调用next,但是
  • conditionfalse时,next unless condition调用next

当使用datastore.id == 5这样的条件调用next时,问题不在于ifunless的使用,因为它们的工作方式相反。
相反,您需要调试为什么期望datastore.id == 5true以及为什么不为true。显然,当datastore.id返回整数5时,条件datastore.id == 5只能为true。如果它返回false,则datastore.id可能返回具有数字"5"的字符串。
我建议在代码中添加调试输出以进行更深入的研究,如下所示:

p datastore.id
p datastore.id.class
dldeef67

dldeef673#

除了答案之外,最流行的Ruby风格指南还建议使用肯定条件而不是否定条件

# bad
do_something if !some_condition

# good
do_something unless some_condition

根据具体情况,您可以选择ifunless

相关问题