尝试注释此代码时,rose memoization ( @||=) 给了我一个错误Use of undeclared variable @git_sha。
# typed: strict
# frozen_string_literal: true
module Util
extend T::Sig
sig { returns(String) }
def self.git_sha
@git_sha ||= ENV.fetch(
'GIT_REV',
`git rev-parse --verify HEAD 2>&1`
).chomp
end
end
Run Code Online (Sandbox Code Playgroud)
据我发现,我应该声明变量的类型,T.let但还没有弄清楚具体如何。
从 0.4.4679 开始,Sorbet 现在已经内置了对此的支持。在此之前,还有其他解决方法(见下文)。
T.nilable,并用该方法替换其他地方对实例变量的所有直接访问:# typed: strict
# frozen_string_literal: true
module Util
extend T::Sig
sig { returns(String) }
def self.git_sha
@git_sha = T.let(@git_sha, T.nilable(String))
@git_sha ||= ENV.fetch(
'GIT_REV',
`git rev-parse --verify HEAD 2>&1`
).chomp
end
end
Run Code Online (Sandbox Code Playgroud)
这是首选的解决方案。
# typed: strict
# frozen_string_literal: true
module Util
extend T::Sig
@git_sha = T.let(nil, T.nilable(String))
sig { returns(String) }
def self.git_sha
@git_sha ||= ENV.fetch(
'GIT_REV',
`git rev-parse --verify HEAD 2>&1`
).chomp
end
end
Run Code Online (Sandbox Code Playgroud)
从概念上讲,这个类有两个执行阶段:初始化时和使用时。如果一个实例变量在 Sorbet 中初始化时没有被赋予类型注解,它将T.untyped无处不在(或在 中出现错误# typed: strict)。因为如果它没有在初始化中注释,Sorbet 就无法知道哪个代码路径可能首先写入这个位置。(即使在这种情况下只有一个位置,Sorbet 也不会进行那种全局分析。)
Sorbet 仅在实例变量为 nilable 时才放宽这一点,在这种情况下,它可以在任何地方初始化,因为 Sorbet 不需要保证它被初始化为非 nil。
如果您发现添加类型注释太麻烦,您可以通过 using 选择不要求类型注释# typed: true,其中需要对实例变量进行类型注释的错误被消除。
| 归档时间: |
|
| 查看次数: |
605 次 |
| 最近记录: |