我想Sample#cap(String)在selectDynamic的以下宏实现中使用.
可能吗?
// macro implementation
import scala.language.experimental.macros
import scala.reflect.macros._
object MyMacros {
def selectDynamic(c: Context)(name: c.Expr[String]): c.Expr[String] = {
// I expected `This` to refer a Sample instance, but actually it refers SampleSpec instance...
c.Expr[String](Apply(TypeApply(Select(This(tpnme.EMPTY), newTermName("cap")), List(Ident(typeTag[String].tpe.typeSymbol))), List(name.tree)))
}
}
// class which uses selectDynamic and macro
import scala.language.dynamics
class Sample extends Dynamic {
def cap(name: String): String = name.toUpperCase
def selectDynamic(name: String): String = macro MyMacros.selectDynamic
}
class SampleSpec extends FlatSpec with ShouldMatchers {
it should "call …Run Code Online (Sandbox Code Playgroud) 我有下一个类结构:
trait SomeType
trait Root {
val allMySomeTypes: Seq[SomeType]
}
class Child extends Root {
object MyType1 extends SomeType {...}
object MyType2 extends SomeType {...}
}
Run Code Online (Sandbox Code Playgroud)
我想初始化val allMySomeTypes作为扩展在具体类中定义的SomeType的所有对象的Seq.所以对于Child实例,它将是val allMySomeTypes:Seq [SomeType] = Seq(MyType1,MyType2).
我写了一个宏来查找具有一些基类型的对象:
def getMembersOfCurrentByType_impl[S](c: Context)(implicit ev: c.WeakTypeTag[S]) = {
import c.universe._
val seqApply = Select(reify(Seq).tree, newTermName("apply"))
val objs = c.enclosingClass.symbol.typeSignature.declarations.collect {
case o: ModuleSymbol if o.typeSignature <:< ev.tpe => Ident(o) //Select(c.prefix.tree, o)
}.toList
c.Expr[Seq[S]] {Apply(seqApply, objs)}
}
Run Code Online (Sandbox Code Playgroud)
并绑定到
trait Root {
val allMySomeTypes: Seq[SomeType] = macro getMembersOfCurrentByType_impl[SomeType]
}
Run Code Online (Sandbox Code Playgroud)
但是,显然,由于基本特征的宏扩展,我在Child类中有空序列.我可以在没有在Child类中额外输入而不使用运行时反射的情况下构建实际成员的Seq吗?
通用案例类
case class GroupResult[T](
group: String,
reduction: Seq[T]
)
Run Code Online (Sandbox Code Playgroud)
宏观方法
def foo[T] = macro fooImpl[T]
def fooImpl[T: c.WeakTypeTag](c: Context) = {
import c.universe._
val tpe = weakTypeOf[T]
tpe.declarations.collect {
case m: MethodSymbol if m.isCaseAccessor => println(m.returnType)
}
c.literalUnit
}
Run Code Online (Sandbox Code Playgroud)
当我调用 foo[GroupResult[Int]]
输出是
String
Seq[T]
Run Code Online (Sandbox Code Playgroud)
T不适用?我怎样才能获得申请Seq[Int]?
如何让 Scala 编译器自动生成 case 对象?
// Pizza class
class Pizza (val crust_type: String)
// companion object
object Pizza {
val crustType = "crust_type"
}
Run Code Online (Sandbox Code Playgroud)
案例对象的所需属性
case class生成一个属性case objectcamelCase到snake_case该对象的属性名,保持snake_case为对象的属性值看来 的输入Context.eval只能引用来自不同编译单元的值:
// project 1
object Z {
val foo = "WOOF"
def impl(c: Context)(x: c.Expr[String]) = {
val x1 = c.Expr[String](c.untypecheck(x.tree.duplicate))
println(s"compile-time value is: ${c.eval(x1)}")
x
}
def test(x: String) = macro impl
}
// project 2
object Y {
val foo = "GOOF"
val boo = Z.test(Z.foo)
}
println(Y.boo)
Run Code Online (Sandbox Code Playgroud)
打印出"WOOF",但如果我将 boo 替换为val boo = Z.test(Y.foo),则会出现以下编译错误:
Error:(32, 29) exception during macro expansion:
java.lang.ClassNotFoundException: Y$
at scala.reflect.internal.util.AbstractFileClassLoader.findClass(AbstractFileClassLoader.scala:72)
...
Run Code Online (Sandbox Code Playgroud)
有什么办法可以解决这个问题吗?我知道用 quill.io 定义的查询可以引用同一范围的方法,但我无法找到他们用来允许它的技巧。
我正在使用 scala3 进行编码,利用编程结构类型。结构类型恰好模仿了现有的案例类:它们的定义是纯粹的样板,因此很容易通过元编程来制作它们。
我了解如何制作函数实现,通常是通过类型类派生。但在这里我们正在尝试制作一个(结构)类型。
这在 scala2 中是可能的,通过类宏注释,但这些在 scala3 中已经消失了。有办法吗?如果是这样怎么办?
下面的代码是我想获得的结果:
// Library part
trait View extends scala.Selectable :
def selectDynamic(key:String) =
println(s"$key is being looked up")
???
// DSL Definition part
case class SomeDefWithInt ( i : Int )
case class SomeDefWithString( s : String )
// Boiler-plate code
type ViewOf[M] = M match
case SomeDefWithInt => View { def i : Int }
case SomeDefWithString => View { def s : …Run Code Online (Sandbox Code Playgroud) Scala不像Python那样提供链式比较:
// Python:
0 < x <= 3
// Scala:
0 < x && x <= 3
Run Code Online (Sandbox Code Playgroud)
具有新宏功能的Scala 2.10能否让程序员编写一个添加此功能的库?或者这超出了Scala宏的范围?
宏似乎是实现这种语法糖的正确选择,因为它们不会使解析器/编译器复杂化.
我想使用Scala宏在树中找到所有可能的序列创建.
val l = List(1, 2)
val v = Vector(1, 2)
val ab = ArrayBuffer(1, 2)
val s = Seq(1, 2)
Run Code Online (Sandbox Code Playgroud)
但以下匹配不起作用:
case Apply(TypeApply(Select(path, Name("apply")), _), args) if path.tpe <:< weakTypeOf[SeqFactory[Any]] => ...
Run Code Online (Sandbox Code Playgroud)
同样,我需要通过索引查找序列的所有访问:
val v = Vector(1, 2)
val one = v(0)
Run Code Online (Sandbox Code Playgroud)
或路径上的所有'apply'方法调用,即path.tpe <:<???? [Seq [_]
怎么写这张支票?这不编译:
case Apply(Select(path, Name("apply")), List(idx)) if path.tpe <:< typeOf[Seq[_]]
Run Code Online (Sandbox Code Playgroud) 我有一个使用宏的scala项目,它基本上遵循这里描述的确切方法(http://www.scala-sbt.org/0.12.4/docs/Detailed-Topics/Macro-Projects.html),包括整个分发部分(所以本质上我有一个根项目,一个名为宏的子项目,用于保存正在使用的宏)
问题是,当我发布我的项目(现在使用publish-local),而另一个scala项目使用带有宏作为依赖项的项目时,它会尝试拉宏#macro_2.10; 0.1-SNAPSHOT因为它出现在POM.这导致项目无法编译,因为它无法解决依赖关系,即
> compile
[info] Updating {file:/Users/mdedetrich/silvermanwylie/waitress/}default-0e4b9d...
[info] Resolving macro#macro_2.10;0.1-SNAPSHOT ...
[warn] module not found: macro#macro_2.10;0.1-SNAPSHOT
[warn] ==== local: tried
[warn] /Users/mdedetrich/.ivy2/local/macro/macro_2.10/0.1-SNAPSHOT/ivys/ivy.xml
[warn] ==== public: tried
[warn] http://repo1.maven.org/maven2/macro/macro_2.10/0.1-SNAPSHOT/macro_2.10-0.1-SNAPSHOT.pom
[info] Resolving org.slf4j#slf4j-api;1.6.4 ...
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: UNRESOLVED DEPENDENCIES ::
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: macro#macro_2.10;0.1-SNAPSHOT: not found
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[trace] Stack trace suppressed: run last *:update for the full output.
[error] (*:update) sbt.ResolveException: unresolved dependency: macro#macro_2.10;0.1-SNAPSHOT: not found
[error] Total time: 0 s, completed Aug 23, 2013 8:15:56 …Run Code Online (Sandbox Code Playgroud) 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 ×10
scala-macros ×10
macros ×3
scala-2.10 ×2
annotations ×1
case-class ×1
comparison ×1
generics ×1
pom.xml ×1
quill.io ×1
sbt ×1
scala-3 ×1
scalameta ×1