2011-02-02 38 views
4

虽然在this question工作,我想出了以下问题。考虑两种方法定义:集合如何使用元素类型的隐式转换?

def foo[T <: Ordered[T]](s : Seq[T]) = s.sorted 

def foo[T <% Ordered[T]](s : Seq[T]) = s.sorted 

第一个编译,第二个没有。编译器没有发现它可以使用声明的隐式转换来获得Ordering。如果我们帮助了一下,它的工作原理:

def foo[T <% Ordered[T]](s : Seq[T]) = s.sortWith(_<=_) 

在编写匿名函数,编译器应用的隐式转换找方法<=,一切都很好。

我没有其他的例子,但可以想见类似的问题与其他功能发生在需要的元素具有一定的特性,如果这些只能通过转换断言集合。

有编译器为什么被限制这样一个特别的原因?没有通用的方法来解决这些问题吗? (这里看起来很简单。)是否有解决方法,例如这相当于TKey[T]财产另一个隐式转换?

(请注意,如果T的具体值最终具有该属性,那么最后的想法可能会有问题;然后我们会得到一个模糊的情况)。

回答

4
scala> implicit def ordering[T <% Ordered[T]] = new Ordering[T]{def compare(x: T, y: T) = x compare y} 
ordering: [T](implicit evidence$1: (T) => Ordered[T])java.lang.Object with Ordering[T] 

scala> def foo[T <% Ordered[T]](s : Seq[T]) = s.sorted 
foo: [T](s: Seq[T])(implicit evidence$1: (T) => Ordered[T])Seq[T] 
+0

为2.8.1,最终有效的解决方案,谢谢。我想没有一般的方法,因为你必须有一个特殊的类型来描述每个场景的特殊元素属性(这里是`Ordering`)? – Raphael 2011-02-03 12:57:21

+0

注意,如果`T <一个正是如此定义排序甚至会被使用:有序[T]`。显然,implicits是静态解决的。 – Raphael 2011-02-03 13:27:07

3
% scala29 
Welcome to Scala version 2.9.0.r24168-b20110202012927 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_22). 
Type in expressions to have them evaluated. 
Type :help for more information. 

scala> def foo[T <% Ordered[T]](s : Seq[T]) = s.sorted 
foo: [T](s: Seq[T])(implicit evidence$1: (T) => Ordered[T])Seq[T] 

scala> 

顺便说一句,重新 “这里似乎很容易”,事实并非如此。像这样的暗示享受分歧,他们非常坚定。