可能重复:
scala自我类型和特质子类之间有什么区别?
我理解一个自我注释作为对编译器的承诺,程序员在其中表明特征将与带注释的特征混合.例如:
scala> trait X
defined trait X
scala> trait Y { this: X => }
defined trait Y
scala> new Y {}
<console>:10: error: illegal inheritance;
self-type Y does not conform to Y's selftype Y with X
new Y {}
^
scala> new Y with X {}
res1: Y with X = $anon$1@1125a40
Run Code Online (Sandbox Code Playgroud)
在前面的示例中,第三个表达式失败,因为我们没有为新实例设置有效的X. 显然,最后一个很好用.到现在为止还挺好.现在,让我们看另一个涉及对象的例子.
scala> object Z { this: X => }
defined module Z
Run Code Online (Sandbox Code Playgroud)
我理解对象是在实例化的情况下失败的X承诺(我们现在正在创建一个具有未来承诺的实例!),如下一行所示,其中特征略有修改:
scala> trait X { class X1 }
defined trait X
scala> …Run Code Online (Sandbox Code Playgroud) 我必须在一个使用蛋糕模式的项目中集成一些宏.这种模式使我们能够避免数以万计的进口,以及其他优势,因此我们希望保留它.现在,我们正面临一些问题,我们已经在主干外测试了一些实验宏.首先,让我们展示一个名为Cake的虚拟系统:
trait APiece {
class A
}
trait BPiece { this: APiece =>
def aMacro(a: A): Unit = () /* macro ??? */
}
trait CPiece { this: APiece with BPiece =>
def aMacroInvoker = aMacro(new A)
}
class Cake { this: APiece with BPiece with CPiece => }
Run Code Online (Sandbox Code Playgroud)
APiece定义了一个类,BPiece应该是一个使用APiece定义类的宏,最后,CPiece调用宏.我说BPiece应该是一个宏,因为我无法为它编写实现代码.我尝试了几种方法,但我总是崩溃以下错误:
"macro implementation must be in statically accessible object"
Run Code Online (Sandbox Code Playgroud)
读取宏代码可以猜测将宏封装在静态模块中是必要的.有没有办法部署使用系统结构的宏?
我一直在测试一些嵌套的宏调用,它们按预期工作(...正如我所料!)例如,假设一个虚构的添加宏和下面的表达式:
add(1, add(2, 3))
Run Code Online (Sandbox Code Playgroud)
首先,内部添加扩展(2 + 3),其次,外部添加部分(1 +(2 + 3)).我已经看到outter宏没有从内部调用中获得任何噪声 - 在输入表达式中 - 因此内部扩展似乎对它完全透明.这个事实总是成立(即使是更复杂的宏和类型)?这样做是否安全?
在使用宏时,我已经达到了这一点(我一直在努力避免它),我需要在AST中更新那些具有特定条件的节点.例如,假设我想更新每个节点:
Literal(Constant(1))
Run Code Online (Sandbox Code Playgroud)
价值:
Literal(Constant(2))
Run Code Online (Sandbox Code Playgroud)
那些AST节点可以在表达式树中的任何位置,因此我不能使用ad-hoc模式匹配器.显然,我想做的最后一件事是编写一个完整的模式匹配器,它能够覆盖所有的编译器原语.我一直在API中搜索,但我的印象是诸如collect和遍历族之类的方法不足以满足我的需求,因为它们将树视为线性的东西,我希望整个更新的树作为结果.那么,是否可以以智能方式更新不可变表达式树?为什么在标准API中不存在这样的"更新"操作?
我正在玩反思,以实现对特质的深入分析.我想得到的一件事是设置成员字段的初始值.例如,在特征中:
trait A {
val x: Int = 3
val y: String = "y"
}
Run Code Online (Sandbox Code Playgroud)
知道3和"y"会很高兴.我没有在API中找到与此任务相关的任何内容,并且由于以下输出(由scalac -Xprint生成):
abstract trait A extends Object {
<accessor> def com$hablapps$A$_setter_$x_=(x$1: Int): Unit;
<accessor> def com$hablapps$A$_setter_$y_=(x$1: String): Unit;
<stable> <accessor> def x(): Int;
<stable> <accessor> def y(): String
};
abstract trait A$class extends {
def /*A$class*/$init$($this: com.hablapps.A): Unit = {
$this.com$hablapps$A$_setter_$x_=(3);
$this.com$hablapps$A$_setter_$y_=("y");
()
}
}
Run Code Online (Sandbox Code Playgroud)
我担心访问它们会很困难,因为它们保存在$ init $方法的主体中.是否有任何(简单)方法可以通过反射获得这些值?
Let's say I wanted to replicate an annotation like @specialized(Int)--crazy I know--using macro annotations. Something like:
class expand(expanded: Any*) extends Annotation with StaticAnnotation {
def macroTransform(annottees: Any*) = macro expand.expandImpl
}
object expand {
def expandImpl(c: Context)(annottees: c.Expr[Any]*):c.Expr[Any] = {
// would like to be able to get access to the "expanded" args above.
???
}
}
// Usage:
def foo[@expand(Int) T] = 4
Run Code Online (Sandbox Code Playgroud)
Is there any way to get access to the arguments of the annotation (Int in the …
scala ×6
scala-2.10 ×4
macros ×3
self-type ×2
annotations ×1
cake-pattern ×1
mixins ×1
reflection ×1
scala-macros ×1