【问题标题】:Why not infer T::Boolean for true and false?为什么不推断 T::Boolean 的真假?
【发布时间】:2022-03-29 03:07:00
【问题描述】:

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 更改为FalseClass

【问题讨论】:

    标签: sorbet


    【解决方案1】:

    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
    

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

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

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

    【讨论】:

    • 你为什么要回答自己的问题?
    • @PavelEvstigneev:这没有错。看到这个问题,我意识到我不知道答案。这是一个有用的问答。
    【解决方案2】:

    今天也问了同样的问题。 最终按照您的建议使用类型注释修复它并使用 T.let(true, T::Boolean) 进行初始化

    # typed: true
    extend T::Sig
    
    sig {params(x: T::Boolean).void}
    def test(x)
      var = T.let(true, T::Boolean)
      10.times do
        var = T.let(false, T::Boolean)
      end
    end
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-01
      • 2016-08-16
      • 2014-05-06
      • 2017-02-20
      • 2014-09-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多