gpt4 book ai didi

scala - 如何将特征混合到实例中?

转载 作者:行者123 更新时间:2023-12-01 05:12:08 27 4
gpt4 key购买 nike

给定一个特征 MyTrait :

trait MyTrait {
def doSomething = println("boo")
}

它可以与 extends 混合成一个类或 with :
class MyClass extends MyTrait

它也可以在实例化新实例时混合使用:
var o = new MyOtherClass with MyTrait
o.doSomething

但是...可以将特征(或任何其他特征,如果这有所不同)添加到现有实例中?

我正在使用 Java 中的 JPA 加载对象,我想使用特征为它们添加一些功能。有可能吗?

我希望能够混合如下特征:
var o = DBHelper.loadMyEntityFromDB(primaryKey);
o = o with MyTrait //adding trait here, rather than during construction
o.doSomething

最佳答案

我对这种用法有一个想法:

//if I had a class like this
final class Test {
def f = println("foo")
}
trait MyTrait {
def doSomething = {
println("boo")
}
}
object MyTrait {
implicit def innerObj(o:MixTest) = o.obj

def ::(o:Test) = new MixTest(o)
final class MixTest private[MyTrait](val obj:Test) extends MyTrait
}

你可以使用这个特性如下:
import MyTrait._

val a = new Test
val b = a :: MyTrait
b.doSomething
b.f

对于您的示例代码:
val o = DBHelper.loadMyEntityFromDB(primaryKey) :: MyTrait
o.doSomething

我希望这可以帮助你。

更新
object AnyTrait {
implicit def innerObj[T](o: MixTest[T]):T = o.obj

def ::[T](o: T) = new MixTest(o)
final class MixTest[T] private[AnyTrait](val obj: T) extends MyTrait
}

但是这个模式有一些限制,你不能使用一些已经定义的隐式辅助方法。
val a = new Test
a.f
val b = a :: AnyTrait
b.f1
b.f
val c = "say hello to %s" :: AnyTrait
println(c.intern) // you can invoke String's method
println(c.format("MyTrait")) //WRONG. you can't invoke StringLike's method, though there defined a implicit method in Predef can transform String to StringLike, but implicit restrict one level transform, you can't transform MixTest to String then to StringLike.
c.f1
val d = 1 :: AnyTrait
println(d.toLong)
d.toHexString // WRONG, the same as above
d.f1

关于scala - 如何将特征混合到实例中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3893274/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com