1

Sorbet 推断出 的类型为trueTrueClass, 的类型falseFalseClass。如果它改为推断,通常会很好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循环中对to的赋值var会导致引发错误,因为类型var正在从TrueClassto更改FalseClass

4

1 回答 1

1

Sorbet 的流敏感打字通过不同的类型true变得更加精确。false在以下示例中,具有值的变量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

在幕后,sorbet 知道被检查的值具有 type TrueClass,并且该值true是该类型的唯一值。结果,它知道val不可能false,并且该else分支永远不会被执行。

现在考虑我们改为推断 和 的类型的T::Boolean情况。是 的同义词,因此在示例中它现在意味着可能是或。结果,无法仅从类型判断分支不会被执行。truefalseT::BooleanT.any(TrueClass, FalseClass)valtruefalseelse

sorbet.org 上的流敏感类型文档有更多关于这个主题的信息。

于 2019-09-06T23:07:22.797 回答