具有相同签名和参数类型的 Scala 不明确引用

Scala Ambiguous reference with same signature and argument types

Scala 如何显示不明确的引用错误,其中两个备选方案具有相同的签名?如何克服呢?

代码:

import org.apache.kafka.streams.test

val stringSerializer = new StringSerializer
val stringFactory: ConsumerRecordFactory[String, String] =
    new ConsumerRecordFactory[String, String](
      eventTopic, stringSerializer, stringSerializer)
val testKey : String = ""
val testVal : String = ""
val recordString : ConsumerRecord[Array[Byte], Array[Byte]] = 
    stringFactory.create(testKey, testVal)

ambiguous reference to overloaded definition,
[error] both method create in class ConsumerRecordFactory of type (x: String, x: String)org.apache.kafka.clients.consumer.ConsumerRecord[Array[Byte],Array[Byte]]
[error] and  method create in class ConsumerRecordFactory of type (x: String, x: String)org.apache.kafka.clients.consumer.ConsumerRecord[Array[Byte],Array[Byte]]
[error] match argument types (String,String) and expected result type org.apache.kafka.clients.consumer.ConsumerRecord[Array[Byte],Array[Byte]]
[error]     val recordString : ConsumerRecord[Array[Byte], Array[Byte]] = stringFactory.create(testKey, testVal)

如您所见,这两种方法具有相同的签名。使用其他类型的 CustomerFactory 时不会发生这种情况,即自定义案例 class 类型,我为其自定义序列化器(而不是提供的 StringSerializer)。

为了解决模棱两可的方法问题,您应该遵循以下方法。

  1. 使用 KeySerializer 和 ValueSerializer 创建 ConsumerRecordFactory 实例

  2. 传递 ConsumerRecord 中的主题,后跟键和值。

示例:

val stringSerializer = new StringSerializer
val stringFactory: ConsumerRecordFactory[String, String] =
    new ConsumerRecordFactory[String, String](
      stringSerializer, stringSerializer)
val testKey : String = ""
val testVal : String = ""
val recordString : ConsumerRecord[Array[Byte], Array[Byte]] = 
    stringFactory.create(eventTopic, testKey, testVal)

另一种选择是将键和值作为字节数组传递。

val stringFactory: ConsumerRecordFactory[String, String] =
    new ConsumerRecordFactory[String, String](
      eventTopic, stringSerializer, stringSerializer)
val testKey : String = ""
val testVal : String = ""
val recordString : ConsumerRecord[Array[Byte], Array[Byte]] = 
    stringFactory.create(testKey.getBytes, testVal.getBytes)

我找到了解决办法。

因此,在 class ConsumerFactory 中,有一个方法 create(final K key, final V value) 和另一个方法 create(final String topicName, final V value)。 由于第一个 K 可以通过 String 匹配,因此它是一个有歧义的引用。但是,由于错误中显示的不是方法签名中的原始类型,而是 effective 类型,因此消息有些混乱。 这是此 API 的特殊性,而不是 Scala 或 Scala-Java 互操作的特殊性。

我在这种情况下的解决方案是将键和值作为 ByteArray 提供,这是 Kafka 用作源类型的最终类型:

val byteArraySerializer = new ByteArraySerializer
val stringFactory: ConsumerRecordFactory[Array[Byte], Array[Byte]] =
    new ConsumerRecordFactory[Array[Byte], Array[Byte]](
      eventTopic, byteArraySerializer, byteArraySerializer)
val recordString : ConsumerRecord[Array[Byte], Array[Byte]] = 
    stringFactory.create(testKey.getBytes, testVal.getBytes)

@nishu-tayal 提供的解决方案也有效,但它会强制您每次都指定主题。我想这是一个品味问题。