这是示例代码:
# typed: true
class KeyGetter
sig {params(env_var_name: String).returns(KeyGetter)}
def self.from_env_var(env_var_name)
return Null.new if env_var_name.nil?
return new(env_var_name)
end
def initialize(env_var_name)
@env_var_name = env_var_name
end
def to_key
"key from #{@env_var_name}"
end
def to_s
"str from #{@env_var_name}"
end
class Null
def to_key; end
def to_s; end
end
end
在它上面运行srb tc
失败
key_getter.rb:7: Returning value that does not conform to method result type https://srb.help/7005
7 | return Null.new if env_var_name.nil?
^^^^^^^^^^^^^^^
Expected KeyGetter
key_getter.rb:6: Method from_env_var has return type KeyGetter
6 | def self.from_env_var(env_var_name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Got KeyGetter::Null originating from:
key_getter.rb:7:
7 | return Null.new if env_var_name.nil?
^^^^^^^^
我看到了几种解决方法:
.returns(T.any(KeyGetter, KeyGetter::Null))
在 sig 中使用类似的东西。- 使
KeyGetter::Null
继承自KeyGetter
. 提取一个“接口”并期待它。
class KeyGetter module Interface def to_key; end def to_s; end end class Null include KeyGetter::Interface end include Interface sig {params(env_var_name: String).returns(KeyGetter::Interface)} def self.from_env_var(env_var_name) return Null.new if env_var_name.nil? return new(env_var_name) end
但是我想知道(并且在文档中没有找到)是:我可以描述鸭子类型吗?就像我们可以在 YARD 中做的那样,例如:
# @returns [(#to_s, #to_key)]
或者它是一个天生有缺陷的想法(因为理想情况下我们也需要注释鸭子类型的方法。并且在这样做时不要迷失在语法中)。
所以是的,我们可以在这里对鸭子类型进行内联注释吗?如果不是,我们应该怎么做?