1

要编写泛型方法,我只在 sorbet.run 上找到了这个示例sorbet.org/docs目前没有提及type_parameter。所以我有几个关于T.type_parameter.

  1. 限制父类型

如何指定只允许某种类型的子类型?(对于泛型类也一样,使用type_member) 例如,只允许“Enumerable”类型,所以我可以在该对象上调用“Enumerable”中的所有内容。

  1. 工厂方法

我有一个实例化给定类的对象的方法。(例如,因为它正在使用应保密的参数)。我怎样才能为此写签名?

→ 在 sorbet.run 上查看

#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
4

1 回答 1

0

猜猜我找到了“1.限制父类型”的答案。

尽管如此,我仍然缺少“2.工厂方法”的解决方案。
特别是如何通过给定类的泛型类型指定返回值。


答:1.限制父类型

它就在五天前的提交日志中。

为泛型添加类型边界 (#1392)

貌似lower也可以省略。

→ 在 sorbet.run 上查看

# 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

https://github.com/sorbet/sorbet/blob/417c1087dc3a5f76665fc49459b85c297e1ffac4/test/testdata/infer/generics/bounds_super.rb

于 2019-08-12T18:27:35.403 回答