作为一个初学者,你有没有挑选一个坚硬的坚果来破解斯卡拉!-)
好的,简短的旅行,不要期望现在就完全理解它。首先,请注意,问题发生在方法中
++
. 寻找它的定义,我们发现它的特点
MapLike
,接收
Iterator
或A
Traversable
. 自从
y
是一个
SortedMap
,然后是
可移动的
正在使用的版本。
在其扩展类型签名中注意到
CanBuildFrom
被通过。它是隐式传递的,所以您通常不需要担心它。然而,要理解发生了什么,这次你要做。
您可以通过单击canbuildFrom的定义中它出现的位置来定位canbuildFrom。
++
或者通过过滤。正如Randall在评论中提到的,scalaDoc页面的左上角有一个未标记的空白字段。你只需点击那里输入,它就会返回你输入的匹配项。
所以,看看这个特点
坎勃罗德
在scaladoc上选择它。它有大量的子类,每个子类负责构建特定类型的集合。搜索并单击子类
SortedMapCanBuildFrom
. 这是您需要生成的对象的类
排序映射
从A
可穿越的
.关于实例构造函数(类的构造函数)的注意事项是,它接收到一个隐式
Ordering
参数。现在我们越来越接近了。
这次,使用筛选器搜索
排序
. 它的伴生对象(单击小的“o”名称)承载将生成的隐式
排序
作为伴生对象,将检查该类的隐式生成实例或转换。它是在特性内部定义的。
LowPriorityOrderingImplicits
,哪个对象
排序
扩展,查看它,您将看到方法
ordered[A <: Ordered[A]]
将产生
排序
必修的。。。如果没有问题的话,也会生产出来。
我们可以假定从
X
到
Ordered[X]
这就足够了,就像我之前更仔细地研究这个问题一样。然而,这是对
物体
和
ordered
期望收到
类型
它是
有序[ X ]
. 同时可以转换类型的对象
X
到类型的对象
有序[ X ]
,
X
本身不是
有序[ X ]
,因此它不能作为参数传递给
命令
.
另一方面,您可以创建一个隐式
val
Ordering[X]
,而不是
def
有序[ X ]
你会解决这个问题的。明确地:
object ViewBoundExample {
class X
def combine[Y](a: SortedMap[X, Y], b: SortedMap[X, Y]): SortedMap[X, Y] = {
a ++ b
}
implicit val orderingX = new Ordering[X] { def compare(x: X, y: X) = 0 }
}
我认为大多数人对
Ordered
/
排序
一定很困惑:为什么要为同样的事情上课?前者延伸
java.lang.Comparable
,而后者延伸
java.util.Comparator
. 唉,类型签名
compare
主要区别在于:
def compare(that: A): Int // Ordered
def compare(x: T, y: T): Int // Ordering
AN的使用
Ordered[A]
两者都需要
A
延伸
有序[ a]
需要一个人能够
修改
一
或传递一个方法,该方法可以
一
变成一个
有序[ a]
. scala完全可以轻松完成后者,但是
有
在比较之前转换每个实例。
另一方面,使用
Ordering[A]
需要创建单个对象,如上面所示。使用它时,只传递两个类型的对象
一
到
比较
--在此过程中未创建任何对象。
因此,需要获得一些性能提升,但scala更倾向于
订购
结束
命令
. 再次查看伴生对象
排序
. 您将注意到其中定义的许多scala类都有几个隐式。你可能还记得我之前提到的一个隐式for类
T
将在
T
正是这样。
这个
能够
做某事
命令
也。然而,这就是症结所在,这意味着每种方法都支持
排序
和
命令
会失败的!这是因为scala会寻找一个隐式的方法使其工作,并且会找到两个:一个用于
订购
一个
命令
. 由于无法确定您想要哪一个,scala放弃了一条错误消息。因此,必须做出选择,并且
排序
有更多的事情要做。
噢,我忘了解释为什么签名没有被定义为
ordered[A <% Ordered[A]]
而不是
已订购[A<:已订购[A]
. 我怀疑这样做会导致我之前提到的双重隐式失败,但是我会问真正做了这些事情并且有双重隐式问题的人,这个特定的方法是否有问题。