我有看起来像这样的代码(游乐场链接):
# typed: strict
class A
extend T::Sig
sig { returns(T::Array[Integer]) }
def compute_expensive
[1, 2, 3]
end
sig { returns(T::Array[Integer]) }
def expensive
@expensive ||= T.let(compute_expensive, T::Array[Integer])
end
end
这无法进行类型检查,说:
editor.rb:12: The instance variable @expensive must be declared inside initialize or declared nilable https://srb.help/5005
12 | @expensive ||= T.let(compute_expensive, Integer)
^^^^^^^^^^
我已经尝试了一些方法来解决这个问题……</p>
- 当我将类型声明为
T.nilable(Integer)
时,Sorbet 说返回类型与 sig 不匹配。公平的。 - 当我将类型声明
initialize
为时@expensive = nil
,Sorbet 说不使用下面的定义nil
进行类型检查。Integer
也很公平。 - 如果我在 中声明
@expensive = []
,initialize
我的分配将||=
变得无法访问。 - 我当然可以说
@expensive = compute_expensive if @expensive.empty?
然后返回@expensive
,但我更感兴趣的是 Sorbet 的类型系统如何适应这种||=
模式。
对我来说,这感觉像是 Ruby 中非常常见的模式!我怎样才能让 Sorbet 为我进行类型检查?