纯方法必须是静态的吗?

2022-09-01 13:47:07

我目前正在阅读一本教科书,它将纯方法定义为:

“一种静态方法,仅依赖于其参数而不依赖于其他数据”

难道不可能让实例方法成为纯方法而不是静态的(只要它不修改参数并且没有像打印那样的“副作用”)?

我知道对于纯方法来说,返回值仅取决于参数而不是任何其他状态,因此,也许实例方法的调用方式意味着从调用该方法的对象中获取的变量不算作参数,而是作为另一个“状态”?

除此之外,我想不出任何理由为什么非静态方法不能成为纯方法。

下面是一个示例:

public class Rational {

    private int numer;
    private int denom;

    public Rational() {
        this.numer = 0;
        this.denom = 1;
    }

    public Rational(int numer, int denom) {
        this.numer = numer;
        this.denom = denom;
    }
}

上面定义了一个类Rational

然后,您可以在类中编写一个方法,该方法通过下面的“方法一”或“方法二”将对象作为返回。RationalRationaldouble

方法一:

public double toDouble() {
    double x = this.numer;
    double y = this.denom;
    double fprat = x / y;
    return fprat;
}   

方法二:

public static double toDouble(Rational rational)
{
    double x = rational.numer;
    double y = rational.denom;
    double fprat = x / y;
    return fprat;
} 

它们本质上做完全相同的事情,但一个是静态方法,另一个是实例方法,因此它们的调用将采用不同的格式。方法二当然是纯方法,但在这种情况下,非静态方法一是否也被定义为纯方法?


答案 1

该定义的“静态”部分是多余的。静态方法并不能保证它不依赖于任何其他状态。我怀疑该定义只是想确保该方法不使用实例变量。

另一方面,从技术上讲,您也可以将实例方法视为具有第0个参数(对象本身)的静态方法。如果该对象是不可变的(或者该方法不会更改对象中的任何内容),则可以认为该方法仍然是纯的。基本上,您将“对象”视为附加参数。

例如,Java中的方法引用可以以这种方式运行,使第一个参数成为调用方法的对象本身。


答案 2

纯方法也可以是静态的根据维基百科,纯方法的两个标准是:

  1. 该函数始终在给定相同参数值的情况下计算相同的结果值。函数结果值不能依赖于在程序执行过程中或在程序的不同执行之间可能更改的任何隐藏信息或状态,也不能依赖于来自 I/O 设备的任何外部输入。

  2. 结果的评估不会导致任何语义上可观察的副作用或输出,例如可变对象的突变或输出到I / O设备。

(强调我的)

没有理由不能将这应用于非静态方法。使该方法成为静态方法将为调用方提供更强的保证,即没有使用实例状态,因此最好将其设置为静态。


根据您的观点,可以将实例方法视为只是一个采用额外隐式参数的函数:实例本身。通过这种方式,非静态方法可以依赖于实例状态并被视为纯方法,前提是它不依赖于任何外部状态(单例等)或产生副作用。罗伯特的回答说得好。这取决于解释,但我个人的意见是,这种方法将是纯粹的。

Voo在评论中很好地表达了这一点:

为什么隐藏的此指针应该被视为比函数的任何其他参数更特殊?这个论点导致了一个矛盾:假设
它是纯的,显然同构
也是纯的。public static int pureFunc(MyInstance self)public int pureFunc()


推荐