与 Scala 隐含的类型不匹配
Type mismatch with Scala implicits
我正在尝试在 Scala 中使用隐式。
object TypeClasses extends App {
trait HTMLWritable {
def toHTML: String
}
case class User(name: String, age: Int, email: String) extends HTMLWritable {
override def toHTML: String = s"<div>$name ($age yo) <a href=$email/> </div>"
}
val john = User("John", 32, "john@rockthejvm.com")
trait HTMLSerializer[T] {
def serialize(value: T): String
}
object UserSerializer extends HTMLSerializer[User] {
def serialize(user: User): String = s"<div>${user.name} (${user.age} yo) <a href=${user.email}/> </div>"
}
implicit class HTMLEnrichment[T](value: T) {
def toHTML(serializer: HTMLSerializer[T]): String = serializer.serialize(value)
}
println(john.toHTML(UserSerializer))
}
此代码无法编译:
Error:(41, 23) type mismatch;
found : lectures.part4implicits.TypeClasses.UserSerializer.type
required: Int
println(john.toHTML(UserSerializer))
我无法理解该消息,因为根据 IntelliJ,john.toHTML
是对 HTMLEnrichment
class 上的 toHTML
方法的调用,它期望一个HTMLSerializer
,这是我给的。我没有在任何地方定义需要 Int
.
的 toHTML
方法
这是因为您不小心重载了 toHTML
方法。您收到的错误是因为 String.apply
returns 给定索引处的字符,这就是为什么您收到有关 Int
.
的错误的原因
Intelij 并不总是能有效地挑选出这种阴影。使隐式机制远离域模型是个好主意,例如,将专门的序列化解耦为隐式,就像您正在做的那样:
implicit object UserSerializer extends HTMLSerializer[User] {
def serialize(user: User): String = s"<div>${user.name} (${user.age} yo) <a href=${user.email}/> </div>"
}
然后从您的 user
中删除所有内容,并可能添加一个助手。
trait HTMLSerializer {
def toHTML: String
}
object HTMLSerializer {
// if you put this here you don't need to explicitly import it.
implicit class HTMLEnrichment[T](val value: T) extends AnyVal {
def toHTML(implicit serializer: HTMLSerializer[T]): String =
serializer.serialize(value)
}
}
这意味着您可以简单地获得与使用伴随方法相同的效果,但您可以使所有内容很好地解耦,并且您不会冒出现此类着色效果的风险。
我正在尝试在 Scala 中使用隐式。
object TypeClasses extends App {
trait HTMLWritable {
def toHTML: String
}
case class User(name: String, age: Int, email: String) extends HTMLWritable {
override def toHTML: String = s"<div>$name ($age yo) <a href=$email/> </div>"
}
val john = User("John", 32, "john@rockthejvm.com")
trait HTMLSerializer[T] {
def serialize(value: T): String
}
object UserSerializer extends HTMLSerializer[User] {
def serialize(user: User): String = s"<div>${user.name} (${user.age} yo) <a href=${user.email}/> </div>"
}
implicit class HTMLEnrichment[T](value: T) {
def toHTML(serializer: HTMLSerializer[T]): String = serializer.serialize(value)
}
println(john.toHTML(UserSerializer))
}
此代码无法编译:
Error:(41, 23) type mismatch;
found : lectures.part4implicits.TypeClasses.UserSerializer.type
required: Int
println(john.toHTML(UserSerializer))
我无法理解该消息,因为根据 IntelliJ,john.toHTML
是对 HTMLEnrichment
class 上的 toHTML
方法的调用,它期望一个HTMLSerializer
,这是我给的。我没有在任何地方定义需要 Int
.
toHTML
方法
这是因为您不小心重载了 toHTML
方法。您收到的错误是因为 String.apply
returns 给定索引处的字符,这就是为什么您收到有关 Int
.
Intelij 并不总是能有效地挑选出这种阴影。使隐式机制远离域模型是个好主意,例如,将专门的序列化解耦为隐式,就像您正在做的那样:
implicit object UserSerializer extends HTMLSerializer[User] {
def serialize(user: User): String = s"<div>${user.name} (${user.age} yo) <a href=${user.email}/> </div>"
}
然后从您的 user
中删除所有内容,并可能添加一个助手。
trait HTMLSerializer {
def toHTML: String
}
object HTMLSerializer {
// if you put this here you don't need to explicitly import it.
implicit class HTMLEnrichment[T](val value: T) extends AnyVal {
def toHTML(implicit serializer: HTMLSerializer[T]): String =
serializer.serialize(value)
}
}
这意味着您可以简单地获得与使用伴随方法相同的效果,但您可以使所有内容很好地解耦,并且您不会冒出现此类着色效果的风险。