【问题标题】:Having trouble with implicit conversion in scalascala中的隐式转换有问题
【发布时间】:2014-07-19 15:25:20
【问题描述】:

有这个代码

case class Workspace(ident: Long, name: String)
case class Project(ident: Long, name: String)

implicit def workspaceJSON: JSONR[Workspace] = new JSONR[Workspace] {
  def read(json: JValue) =
    Workspace.applyJSON(field[Long]("id"), field[String]("name"))(json)
}

implicit def projectJSON: JSONR[Project] = new JSONR[Project] {
  def read(json: JValue) =
    Project.applyJSON(field[Long]("id"), field[String]("name"))(json)
}

def parseEnt[T: JSONR](json: JValue): Either[String, T] =
  fromJSON[T](json).toEither.left.map{ _.toString }

def fetchProjects(ws: Workspace): Either[String, Project] = {
  parseEnt(parse("some text"))
}

parseEnt(parse("some text")) 上编译失败

ambiguous implicit values:  both method taskJSON in class Fetcher of type =>
Fetcher.this.JSONR[types.Task]  and method workspaceJSON in class Fetcher of type =>
Fetcher.this.JSONR[Fetcher.this.Workspace]  match expected type Fetcher.this.JSONR[T]

有没有办法保证 scala,在这种情况下,我希望类型变量 T 成为 Project 并选择 projectJSON 函数来解析它?或者如果我做错了,那么如何以正确的方式做呢?

【问题讨论】:

  • 如果你明确说出你期望解析的内容怎么样? parseEnt[Project](parse("some text"))

标签: scala implicit-conversion json4s


【解决方案1】:

编译器试图自动推断类型 T,它必须是可以从 String 开始生成的东西(或多或少,但在这里详细说明不重要)

很遗憾,它无法成功,因为您提供了从 StringProjectWorkspace 的多个隐式转换。简单的解决方案是明确指出您要生成的类型:

parseEnt[Project](parse("some text"))

这种模式在序列化类型类中相当常见,您将多个特定类型映射到一个通用类型(在本例中为String)。

【讨论】:

  • 我知道编译器对于使用哪个实例模棱两可,但它无法从函数类型fetchProjects 推断类型对我来说很奇怪,我认为在这种情况下很清楚T 应该是 Project。似乎我必须阅读更多关于 scala 中的类型推断和隐含的内容。
猜你喜欢
  • 1970-01-01
  • 2012-01-02
  • 2019-04-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多