这会编译。 (请注意,implicit val subscriptionReads
由 emailIdReads
和 intervalReads
声明在隐式之外,而 subscriptionWrites
由隐式内部声明的Writes
组成。)
import play.api.libs.json.Reads._
import play.api.libs.json.Writes._
import play.api.libs.json._
import play.api.libs.functional.syntax._
case class Subscription(emailId: String, interval: String)
object Subscription {
val emailIdReads: Reads[String] = (JsPath \ "emailId").read[String]
val intervalReads: Reads[String] = (JsPath \ "interval").read[String]
implicit val subscriptionReads: Reads[Subscription] = (
emailIdReads and
intervalReads
)(Subscription.apply _)
implicit val subscriptionWrites: Writes[Subscription] = (
(JsPath \ "emailId").write[String] and
(JsPath \ "interval").write[String]
)(unlift(Subscription.unapply))
}
然而下面的代码——其中两个 Writes
值被声明在隐式之外——没有编译,产生错误消息:“值 and
不是 play.api.libs.json.Writes[String] 的成员。”
import play.api.libs.json.Reads._
import play.api.libs.json.Writes._
import play.api.libs.json._
import play.api.libs.functional.syntax._
case class Subscription(emailId: String, interval: String)
object Subscription {
val emailIdReads: Reads[String] = (JsPath \ "emailId").read[String]
val intervalReads: Reads[String] = (JsPath \ "interval").read[String]
implicit val subscriptionReads: Reads[Subscription] = (
emailIdReads and
intervalReads
)(Subscription.apply _)
val emailIdWrites: Writes[String] = (JsPath \ "emailId").write[String]
val intervalWrites: Writes[String] = (JsPath \ "interval").write[String]
implicit val subscriptionWrites: Writes[Subscription] = (
emailIdWrites and
intervalWrites
)(unlift(Subscription.unapply))
}
我错过了什么?为什么我不能用 equals 代替 equals?此外,为什么我可以使用Reads
而不是Writes
。我想理解为什么这行不通。
和
的相关定义见play.api.libs.functional
。
package play.api.libs.functional
import scala.language.higherKinds
case class ~[A, B](_1: A, _2: B)
trait FunctionalCanBuild[M[_]] {
def apply[A, B](ma: M[A], mb: M[B]): M[A ~ B]
}
class FunctionalBuilderOps[M[_], A](ma: M[A])(implicit fcb: FunctionalCanBuild[M]) {
def ~[B](mb: M[B]): FunctionalBuilder[M]#CanBuild2[A, B] = {
val b = new FunctionalBuilder(fcb)
new b.CanBuild2[A, B](ma, mb)
}
def and[B](mb: M[B]): FunctionalBuilder[M]#CanBuild2[A, B] = this.~(mb)
}
/* Additional arities elided */
最佳答案
我不得不深入挖掘一下,原因实际上是在这个文件中,其中定义了所需的隐式:
它是为类型 OWrites 而不是 Writes 定义的。你从 .write[String] 得到的实际上是 OWrites[String] 类型。它不起作用的原因是,您明确指定了更宽的 Writes 类型。
关于json - 为什么 Scala 编译器会区别对待这两个代码块?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35352966/