2011-02-02 65 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> 

順便說一句,重新 「這裏似乎很容易」,事實並非如此。像這樣的暗示享受分歧,他們非常堅定。