为什么不推断T :: Boolean为true和false?

时间:2019-09-06 22:44:51

标签: sorbet

冰糕推断true的类型为TrueClass,而false的类型为FalseClass。如果可以推断T::Boolean,通常会很好。为什么不将特殊情况truefalse的类型改为T::Boolean

可以通过类型注释解决该问题,例如,使用T.let(true, T::Boolean)初始化变量,但是不必提供这些额外的信息将是很好的选择。

# typed: true

T.reveal_type(true) # Revealed type: `TrueClass`
T.reveal_type(false) # Revealed type: `FalseClass`

extend T::Sig

sig {params(x: T::Boolean).void}
def test(x)
  var = true
  10.times do
    var = false # Changing the type of a variable in a loop is not permitted
  end
end

在循环中将false分配给var会引起错误,因为var的类型从TrueClass变为{{1} }。

1 个答案:

答案 0 :(得分:0)

通过truefalse具有不同类型,Sorbet的流敏感键入变得更加精确。在以下示例中,将值为true的变量用作if语句的条件:

# typed: true

val = true
if val
  puts "true!"
else
  puts "false?"
end

冰糕产生的错误是:

editor.rb:7: This code is unreachable https://srb.help/7006
     7 |  puts "false?"
               ^^^^^^^^
Errors: 1

在后台,冰糕知道要检查的值的类型为TrueClass,而值true是该类型的唯一值。结果,它知道val不能为false,并且else分支将永远不会执行。

现在考虑以下情况,我们改为为T::Booleantrue推断类型falseT::BooleanT.any(TrueClass, FalseClass)的同义词,因此在该示例中,现在意味着val可以是truefalse。结果,仅凭类型就无法判断将不会执行else分支。

sorbet.org上的flow-sensitive typing documentation了解有关此主题的更多信息。