Как я могу использовать неявные преобразования для двух типов, которые разрешаются в один и тот же базовый тип?

type JSON = String
type YAML = String

implicit def json2yaml(in:JSON):YAML = "some conversion"

val js:JSON = "some json"
val yml: YAML = js

В приведенном выше коде yml назначается "some json". Неявное преобразование не используется. Это потому, что и YAML, и JSON разрешаются в String? Есть ли способ заставить код поднять конверсию?


person Greg    schedule 23.12.2019    source источник
comment
Такие напрямую - нет, но, конечно, вы всегда можете обернуть их в классы case со строковыми параметрами и сделать это легко   -  person Dmitry Reutov    schedule 24.12.2019
comment
Подразумевает, что преобразования - плохая практика, теперь преобразование из двух одинаковых типов кажется отличным способом сделать код трудным для понимания. Что плохого в добавлении только toYaml метода расширения?   -  person Luis Miguel Mejía Suárez    schedule 24.12.2019


Ответы (1)


Обратите внимание, что между типом и его псевдонимом существует связь эквивалентность

Если ???? определяется псевдонимом типа type ???? = ????, то ???? эквивалентно ????.

это означает, что ???? и ???? взаимозаменяемы в всех контекстах. Когда мы определяем псевдоним

type JSON = String

тогда String не является "базовым" типом JSON, вместо этого он является JSON самим. Таким образом

implicit def json2yaml(in: JSON): YAML = "some conversion"

эквивалентно

implicit def json2yaml(in: String): String = "some conversion"

поэтому неявное преобразование не происходит.

Вместо неявного преобразования (которое, как правило, не рекомендуется) рассмотрите подход метода расширения следующим образом

case class Json(v: String)
case class Yaml(v: String)

implicit class JsonToJaml(json: Json) {
  def asYaml: Yaml = Yaml("some conversion which uses ${json.v}")
}

val js: Json = Json("some json")
val yml: Yaml = js.asYaml
person Mario Galic    schedule 23.12.2019