不改变函数签名使参数变得懒惰?

时间:2016-03-31 13:51:30

标签: scala lazy-evaluation

假设:

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参数?

1 个答案:

答案 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;是一个宏(并且它不可能;宏可以实现抽象方法(当然也可以覆盖具体的方法))。