bru*_*uno 2 extension-methods scala class implicit implicit-class
假设我有两个类Person
和Business
,它们由特质 扩展Entity
。
trait Entity
case class Person(name: String) extends Entity
case class Business(id: String) extends Entity
Run Code Online (Sandbox Code Playgroud)
假设我无法更改Entity
,Person
并且Business
(它们位于不同的文件中并且不能更改),我如何定义一个函数,例如 a ,根据实体printEntity
打印字段name
或?id
例如,给定Person
和的实例Business
,我该如何做这样的事情:
object Main extends App {
val person1: Person = Person("Aaaa Bbbb")
val business1: Business = Business("0001")
// How can I do something like this?
person1.printEntity // would call a function that executes println(id)
business1.printEntity // would call a function that executes println(name)
}
Run Code Online (Sandbox Code Playgroud)
任何想法表示赞赏!抱歉,缺乏上下文,我仍在学习!
这是通过所谓的“扩展方法”完成的。在 scala 2 中,这是使用隐式包装类来实现的:
trait Entity
case class Person(name: String) extends Entity
case class Business(id: String) extends Entity
implicit class PersonWrapper(val p: Person) extends AnyVal {
def printEntity(): Unit = {
println(p.name)
}
}
implicit class BusinessWrapper(val b: Business) extends AnyVal {
def printEntity(): Unit = {
println(b.id)
}
}
val person1: Person = Person("Aaaa Bbbb")
val business1: Business = Business("0001")
person1.printEntity()
business1.printEntity()
// prints:
//Aaaa Bbbb
//0001
Run Code Online (Sandbox Code Playgroud)
注意,x.printEntity
可以在没有括号的情况下调用,但是按照惯例,具有Unit
结果类型和副作用的方法应该使用显式的空括号来调用。
UPD:正如 @DmytroMitin 指出的那样,您应该从AnyVal
. 这允许编译器避免在运行时实际分配包装类实例,从而提高性能。