Scala Ordering [T]和Serializable

时间:2015-04-30 12:36:04

标签: scala

鉴于此类案例类:

case class KVPair[
    K <: Ordering[K] with Serializable, 
    VV <: Serializable
](key: K, value: VV)

如何使用KVPair构建Longs,如下所示:

def createKVPair(): KVPair[Long, Long] = {
    KVPair(1L, 1L)
}

编译器一直在抱怨:

  

Long不符合方法apply的类型参数边界。

2 个答案:

答案 0 :(得分:3)

这里有两件事。首先,Long不会延伸Ordering[Long]。注释中的The page you linked from the docsLong包中名为scala.math.Ordering的隐式对象的文档。

但是,这个对象在这里非常重要。由于该对象位于隐式范围内,因此您可以使用上下文绑定来确保有Ordered[Long]的实例可用,这将允许代码对Longs进行排序。

case class Key[K : Ordering](key: K)

这将允许您执行Key(1L)

您的另一个问题是Long也不是Serializable,因此第二个通用参数也存在问题。 Long可以隐式查看为java.io.Serializable,您可能会对此感兴趣。您可以使用视图绑定来确保KV具有此约束:

type JS = java.io.Serializable
case class KVPair[K <% JS : Ordering, V <% JS](key: K, value: V)

上下文绑定和视图绑定语法使其等同于:

 case class KVPair[K, V](key: K, value: V)(
    implicit kev1: Ordering[K], 
             kev2: K => JS, 
             vev1: V => JS
 )

您可以在this answer上阅读有关上下文边界和视图边界的更多信息。

答案 1 :(得分:2)

scala.Long不是Ordering。绑定类型K <: Ordering[K]表示K必须以Ordering类型为界。并且scala.Long肯定不会扩展类型类Ordering。存在Ordering[Long]的实例,但scala.Long不会扩展它。

你想要的是Ordering[K]的证据,即上下文绑定。像这样:

case class KVPair[K : Ordering , VV](key: K, value: VV)

def createKVPair(): KVPair[Long, Long] = {
    KVPair(1L, 1L)
}

以上案例类是以下语法糖:

case class KVPair[K, VV](key: K, value: VV)(implicit ev: Ordering[K])

您可能已经注意到我还删除了Serializable界限。这是因为Long不是Serializable,因此无法使用该约束。

scala> implicitly[Long <:< Serializable]
<console>:26: error: Cannot prove that Long <:< Serializable.
              implicitly[Long <:< Serializable]