在Scala中键入相等性

Ser*_*iss 8 scala

这是一小段代码:

class Foo[A] {
  def foo[B](param: SomeClass[B]) {
  //
  }
}
Run Code Online (Sandbox Code Playgroud)

现在,在内部foo,我该如何:
1)验证B是否与A的类型相同?
2)验证B是否是A的子类型?

xie*_*fei 7

您需要隐式类型证据,<:<用于子类型检查和=:=相同类型检查.请参阅此问题的答案.

  • @Sergey不,只需在方法中附加一个额外的(隐式ev:B <:<A)参数列表.或者(隐含的ev:B =:= A)表示平等. (2认同)

Pth*_*ame 7

作为旁注,广义类型约束实际上不是必需的:

class Foo[A] {
  def foo_subParam[B <: A](param: SomeClass[B]) {...}
  def foo_supParam[B >: A](param: SomeClass[B]) {...}
  def foo_eqParam[B >: A <: A](param: SomeClass[B]) {...}
  def foo_subMyType[Dummy >: MyType <: A] {...}
  def foo_supMyType[Dummy >: A <: MyType] {...}
  def foo_eqMyType[Dummy1 >: MyType <: A, Dummy2 >: A <: MyType] {...}
}
Run Code Online (Sandbox Code Playgroud)

实际上,我更喜欢这种方式,因为它既略微改进了类型推断,又保证不使用无关的运行时数据.

  • 嗨@ Ptharien's Flame,我刚看到你的回答,看起来很有趣.你能解释一下吗?MyType来自哪里以及如何使用foo_eqMyType方法?提前感谢您的回答. (2认同)

mis*_*tor 6

1)验证B是否与A的类型相同?

class Foo[A] {
  def foo(param: SomeClass[A]) = ???
}

// or

class Foo[A] {
  def foo[B](param: SomeClass[B])(implicit ev: A =:= B) = ???
}
Run Code Online (Sandbox Code Playgroud)

2)验证B是否是A的子类型?

class Foo[A] {
  def foo[B <: A](param: SomeClass[B]) = ???
}

// or

class Foo[A] {
  def foo[B](param: SomeClass[B])(implicit ev: B <:< A) = ???
}
Run Code Online (Sandbox Code Playgroud)

在您的情况下,您不需要 广义类型约束(即=:=,<:<).当您需要在其他地方定义的类型参数上添加约束时,它们是必需的,而不是在方法上.

例如,确保AString:

class Foo[A] {
  def regularMethod = ???
  def stringSpecificMethod(implicit ev: A =:= String) = ???
}
Run Code Online (Sandbox Code Playgroud)

如果没有通用类型约束,则无法强制执行类型约束.