Nik*_*kov 38 scala traits mixins case-class
有特点
trait Persisted {
def id: Long
}
Run Code Online (Sandbox Code Playgroud)
如何实现一个接受任何case类实例的方法并返回其特征混合的副本?
该方法的签名如下:
def toPersisted[T](instance: T, id: Long): T with Persisted
Run Code Online (Sandbox Code Playgroud)
Eug*_*ako 32
这可以通过宏完成(从2.10.0-M3开始,它正式成为Scala的一部分).以下是您正在寻找的主要示例.
1)我的宏生成一个本地类,它继承自提供的case类和Persisted,就像new T with Persisted那样.然后它缓存其参数(以防止多次评估)并创建所创建的类的实例.
2)我怎么知道要生成什么树?我有一个简单的应用程序,parse.exe打印解析输入代码产生的AST.所以我只是调用parse class Person$Persisted1(first: String, last: String) extends Person(first, last) with Persisted,注意输出并在我的宏中重现它.parse.exe是一个包装器scalac -Xprint:parser -Yshow-trees -Ystop-after:parser.探索AST有不同的方法,请阅读"Scala 2.10中的元编程".
3)如果你提供-Ymacro-debug-litescalac的参数,宏扩展可以进行健全性检查.在这种情况下,所有扩展都将打印出来,您将能够更快地检测到codegen错误.
编辑.更新了2.10.0-M7的示例
使用vanilla scala无法实现您想要的效果.问题是mixins如下:
scala> class Foo
defined class Foo
scala> trait Bar
defined trait Bar
scala> val fooWithBar = new Foo with Bar
fooWithBar: Foo with Bar = $anon$1@10ef717
Run Code Online (Sandbox Code Playgroud)
创建一个Foo with Bar混合,但它不是在运行时完成的.编译器只是生成一个新的匿名类:
scala> fooWithBar.getClass
res3: java.lang.Class[_ <: Foo] = class $anon$1
Run Code Online (Sandbox Code Playgroud)
请参阅Scala中的动态混合 - 是否可能?了解更多信息.
| 归档时间: |
|
| 查看次数: |
10675 次 |
| 最近记录: |