Это может быть ковариантным, особенно если вы рассматриваете Reads[A]
как более богатую форму JsValue => A
.
Но .... implicitness.
Reads[A]
не только способ преобразования из JsValue
в A
, это путь.
Так что, если мы имели
sealed trait Foo
case class Bar(a: Int)
case class Baz(b: Int)
Если вы определили Reads[Bar]
, вы бы также (с ковариации) имеют Reads[Foo]
.
Это может быть немного странно.
object Foo {
implicit reads: Reads[Foo] =
implicitly[Reads[Bar]].orElse[implicitly[Reads[Baz]]]
}
object Bar {
implicit reads = Json.reads[Bar] // {"a":0}
}
object Baz {
implicit reads = Json.reads[Baz] // {"b":0}
def blah(jsValue: JsValue): Foo = jsValue.as[Foo]
}
object Main {
def blah(jsValue: JsValue): Foo = jsValue.as[Foo]
}
Что происходит в Baz.blah
и Main.blah
? Первый использует Baz.reads
, а последний использует Foo.reads
из-за (сложного) неявного порядка разрешения.
Это краевой кейс, и я все еще думаю, что вы можете сделать хороший аргумент для ковариации, но он показывает разницу между «вещью, возможно, разобрать JSON на Foo
» и «вещь, которая может анализировать JSON во всех возможно Foo
".
Спасибо, это не так, как я думал. Можете ли вы прокомментировать суть. Как вы думаете, следует ли писать 'читает [Child] .map (x => x)' или 'читает [Child] .as [Reads [Parent]]', может ли что-то не так случилось в последнем? – phadej
@phadej, вы имеете в виду '.asInstanceOf'? В любом случае, я не думаю, что с расширением этого типа есть что-то плохое. Единственная проблема заключается в том, если это делается для implicits автоматически. –