簡體   English   中英

我可以讓Scala更喜歡隱式轉換為Java 8 Lambda嗎?

[英]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.

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