简体   繁体   English

Scala排序[T]和可序列化

[英]Scala Ordering[T] and Serializable

Given a case class like this: 给定这样的案例类:

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

How would I go about constructing a KVPair with Longs , something like this: 我将如何与Longs一起构建KVPair ,如下所示:

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

The compiler keeps complaining with: 编译器不断抱怨:

Long does not conform to method apply's type parameter bounds. Long不符合方法应用的类型参数范围。

There are 2 things going on here. 这里有两件事。 First of all Long does not extend Ordering[Long] . 首先, Long不扩展Ordering[Long] The page you linked from the docs in the comments is the documentation of an implicit object called Long in the scala.math.Ordering package. 您从注释中的文档链接到的页面scala.math.Ordering包中一个名为Long的隐式对象的文档。

However, that object is very relevant here. 但是,该对象在这里非常重要。 Since that object is in implicit scope, you can use a context bound to ensure that there is an instance of Ordered[Long] is available, which will allow code to order your Longs . 由于该对象处于隐式范围内,因此可以使用上下文绑定来确保有一个Ordered[Long]实例可用,这将允许代码对Longs进行排序。

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

This will allow you to do Key(1L) . 这将允许您执行Key(1L)

Your other problem is that Long is also not Serializable , so the second generic parameter is also problematic. 您的另一个问题是Long也不可Serializable ,因此第二个通用参数也是有问题的。 Long is implicitly viewable as a java.io.Serializable , which might be of interest to you here. Long作为java.io.Serializable隐式可见,在这里您可能会感兴趣。 You can use a view bound to ensure that K and V have this constraint: 您可以使用视图绑定来确保KV具有此约束:

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

The context-bound and view-bound syntax make this equivalent to: 上下文绑定和视图绑定的语法使其等效于:

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

You can read more about context bounds and view bounds on this answer . 您可以在此答案中了解有关上下文范围和视图范围的更多信息。

scala.Long is not an Ordering . scala.Long不是Ordering The type bound K <: Ordering[K] means K should must be bounded by the Ordering type. 类型绑定K <: Ordering[K]表示K必须由Ordering类型限制。 And scala.Long most certainly does not extend the type class Ordering . scala.Long最肯定不会扩展Type类Ordering There exists an instance of an Ordering[Long] , but scala.Long does not extend it. 存在一个Ordering[Long]的实例,但是scala.Long不扩展它。

What you want is evidence of an Ordering[K] , ie., a context bound . 您想要的是Ordering[K]证据,即上下文绑定 Something like this: 像这样:

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

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

The above case class is syntactic sugar for: 上面的案例类是用于以下方面的语法糖:

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

You may have noticed that I've also removed the Serializable bound. 您可能已经注意到,我还删除了Serializable绑定。 This is because Long is not Serializable , so it cannot possibly work with that constraint. 这是因为Long不可Serializable ,因此它可能无法使用该约束。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM