像F#一样的Scala泛型类型函数限制

时间:2017-06-15 13:56:13

标签: scala

有没有办法对泛型A进行限制,这样A必须有一个给定的方法?我知道在F#中可以这样做

type GenericState<'A when 'A:comparison>

意味着A必须是具有比较功能的类型。我想知道这是否可以在Scala中轻松完成

1 个答案:

答案 0 :(得分:2)

有一对。

下限

trait Behaviour {
  def someMethod...
}

// GenericState has to inherit from Behaviour and therefore
// implement someMethod
type GenericState <: Behaviour

上下文界限

trait Behaviour[T] {
  def someMethod ..
}

// T has to inherit from GenericState and have
// an implicit Behaviour[T] in scope.
class Test[T <: GenericState : Behaviour] {
  // this is a good way to decouple things
  // You can get a reference to the materialized bound with implicitly
  // and call your method on that.
  implicitly[Behaviour[T]].someMethod(..)
}

结构类型

不建议使用最直接的等价,因为它在JVM上没有高性能的实现。

// This creates a type definition in place and it's effectively similar
// to the first variant, except the type is structurally defined.
type GenericState <: {
  def someMethod ..
}

我个人更喜欢这里绑定的上下文。

trait Comparable[T] {
  def compare(x: T, y: T): Int
}
object Comparable {
  implicit val intComparable = new Comparable[Int] {
    def compare(x: Int, y: Int): Int = ..
  }

 // and so on
}

然后,只要您需要类似的东西,就可以使用上下文边界。

class Something[T : Comparable](obj: T)

这只是语法糖:

class Something[T](obj: T)(implicit ev: Comparable[T])