簡體   English   中英

通過方法/構造函數參數與隱式使用隱含

[英]Implicits via method/constructor arguments vs using implicitly

此代碼編譯並完成預期的操作

class MyList[T](list: T)(implicit o: Ordering[T])

但是,這不是:

class MyList2[T](list: T) {
  val o = implicitly[Ordering[T]]
}

我不明白為什么。 在構造類的第一個示例中,編譯器將發現Ordering隱式,因為它將知道具體類型T 但在第二種情況下,它也應該找到隱含的,因為T已經是一個具體的類型。

在構造類的第一個示例中,編譯器將發現Ordering隱式,因為它將知道具體類型T.

在第一個示例中,需要在范圍內具有隱式Ordering[T] ,以便編譯器找到它。 編譯器本身不會“彌補”暗示。 由於您直接要求通過第二個參數列表提供一個,如果存在這樣的隱式,它將被傳遞給類構造函數。

但在第二種情況下,它也應該找到隱含的,因為T已經是一個具體的類型。

在編譯時T是具體類型這一事實無助於編譯器找到它的隱含。 當我們說T是具體類型時,你必須記住,在調用站點, T只是一個泛型類型參數,僅此而已。 如果您不幫助編譯器,則無法保證具有隱式范圍。 您需要讓方法提供一個隱式,這可以通過Context Bound完成

class MyList2[T: Ordering](list: T)

這需要在編譯時存在類型T的排序。 從語義上講,這相當於您的第二個參數列表。

您必須始終告訴編譯器應為您的類型提供隱式。 也就是說,你必須總是implicit o: Ordering[T] implicitly是,它允許您在未命名的情況下訪問隱式。 請注意,您可以對隱式參數使用語法糖(稱為“上下文綁定”),在這種情況下implicitly變為必需:

class MyList2[T : Ordering](list: T) {
  val o = implicitly[Ordering[T]]
}

類型[T : Ordering]是“范圍內存在隱式Ordering[T]某些類型T ”的簡寫。 它和寫作一樣:

class MyList2[T](list: T)(implicit o: Ordering[T]) {

}

但在這種情況下implicitly不需要,因為您可以通過其標識符o訪問隱式參數。

但在第二種情況下,它也應該找到隱含的,因為T已經是一個具體的類型。

Scala(和Java)泛型不像C ++模板那樣工作。 編譯器不會在其他地方看到MyList2[Int] ,生成

class MyList2_Int(list: Int) {
  val o = implicitly[Ordering[Int]]
}

和typecheck 那個定義。 它是MyList2本身,它沒有具體的T

要使第二個工作,您需要使用上下文綁定指定類型TOrdering

class MyList2[T : Ordering](list: T) {
  val o = implicitly[Ordering[T]]
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM