scala - 用宏写数组填充

标签 scala macros

我正在尝试编写一个函数,该函数使用 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:_*))
}

但这里我卡住了有两个原因:

  1. 我不知道如何获取预计算值 ($value)
  2. 对于大小为 3、4、6、9 和 27 的数组,我需要这些函数中的几个。有没有办法干掉定义,或者我应该写 fill3, fill4fill6

有正确的方法吗?我该如何解决我的两个问题?

编辑:我意识到我最初的问题很愚蠢,因为在编译时必须知道大小......

最佳答案

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/

相关文章:

scala - 使用 Scala 转换 LabeledPoint 中 Vector 的 RDD - Apache Spark 中的 MLLib

c++ - C++ 错误代码样板的模板与宏

macros - Scheme (Kawa) - 如何在另一个宏中强制展开宏

c++ - C/C++ 预处理器中宽字符串文字的宏参数字符串化

c - 是否可以在字符串化宏之前处理数学计算?

斯卡拉 Spark : Performance issue renaming huge number of columns

scala - 为什么我的 'SparkSession'下面没有 'org.apache.spark.sql'

scala - 字符串差异作为列表

scala - 尝试使用 Scalatra 编译项目但失败

c++ - 定义宏错误 : expected primary-exception before 'asm'