在类型 class 解决方案中遵循隐式实现有什么区别?
What is the difference in following implicit implementations in type class solutions?
在下面的例子中:
trait Writer[A] {
def write(a: A): String
}
case class Person(name: String, age: Int)
case class Student(name: String, roll: Int)
object DefaultStringWriters {
//here is implicit object, when to use object here?
implicit object PersonNameWriter extends Writer[Person] {
def write(person: Person) = person.name
}
//here is implicit val, when to use val here?
implicit val studentNameWriter = new Writer[Student] {
def write(student: Student) = student.name
}
}
object WriterUtil {
def stringify[A](data: A)(implicit writer: HtmlWriter[A]): String = {
writer.write(data)
}
}
#It works here with both.
WriterUtil.stringify(Person("john", "person@john.com"))
res0: String = john
WriterUtil.stringify(Person("student", "student@student.com"))
res1: String = student
在实际情况下我们什么时候使用隐式对象或 val?
差异
val
是在对象初始化期间按指定顺序创建的。 object
是懒惰创建的。
object
创建新的单例类型(例如 PersonNameWriter.type
) val
创建无类型(如本例)或结构类型。
val
可以被覆盖。 object
不能。
val
可以赋给任何表达式,例如Foo()
或 new Foo
。 object
必须是 class 定义,并且在重用代码的方式上受到更多限制,例如extends Foo
.
如果您不关心这些差异中的任何一个,那么选择哪一个都没有关系。在那种情况下,我建议 val
因为它不需要任何同步。
在下面的例子中:
trait Writer[A] {
def write(a: A): String
}
case class Person(name: String, age: Int)
case class Student(name: String, roll: Int)
object DefaultStringWriters {
//here is implicit object, when to use object here?
implicit object PersonNameWriter extends Writer[Person] {
def write(person: Person) = person.name
}
//here is implicit val, when to use val here?
implicit val studentNameWriter = new Writer[Student] {
def write(student: Student) = student.name
}
}
object WriterUtil {
def stringify[A](data: A)(implicit writer: HtmlWriter[A]): String = {
writer.write(data)
}
}
#It works here with both.
WriterUtil.stringify(Person("john", "person@john.com"))
res0: String = john
WriterUtil.stringify(Person("student", "student@student.com"))
res1: String = student
在实际情况下我们什么时候使用隐式对象或 val?
差异
val
是在对象初始化期间按指定顺序创建的。object
是懒惰创建的。object
创建新的单例类型(例如PersonNameWriter.type
)val
创建无类型(如本例)或结构类型。val
可以被覆盖。object
不能。val
可以赋给任何表达式,例如Foo()
或new Foo
。object
必须是 class 定义,并且在重用代码的方式上受到更多限制,例如extends Foo
.
如果您不关心这些差异中的任何一个,那么选择哪一个都没有关系。在那种情况下,我建议 val
因为它不需要任何同步。