在scala中进行隐式转换遇到麻烦 [英] Having trouble with implicit conversion in scala
问题描述
具有此代码
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"))
}
使用
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
函数对其进行解析?或者,如果我做错了,那怎么做才正确呢?
编译器正在尝试自动推断类型T
,该类型必须是可以从String
开始生成的类型(或多或少,但此处不重要)
不幸的是,它无法成功,因为您要提供从String
到Project
和Workspace
的多个隐式转换.一种简单的解决方案是明确指出您要生成的类型:
parseEnt[Project](parse("some text"))
此模式在序列化类型类中相当普遍,在该类中,您将多个特定类型映射到通用类型(在本例中为String
).
Having this code
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"))
}
Which fails to compile on parseEnt(parse("some text"))
with
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]
Is there a way to assure scala, that in this case I want type variable T
to be a Project
and choose projectJSON
function to parse it? Or if I'm doing it wrong, then how do it in right way?
The compiler is trying to automatically infer the type T
, which must be something that it can be produced starting from a String
(more or less, but details an unimportant here)
Unfortunately it can't succeed, since you're providing multiple implicit conversions going from String
to Project
and Workspace
. The simple solution is to explicitly indicate the type you're trying to produce:
parseEnt[Project](parse("some text"))
This pattern is fairly common with serialization type classes, where you are mapping multiple specific types to a generic one (String
in this case).
这篇关于在scala中进行隐式转换遇到麻烦的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!