副作用——这是什么?

34

请问在下面这句话中,“side effect”是什么意思?

如果您调用的EL函数没有返回任何内容,那么您只是为了产生它的副作用而调用它。


“side effect”指的是一个函数除了返回值外,对系统或者环境产生的其他影响,例如改变变量的值或者输出信息等。在上述引用中,如果EL函数没有返回任何内容,则它被称为具有“副作用”的函数,因为它的调用只是为了其产生的其他效果,而非返回值本身。
5个回答

66

副作用是指一个方法在计算并返回值以外所做的任何事情。改变实例或类字段的任何值都是副作用,如在屏幕上绘图、写入文件或网络连接。

严格来说,“函数”被定义为没有副作用 - 这就是为什么Java使用“方法”这个词。一个真正没有返回值的函数将是无意义的。

显然,一个没有返回值的方法必须具有某种副作用,以证明它的存在。设置方法就是其中的一种例子-副作用是改变对象的内部状态。


10
很好地描述了副作用,但是 - 这并不是Java使用“方法”这个词的原因。这不是为了良好的公关,而是因为“方法”是面向对象编程中的术语,在Java出现之前就已经存在了。 - Don Branson
10
我怀疑“方法”作为面向对象的术语之所以被创造出来,正是因为面向对象的本质在于将数据与改变数据的函数封装起来,因此这些函数并不是真正的函数。 - Michael Borgwardt

23

这意味着你不是在调用一个数学意义上的“真正”函数。这样的函数总是返回一个由其输入参数完全决定的值,没有需要修改的“状态”,也不会发生其他事情。这就是为什么从并行化角度来看,函数式编程很有趣;它使得更容易证明例如两个函数调用是独立的,可以并行运行。

请参阅维基百科关于纯函数的条目以获取更多详细信息。


这样的函数总是返回一个值,该值完全由其输入参数决定。这真的概括了它。关于函数式编程的观点很好。我会研究一下。 - Master Chief

3
一个副作用是当一个方法调用改变了一个类的状态。因此,
public class SideEffectClass{

    private int state = 0;


    public doSomething(int arg0){
        state += arg0;
    }
}

在此,doSomething(int arg0) 的副作用是改变状态变量。

当您考虑一个程序时,可以将它视为指令 + 状态 + 输入。因此,如果程序的域是所有可能的输入 * 状态的范围,并且程序具有副作用,您会发现应用程序可能的结果的值域会随着副作用数量的增加而爆炸性增长。这使得程序的可能状态很大,从而导致了复杂的测试。函数式编程范式旨在消除副作用。通过将函数视为第一类公民,并使所有声明不可变,函数式编程防止副作用,这使得函数式编程在并行处理中表现出色,因为同步问题得到减少。


1
副作用可以是除了上述更改类状态之外的其他事情。 - DJClayworth

3
当你使用药物时,其副作用通常是不希望出现的负面影响。使用它的主要目的是获得其“需求”的效果。在这里,当我们从功能的角度来看,通常当你调用它们时,你会得到一个计算出来的值并使用。还有其他一些函数在计算“需求”值时也会改变一些值,因此这里的“改变一些值”就是一个副作用。在你的句子描述中,如果一个函数没有返回任何东西,那么它仅被用于其副作用,因此这里的副作用是“改变一些值”。

0

让我们稍微修改上面给定的代码,以便更清晰地进行比较。

public class SideEffectClass{

    private int state = 0;

    public doSomething(...){//Does not matter
        state ++;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接