![](/img/trans.png)
[英]Can I tell scala how to prefer more specific implicit, rather than give “ambiguous implicit” error?
[英]Can I make Scala prefer an implicit conversion to a Java 8 Lambda?
我正在為kafka-streams庫編寫一個Scala包裝器。 基本方法是提供從kafka-streams類(如KStream
到豐富的KStreamOps
類的隱式轉換。
例如, KStream
提供以下map
簽名:
<K1, V1> KStream<K1, V1> map(KeyValueMapper<K, V, KeyValue<K1, V1>> mapper)
其中KeyValueMapper
是帶簽名的SAM(來自Scala透視圖) (K, V) => KeyValue[K1, V1]
。
這是KStreamOps
的最小實現,提供了一個map
方法:
class KStreamOps[K, V](underlying: KStream[K, V]) {
def map[K1, V1](f: (K, V) => (K1, V1)): KStream[K1, V1] =
underlying.map { (k, v) =>
val tuple = f(k, v)
KeyValue.pair(tuple._1, tuple._2)
}
}
請注意,此處的map
需要一個返回Tuple2
的函數,並處理將其轉換為kafka-streams
特定的KeyValue
類型,以便用戶無需直接與KeyValue
交互。
我提供了隱式轉換:
implicit def ops[K, V](kstream: KStream[K, V]): KStreamOps[K, V] = new KStreamOps[K, V](kstream)
但是,當我嘗試在代碼中使用我的新map
,如下所示:
val inputStream: KStream[Int, String] = builder.stream(inputTopic)
stream.map{ (k, v) => (k, v) }
我收到以下編譯錯誤:
[error] KStreamOpsTest.scala:47: type mismatch;
[error] found : (Int, String)
[error] required: org.apache.kafka.streams.KeyValue[Int,String]
[error] stream.map((k, v) => (k, v))
[error] ^
[error] KStreamOpsTest.scala:47: Could not derive subclass of org.apache.kafka.streams.kstream.KeyValueMapper[Int,String,org.apache.kafka.streams.KeyValue[Int,String]]
[error] (with SAM `def method apply(x$1: Int, x$2: String)org.apache.kafka.streams.KeyValue[Int,String]`)
[error] based on: ((k: Int, v: String) => scala.Tuple2(k, v)).
[error] stream.map((k, v) => (k, v))
因此,編譯器正在嘗試使用需要返回KeyValue
的SAM而不是我的KStreamOps#map
來使用KStream#map
,而我的KStreamOps#map
期望函數的輸出為Tuple2
。
如果我將我的方法重命名為KStreamOps#map1
並調用stream.map1
,隱式轉換將按預期工作並編譯代碼。
為什么編譯器不能識別出隱式轉換會獲得一個采用正確簽名函數的方法? 不考慮功能返回類型嗎? SAM會不會贏?
我正在使用Scala 2.11.8測試它,並打開-Xexperimental
標志。
正如@Łukasz所暗示的那樣,創建一個明確的包裝似乎就是這樣的方式。 我可能會提供從包裝器類型到KStream
的隱式轉換:
implicit def unwrap[K, V](wrapped: WrappedKStream[K, V]): KStream[K, V] = wrapped.underlying
這樣我們就可以使用KStream
和包裝器的方法,但包裝類方法優先。
這里一個明顯的缺點是用戶在創建初始對象時需要顯式使用包裝器類型。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.