你会如何用冰糕做玫瑰记忆?
How would you do rose memoization with Sorbet?
试图注释这段代码,玫瑰记忆 (@||=
) 给我一个错误 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
据我所知,我应该用 T.let
声明变量的类型,但还没有弄清楚具体如何。
从 0.4.4679 开始,Sorbet 现在有 built-in 支持。在此之前,还有其他解决方法(见下文)。
- 初始化实例变量为
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
这是首选解决方案。
- 在方法外初始化实例变量,并给它一个类型注解:
# 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
从概念上讲,此 class 有两个执行阶段:初始化时和使用时。如果一个实例变量在 Sorbet 中初始化时没有给出类型注解,那么它将到处都是 T.untyped
(或者在 # typed: strict
中出错)。因为如果不在初始化中注释,Sorbet 无法知道哪个代码路径可能首先写入该位置。 (即使在只有一个位置的情况下,Sorbet 也不会进行那种全局分析。)
Sorbet 只在实例变量为 nilable 时放宽这一点,在这种情况下它可以在任何地方初始化,因为 Sorbet 不需要保证它被初始化为 non-nil。
- 使用不同的严格级别。
如果您觉得添加类型注释太麻烦,您可以使用 # typed: true
选择不要求类型注释,其中实例变量需要类型注释的错误被消除。
试图注释这段代码,玫瑰记忆 (@||=
) 给我一个错误 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
据我所知,我应该用 T.let
声明变量的类型,但还没有弄清楚具体如何。
从 0.4.4679 开始,Sorbet 现在有 built-in 支持。在此之前,还有其他解决方法(见下文)。
- 初始化实例变量为
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
这是首选解决方案。
- 在方法外初始化实例变量,并给它一个类型注解:
# 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
从概念上讲,此 class 有两个执行阶段:初始化时和使用时。如果一个实例变量在 Sorbet 中初始化时没有给出类型注解,那么它将到处都是 T.untyped
(或者在 # typed: strict
中出错)。因为如果不在初始化中注释,Sorbet 无法知道哪个代码路径可能首先写入该位置。 (即使在只有一个位置的情况下,Sorbet 也不会进行那种全局分析。)
Sorbet 只在实例变量为 nilable 时放宽这一点,在这种情况下它可以在任何地方初始化,因为 Sorbet 不需要保证它被初始化为 non-nil。
- 使用不同的严格级别。
如果您觉得添加类型注释太麻烦,您可以使用 # typed: true
选择不要求类型注释,其中实例变量需要类型注释的错误被消除。