2010-04-08 87 views
35

任何人都可以在斯卡拉提供<:<運算符的一些細節。 我認爲:<:<斯卡拉運算符

if(apple <:< fruit) //checks if apple is a subclass of fruit. 

還有其他解釋嗎?我在scala源文件中看到很多定義。

+1

您是指'Manifest'上的方法還是'Predef'中定義的類? – 2010-04-08 21:49:16

+62

這就是所謂的「麥當娜穿着鈕釦襯衫」的經營者。 – Syntactic 2010-05-07 14:34:57

+3

哈,我叫它「憤怒的驢子」運營商 – 2010-05-07 14:36:43

回答

23

<:<不是一個操作符 - 它是一個標識符,因此是以下之一:

  • 一個(類的名稱,特徵,類型別名等)
  • 方法的名稱/ val或var

在這種情況下,<:<在庫中出現兩次,一次Predef作爲一類,一次作爲上Manifest的方法。

對於Manifest上的方法,它檢查這個清單所代表的類型是否是清單參數所表示的子類型。

對於Predef中的這種類型,這是相對較新的,我也對此略有困惑,因爲它似乎是同樣聲明三重奏的一部分!

class <%<[-From, +To] extends (From) ⇒ To 
class <:<[-From, +To] extends (From) ⇒ To 
class =:=[From, To] extends (From) ⇒ To 
+1

'Predef'中的那些是廣義類型約束。這個郵件列表的主題覆蓋了一些:http://old.nabble.com/-scala--Using-generalised-type-constraints-in-2.8-collections-td26249516.html – 2010-04-09 11:08:48

+1

但是從聲明他們都看起來相同,那麼他們怎麼能意味着不同的事情呢? – 2010-04-09 11:12:05

+0

感謝您的鏈接:不幸的是,我仍然在努力去理解如何用隱含的ev:A <: B',其中'<:<[A,B] extends A => B'實際上*做任何事情 – 2010-04-09 11:39:50

7

實際上,它檢查類是否代表Manifest蘋果是由清單水果代表的類的子類。

例如:

manifest[java.util.List[String]] <:< manifest[java.util.ArrayList[String]] == false 
manifest[java.util.ArrayList[String]] <:< manifest[java.util.List[String]] == true 
13

我問了一圈,這是我得到的解釋是:

<:<通常用作證據的參數。例如在TraversableOnce中,toMap被聲明爲def toMap[T, U](implicit ev: A <:< (T, U)): immutable.Map[T, U]。這表示約束條件,toMap方法只有在遍歷包含2元組時才起作用。另一個例子是flatten<:<用於表達約束條件,即只能展平可遍歷的遍歷。

3

從scala.Predef複製。階:

// Type Constraints -------------------------------------------------------------- 

    // used, for example, in the encoding of generalized constraints 
    // we need a new type constructor `<:<` and evidence `conforms`, as 
    // reusing `Function2` and `identity` leads to ambiguities (any2stringadd is inferred) 
    // to constrain any abstract type T that's in scope in a method's argument list (not just the method's own type parameters) 
    // simply add an implicit argument of type `T <:< U`, where U is the required upper bound (for lower-bounds, use: `U <: T`) 
    // in part contributed by Jason Zaugg 
    sealed abstract class <:<[-From, +To] extends (From => To) 
    implicit def conforms[A]: A <:< A = new (A <:< A) {def apply(x: A) = x} 
30

<:<類型在Predef.scala與相關類型=:=<%<沿着定義如下:

// used, for example, in the encoding of generalized constraints 
// we need a new type constructor `<:<` and evidence `conforms`, as 
// reusing `Function2` and `identity` leads to ambiguities (any2stringadd is inferred) 
// to constrain any abstract type T that's in scope in a method's argument list (not just the method's own type parameters) 
// simply add an implicit argument of type `T <:< U`, where U is the required upper bound (for lower-bounds, use: `U <: T`) 
// in part contributed by Jason Zaugg 
sealed abstract class <:<[-From, +To] extends (From => To) 
implicit def conforms[A]: A <:< A = new (A <:< A) {def apply(x: A) = x} // not in the <:< companion object because it is also intended to subsume identity (which is no longer implicit) 

這使用了Scala的功能,通用型op[T1, T2]可以寫入T1 op T2。如aioobe所述,可以使用此方法爲僅適用於某些泛型類型實例的方法提供證據參數(給出的示例爲僅可用於Tuple2TraversabletoMap方法)。正如在註釋中指出的那樣,這將一般的泛型類型約束泛化,以允許它引用任何範圍內的抽象類型/類型參數。使用這種方法(implicit ev : T1 <:< T2)比單純使用證據參數(如implicit ev: T1 => T2)的優勢在於後者可能會導致意外的範圍內隱式值用於轉換。

我確定我在Scala的郵件列表上看到過這方面的一些討論,但目前找不到它。

+0

<: Eastsun 2010-05-07 15:25:25

+2

@ Eastsun'<:<'承認子類,而'=:='不。 – 2010-05-07 15:29:17

+3

隱式參數'ev:T1 <: 2010-05-07 15:30:00

2

爲了更好地理解implementation

sealed abstract class <:<[-From, +To] extends (From => To) 
implicit def conforms[A]: A <:< A = new (A <:< A) {def apply(x: A) = x} 

我試圖設計一個更簡單的實現。以下內容無效。

sealed class <:<[-From <: To, +To] 
implicit def conforms[A <: B, B]: A <:< B = new (A <:< B) 

至少因爲它不會輸入檢查所有valid use個案。

case class L[+A](elem: A) 
{ 
    def contains[B](x: B)(implicit ev: A <:< B) = elem == x 
} 

error: type arguments [A,B] do not conform to class <:<'s 
     type parameter bounds [-From <: To,+To] 
def contains[B](x: B)(implicit ev: A <:< B) = elem == x 
            ^