方法可以有上下文參數,也稱為隱含參數,或更簡潔地稱為隱含。從關鍵字 using
(或 Scala 2 中的 implicit
)開始的參數清單標記上下文參數。除非呼叫網站明確提供這些參數的引數,否則 Scala 會尋找正確類型的隱含可用 given
(或 Scala 2 中的 implicit
)值。如果可以找到適當的值,它會自動傳遞它們。
最好先使用一個小範例來說明。我們定義一個介面 Comparator[A]
,它可以比較類型 A
的元素,並提供兩個實作,分別適用於 Int
和 String
。然後我們定義一個方法 max[A](x: A, y: A)
,它會傳回兩個引數中較大的那個。由於 x
和 y
是泛型類型,一般來說我們不知道如何比較它們,但我們可以要求一個適當的比較器。由於通常任何給定類型 A
都有一個正規比較器,我們可以將它們宣告為given,或隱含可用。
trait Comparator[A] {
def compare(x: A, y: A): Int
}
object Comparator {
implicit object IntComparator extends Comparator[Int] {
def compare(x: Int, y: Int): Int = Integer.compare(x, y)
}
implicit object StringComparator extends Comparator[String] {
def compare(x: String, y: String): Int = x.compareTo(y)
}
}
def max[A](x: A, y: A)(implicit comparator: Comparator[A]): A =
if (comparator.compare(x, y) >= 0) x
else y
println(max(10, 6)) // 10
println(max("hello", "world")) // world
// does not compile:
println(max(false, true))
// ^
// error: could not find implicit value for parameter comparator: Comparator[Boolean]
comparator
參數會自動填入 Comparator.IntComparator
,適用於 max(10, 6)
,以及 Comparator.StringComparator
,適用於 max("hello", "world")
。由於找不到隱含的 Comparator[Boolean]
,因此呼叫 max(false, true)
會編譯失敗。
trait Comparator[A]:
def compare(x: A, y: A): Int
object Comparator:
given Comparator[Int] with
def compare(x: Int, y: Int): Int = Integer.compare(x, y)
given Comparator[String] with
def compare(x: String, y: String): Int = x.compareTo(y)
end Comparator
def max[A](x: A, y: A)(using comparator: Comparator[A]): A =
if comparator.compare(x, y) >= 0 then x
else y
println(max(10, 6)) // 10
println(max("hello", "world")) // world
// does not compile:
println(max(false, true))
-- Error: ----------------------------------------------------------------------
1 |println(max(false, true))
| ^
|no given instance of type Comparator[Boolean] was found for parameter comparator of method max
對於 max(10, 6)
,comparator
參數會自動填入 given Comparator[Int]
,而對於 max("hello", "world")
,則會填入 given Comparator[String]
。由於找不到 given Comparator[Boolean]
,因此 max(false, true)
呼叫無法編譯。
Scala 會在兩個地方尋找可用的 given 值
- Scala 會先尋找 given 定義,並在
max
的呼叫位置直接存取使用參數(無前綴)。 - 然後尋找在與隱含候選類型相關聯的伴隨物件中標記為
given
/implicit
的成員(例如:object Comparator
對於候選類型Comparator[Int]
)。
可以在 常見問題 中找到 Scala 尋找隱含值位置的更詳細指南。