一个类型类从编程斯卡拉书所采取的示例:在Scala中构建类型类的不同方法?
case class Address(street: String, city: String)
case class Person(name: String, address: Address)
trait ToJSON {
def toJSON(level: Int = 0): String
val INDENTATION = " "
def indentation(level: Int = 0): (String,String) =
(INDENTATION * level, INDENTATION * (level+1))
}
implicit class AddressToJSON(address: Address) extends ToJSON {
def toJSON(level: Int = 0): String = {
val (outdent, indent) = indentation(level)
s"""{
|${indent}"street": "${address.street}",
|${indent}"city": "${address.city}"
|$outdent}""".stripMargin
}
}
implicit class PersonToJSON(person: Person) extends ToJSON {
def toJSON(level: Int = 0): String = {
val (outdent, indent) = indentation(level)
s"""{
|${indent}"name": "${person.name}",
|${indent}"address": ${person.address.toJSON(level + 1)}
|$outdent}""".stripMargin
}
}
val a = Address("1 Scala Lane", "Anytown")
val p = Person("Buck Trends", a)
println(a.toJSON())
println()
println(p.toJSON())
的代码工作正常,但我的印象(一些博客文章),该类型类通常做这样的斯卡拉:
// src/main/scala/progscala2/implicits/toJSON-type-class.sc
case class Address(street: String, city: String)
case class Person(name: String, address: Address)
trait ToJSON[A] {
def toJSON(a: A, level: Int = 0): String
val INDENTATION = " "
def indentation(level: Int = 0): (String,String) =
(INDENTATION * level, INDENTATION * (level+1))
}
object ToJSON {
implicit def addressToJson: ToJSON[Address] = new ToJSON[Address] {
override def toJSON(address: Address, level: Int = 0) : String = {
val (outdent, indent) = indentation(level)
s"""{
|${indent}"street": "${address.street}",
|${indent}"city": "${address.city}"
|$outdent}""".stripMargin
}
}
implicit def personToJson: ToJSON[Person] = new ToJSON[Person] {
override def toJSON(a: Person, level: Int): String = {
val (outdent, indent) = indentation(level)
s"""{
|${indent}"name": "${a.name}",
|${indent}"address": ${implicitly[ToJSON[Address]].toJSON(a.address, level + 1)}
|$outdent}""".stripMargin
}
}
def toJSON[A](a: A, level: Int = 0)(implicit ev: ToJSON[A]) = {
ev.toJSON(a, level)
}
}
val a = Address("1 Scala Lane", "Anytown")
val p = Person("Buck Trends", a)
import ToJSON.toJSON
println(toJSON(a))
println(toJSON(p))
哪种方式更好或更正确?任何见解都值得欢迎。
你也许可以在程序员社区中问这个问题:http://programmers.stackexchange.com/ – ManoDestra
@ManoDestra - 这可能会被程序员关闭,主要是基于观点。这种问题的很多(大部分)问题都归结为“选择一种方法并保持一致”的答案。 – GlenH7
确实如此。看起来更像是一个编程特定的问题,而不是一个可靠的实现。 – ManoDestra