我正在尝试编写一个函数,该函数使用 scala 宏将给定值填充到数组中。例如调用:
val ary = Array( 0, 1, 2 )
fill3( ary, 50+25 )
应该扩展为:
val ary = Array(0, 1, 2 )
{
val $value = 50+25
ary(0) = $value
ary(1) = $value
ary(2) = $value
}
这是我的第一次尝试:
def fill3( ary: Array[Int], x: Int ) = macro fill_impl3
def fill_impl3( c: Context )
( ary: c.Expr[Array[Int]], x: c.Expr[Int]): c.Expr[Unit] = {
import c.universe._
def const(x:Int) = Literal(Constant(x))
//Precompute x
val valName = newTermName("$value")
val valdef = ValDef( Modifiers(), valName, TypeTree(typeOf[Int]), x.tree )
val updates = List.tabulate( 3 ){
i => Apply( Select( ary.tree, "update"), List( const(i), ??? ) )
}
val insts = valdef :: updates
c.Expr[Unit](Block(insts:_*))
}
但这里我卡住了有两个原因:
- 我不知道如何获取预计算值 (
$value
) - 对于大小为 3、4、6、9 和 27 的数组,我需要这些函数中的几个。有没有办法干掉定义,或者我应该写
fill3
,fill4
、fill6
等
有正确的方法吗?我该如何解决我的两个问题?
编辑:我意识到我最初的问题很愚蠢,因为在编译时必须知道大小......
最佳答案
def fill(size:Int, ary: Array[Int], x: Int ) = macro fill_impl
def fill_impl( c: Context )
(size:c.Expr[Int], ary: c.Expr[Array[Int]], x: c.Expr[Int]): c.Expr[Unit] = {
import c.universe._
def const(x:Int) = Literal(Constant(x))
val Literal(Constant(arySize:Int)) = size.tree
//Precompute x
val valName = newTermName("$value")
val valdef = ValDef( Modifiers(), valName, TypeTree(typeOf[Int]), x.tree )
val updates = List.tabulate( arySize ){
i => Apply( Select( ary.tree, "update"), List( const(i), Ident(valName) ) )
}
val insts = valdef :: updates
c.Expr[Unit](Block(insts:_*))
}
关于scala - 用宏写数组填充,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12018205/