Мы используем Elasticsearch в качестве базы данных и на основе определения я создаю сопоставление типов. Это сопоставление - это в основном объект JSON, который XContentBuilder
с помощью XContentBuilder
Java-API elasticsearch.
В моем файле scala я определил объект Enumeration, который содержит возможные типы данных elasticsearch, например:
object TypeMapping extends Enumeration {
val StringType = DataType("string")
val FloatType = DataType("float")
...
val GeoShapeType = DataType("geo_shape")
val AttachmentType = DataType("attachment")
final case class DataType(esType: String) extends Val {
override def toString: String = esType
}
}
Теперь, когда я использую это при создании отображения JSON следующим образом:
val builder = jsonBuilder.startObject("name").field("type", StringType).endObject
компилятор scala прекрасно справляется со всеми способами вызова; нет ошибок или предупреждений.
Метод field
перегружено, каждый прием String
параметр name
и параметр value
. Эти значения могут быть конкретными (String
, int
, int[]
и т.д.) Или vararg (String...
, int...
и т.д.), Но также вариант Object
для конкретных вызовов и vararg.
Теперь я бы ожидал, что компилятор scala выберет field(String name, Object value)
в случае, который я описываю здесь, но, к моему удивлению, я нахожу, что field(String name, Object... value)
вызывается,
Я не понимаю, почему это происходит. Может ли кто-нибудь объяснить это мне?
Scala выбирает версию varargs как более конкретную, потому что (String, Array[Any])
можно применить к другому сигнатурному field(name: String, value: Any)
. (И не наоборот).
Учитывая, что оба метода находятся в одном классе, я не уверен, есть ли каноническое обходное решение помимо рефлексивного доступа:
type Picker = {
def f(name: String, value: Any): Int
}
Console println x.f("hi", "high") // varargs
Console println (x: Picker).f("hi", "high") // not
неоднозначности:
public class JOver {
public int f(String name, Object value) { return 1; }
public int f(String name, Object... values) { return 2; }
}
StringType
будет выглядеть как тип Any
, который я угадал, и который я ожидал отобразить в типе java.lang.Object
, но если я правильно вас понял, он будет отображаться как Array[Any]
и, следовательно, отображается в java.lang.Object...
?