我定义了一个拥有"视频"信息:
case class User(name:String, video: Option[Video])
case class Video(title:String, url:String)
我们有这样一个json:
{
"name": "somename",
"video": {
"title": "my-video",
"url": "https://youtube.com/watch?v=123123"
}
}
我可以使用这样的代码来解析它:
implicit def DecodeUser: DecodeJson[User] = for {
name <- as[String]("name")
video <- as[Option[Video]]("video")
} yield User(name, video)
implicit def DecodeVideo: DecodeJson[Option[Video]] = for {
titleOpt <- as[Option[String]]("title")
urlOpt <- as[Option[String]]("url")
} yield (titleOpt, urlOpt) match {
case (Some(title), Some(url)) => Video(title, url)
case _ => None
}
从DecodeVideo
,您可以看到我只想在两个&#34;标题&#34;和&#34; url&#34;提供。
如果json包含&#34;视频&#34;它运作良好。部分。但如果它没有,那么argonaut将报告&#34;视频&#34;部分未提供。
如何制作&#34;视频&#34;可选的?
答案 0 :(得分:-1)
我似乎无法弄清楚你的代码如何与argonaut集成。方法as[T]
的所有实例似乎都与您正在使用的签名不匹配。无论如何,这是一个类似的问题和解决方案:
object Test {
case class Video(title: String, url: String)
def test(titleOptIn: List[Option[String]], urlOptIn: List[Option[String]]): List[Option[Video]] = {
for {
titleOpt <- titleOptIn
urlOpt <- urlOptIn
} yield (titleOpt, urlOpt) match {
case (Some(title), Some(url)) => Some(Video(title, url))
case _ => None.asInstanceOf[Option[Video]]
}
}
def main(args: Array[String]): Unit = {
test(List(Some("t")), List(Some("u"), None)).foreach(println)
}
}
// Has Output:
// Some(Video(t,u))
// None
请特别注意,收益率理解应返回Option[String]
,因为您的收益可能会将结果包装在DecodeJson
中,就像我的示例将其包含在List
中一样。请注意,None上的asInstanceOf
是可选的; IntelliJ抱怨如果它不存在但实际上编译得很好。
我认为你缺少的具体内容是将Video
包裹在Some
中。