假设:
output.map{|h| h.each_pair.map{|k,v| [k.gsub(' ', '_'), v]}.to_h }
调用scala> def f(x: Int, y: Int): Int =
| if(x == 55) x else y
f: (x: Int, y: Int)Int
scala> def yFn: Int = {println("y"); 42}
yFn: Int
会产生f(55, yFn)
的评估,由f
打印输出显示。
y
scala> f(55, yFn)
y
res0: Int = 55
的签名如何保持不变:
f
但是(Int, Int) => Int
懒得评估而不使y
成为y
参数?
答案 0 :(得分:2)
将[[NSUserDefaults standardUserDefaults] setObject:@(score) forKey:@"score"];
[[NSUserDefaults standardUserDefaults] synchronize];
转换为宏将有效地执行您想要的操作:
f
import language.experimental.macros
import scala.reflect.macros.whitebox.Context
object Macros {
def f(x: Int, y: Int): Int = macro fImpl
def fImpl(c: Context)(x: c.Expr[Int], y: c.Expr[Int]): c.Expr[Int] = {
import c.universe._
c.Expr(q"if ($x == 55) $x else $y")
}
}
的签名有f
,而不是Int
,但来电=> Int
只会被f(55, yFn)
取代,而if (55 == 55) 55 else yFn
则不会评估yFn
。
通过这个,您可以看到任何宏,它不会查看其参数'结构有效地取代了它们;如果你想确保一个参数只被评估一次,你需要将它分配给一个局部变量:q"{ val x = $x; if (x == 55) x else $y }"
。
但是,如果要将f
转换为对象而不是方法,则会丢失,因为生成的类的apply
方法赢了&# 39;是一个宏(并且它不可能;宏可以实现抽象方法(当然也可以覆盖具体的方法))。