要编写通用方法,我只发现了this example on sorbet.run。 sorbet.org/docs当前未提及type_parameter。因此,我对T.type_parameter的高级用法有一些疑问。
如何指定仅允许某种类型的子类型? (与通用类相同,使用type_member
)
例如。只允许使用“ Enumerable”类型,因此我可以在该对象上调用“ Enumerable”中的所有内容。
我有一个实例化给定类的对象的方法。 (例如,因为它使用的参数应保持私有状态) 我该如何签名?
#typed: true
class Animal
def initialize(secret_of_nature); end
end
class Sidewinder < Animal
def rattle; end
end
class Nature
extend T::Sig
sig {params(animal_cls: T.class_of(Animal)).returns(Animal)}
def self.factory(animal_cls)
animal_cls.new(@secret_dna)
end
end
Nature::factory(Sidewinder).rattle
# => Method rattle does not exist on Animal
答案 0 :(得分:0)
猜猜我找到了答案。就在五天前的提交日志中。
Add type bounds to generics (#1392)
看起来像lower
的小型测试也可以省略。
# typed: true
class Animal; end
class Cat < Animal; end
class Serval < Cat; end
class A
extend T::Generic
T1 = type_member(lower: Serval, upper: Animal)
end
# should pass: Cat is within the bounds of T1
class B1 < A
extend T::Generic
T1 = type_member(fixed: Cat)
end
# should fail: String is not within the bounds
class B2 < A
extend T::Generic
T1 = type_member(fixed: String)
# ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: parent lower bound `Serval` is not a subtype of lower bound `String`
# ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: upper bound `String` is not a subtype of parent upper bound `Animal`
end
# should pass: the bounds are a refinement of the ones on A
class C1 < A
extend T::Generic
T1 = type_member(lower: Serval, upper: Cat)
end
# should fail: the bounds are wider than on A
class C2 < A
extend T::Generic
T1 = type_member(lower: Serval, upper: Object)
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: upper bound `Object` is not a subtype of parent upper bound `Animal`
end
# should fail: the implicit bounds of top and bottom are too wide for T1
class D1 < A
T1 = type_member
# ^^^^^^^^^^^ error: parent lower bound `Serval` is not a subtype of lower bound `T.noreturn`
# ^^^^^^^^^^^ error: upper bound `<any>` is not a subtype of parent upper bound `Animal`
end