最近在学scala的时候,函数传参可以是传名参数,或者传值参数

1.Scala中的传名参数是什么意思?lazy关键字有什么作用?

Scala官方文档的定义是:传名参数 仅在被使用时触发实际参数的求值运算。 它们与 传值参数 正好相反。 要将一个参数变为传名参数,只需在它的类型前加上 =>。

def calculate(input: => Int) = input * 37

测试输出

  def main(args: Array[String]): Unit = {

    def input(): Int ={
println("Initialized")
1
}
lazy val i = input();
println("begin for loop")
for( a <- 1 to 3){ val cal = calculate(i)
println("cal:" + cal)
} }

output:

begin for loop
Initialized
cal:37
cal:37
cal:37

可以看到Initialized是在begin for loop后面打印出来,而且可以看到Initialized在三次循环调用中,只输出了一次,这是因为有缓存的,只会在第一次使用的时候进行初始化。

2.在Java中如何实现类似的功能?

其实单纯的惰性求值,是很好实现的,可以通过Java 8 中的 functional interface Supply来传递参数。

    public static Integer calculate(Supplier<Integer> s) {
return s.get() * 37;
} public static void main(String[] args) { Supplier<Integer> input = () -> {
System.out.println("Initialized");
return 1;
}; System.out.println("begin for loop");
for (int i = 0; i < 3; i++) {
Integer cal = calculate(input);
System.out.println("cal:" + cal);
} }

output:

begin for loop
Initialized
cal:37
Initialized
cal:37
Initialized
cal:37

可以看到虽然实现了惰性求值,但是每次调用的时候supplier都会去计算一遍,这个时候可以用guava提供的MemoizingSupplier

    public static Integer calculate(Supplier<Integer> s) {
return s.get() * 37;
} public static void main(String[] args) { //这里返回的其实是MemoizingSupplier
com.google.common.base.Supplier<Integer> input = Suppliers.memoize(() -> {
System.out.println("Initialized");
return 1;
}); System.out.println("begin for loop");
for (int i = 0; i < 3; i++) {
Integer cal = calculate(input);
System.out.println("cal:" + cal);
}
}

output:

begin for loop
Initialized
cal:37
cal:37
cal:37

通过输出可以看到,实现的效果和scala是一样的,做到了惰性求值,且有缓存,只会被执行一次。

最新文章

  1. Java集合类学习笔记(Set集合)
  2. Effective Java 阅读笔记——并发
  3. postfix删除队列中的邮件
  4. myeclipse关闭properties文件自动转义
  5. Cocos2d-x中播放背景音乐
  6. Oracle Form属性、内置子程序、触发器、系统变量简要
  7. 【转】android JNI
  8. 历届试题 剪格子 IDA*
  9. erlang的脚本执行---escript
  10. Spark集群的任务提交执行流程
  11. python第五十三课——time模块
  12. Codeforces 382 D Permutations
  13. Android JAR包、Library项目
  14. vue中使用promise
  15. Selenium基础知识(八)文本域处理textarea
  16. jquery的load()事件和ajax中load()方法的区别
  17. Linux 如何将一个文件夹的所有内容授权给某一个用户
  18. ORACLE学习文档
  19. Mirror--程序访问镜像数据库的超时机制
  20. iptable filter nat MASQUERADE snat dat

热门文章

  1. Vue mixin混入的介绍
  2. Windows 干净启动
  3. 【redis】配置优化及从库优先级
  4. lg9018题解
  5. Java虚拟机中 -XX:+PrintFlagsFinal与XX:+PrintCommandLineFlags 中MaxHeapSize的值不同的原因
  6. SAP FBL1N屏幕增强,增加自定义的列
  7. linux下yum安装时出现Loaded plugins: fastestmirror
  8. springboot集成xxl-job问题
  9. 靶场练习2:cloudantvirus
  10. Linuxt通过命令lsof或者extundelete工具恢复误删除的文件或者目录