我们注意到Java 8使用了参照透明性:
我测试了许多代码来检测此RT,例如:
public class ReferentialTransparency {
public static int triple(int number) {
System.out.println(number);
try {
Thread.sleep(500);
} catch (Exception e) {
}
return number* 3;
}
public static void main(String[] args) {
List<Integer> vals=Arrays.asList(1,2,3,4,3);
System.out.println(vals.parallelStream()
.mapToInt(ReferentialTransparency::triple)
.sum());
}
}
安慰 :
3
4
2
1
3
39
我注意到Java 8运行三重方法,即使有一个元素出现了两次,也就是3
。
正如Istvan所解释的,我的问题是:
如果三重引用是透明的,为什么编译器不优化对三重(3)的重复调用?
您的triple
方法不是参照透明的,因为它既可以向控制台输出内容,也可以进入休眠状态。这些操作都不是参照透明的。实际上,很难(从您的代码中)检测编译器是否优化了对参照透明函数的调用,因为如果添加了一条print语句来检测它,那么根据定义,您的函数将不再是参照透明的。
请注意,在您提供给referential-transparency的链接中,给定的引用透明性的定义为
函数的一种属性,通过该表达式可以将表达式替换为其(求值的)值,而不会影响程序的含义。
您可以说这triple
不是参照透明的,因为对eg的调用triple(2)
不等同于6
,因为仅仅求值6
不会打印任何内容或休眠,而triple(2)
也会在控制台上输出2并休眠一秒钟。由于替换triple(2)
通过6
将通过移除印刷和睡眠影响程序的意思,triple
不是引用透明。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句