java - 在我们可以调用它之前,一个函数到底必须遵守什么规则 "idempotent"?

标签 java language-agnostic idempotent

A post from another thread表示如果一个函数可以被多次调用而不改变结果,则该函数被称为幂等

然而,所使用的术语(如无副作用和返回相同结果)相对含糊不清。考虑这段代码:

public class test {

    int x = 0;
    java.util.Random r = new java.util.Random();

    public int F() {
        return x + 1;
    }

    public void F2() {
        x = r.nextInt();
    }
}

我们是否可以说 F() 是幂等的,因为对 F() 的连续调用返回相同的值?

或者它不是是幂等的,因为如果在其间调用 F2(),对 F() 的连续调用不会返回相同的值?

PS:“idempotent”在计算机科学而非数学中定义。

最佳答案

我不同意(实际上,我现在看到我同意他们!)与其他答案并说,在最常见的计算机科学用途(具有副作用的函数调用,而不是函数式编程)中,如果您可以安全地将函数的任何调用替换为调用函数两次并仅保留第二次结果,则该函数是幂等的。

例如,考虑两个按名称删除文件的函数:

1) 如果文件不存在则返回成功的函数。 (因为删除操作的目的是让文件不存在。)

2) 如果文件不存在则返回“文件不存在”错误的函数。 (因为无法删除文件。)

第一个是幂等的。如果你调用它并忽略结果,你可以再次调用它并仍然得到正确的信息。完成后文件不存在。

第二个不是幂等的。如果你调用一次并忽略结果,你的第二次调用将失败,让你认为你没有删除文件。

在此定义下,获取当前时间的函数是幂等的,即使结果可能不同。调用函数两次没有坏处。

这个概念在客户端-服务器协议(protocol)中很重要。假设你发送了一个命令但没有得到回复,可能是连接中断了,也可能是服务器崩溃了。所以你再次发送命令并得到回复。但是在第一个命令中,是命令丢失还是回复?如果命令是幂等的,那没关系。您可以直接使用结果。

如果协议(protocol)保证所有操作都是幂等的,较低级别的代码可以重试失败的操作、切换服务器,或者尝试在不破坏操作语义的情况下“让事情正常进行”。

创建幂等协议(protocol)需要做一些工作。例如,您可能想知道如何进行明智的“删除文件”操作。一种方法是为每个文件分配一个唯一的 ID,该 ID 在删除和重新创建文件时发生变化。然后将删除分成两半。第一个“从名称中获取 ID”是幂等的,如果文件不存在则失败。第二,“如果存在则删除 ID”是幂等的,如果您或其他任何人删除了该文件,它就会成功。 (一个怪癖是这并不能确定您是删除文件的人。)两个幂等操作的组合提供了所需的非幂等删除操作。

关于java - 在我们可以调用它之前,一个函数到底必须遵守什么规则 "idempotent"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9111602/

相关文章:

algorithm - 有哪些快速的熵计算算法

apache-kafka - Kafka 主题和微服务的多个实例

.net - 当类没有实现 IEnumerable 时,GetEnumerator 方法是否应该仍然是幂等的

java 8 ZonedDateTime 不打印 EST 当前时间。我在这里做错了什么

java - 要使用的工作流设计模式类型?

Java:BigInteger,如何通过OutputStream编写它

java - Hadoop上的运行字数统计

language-agnostic - 序列化持久/功能数据结构

syntax - BNF 中括号和大括号的用法?

rest - PUT POST 是幂等的 (REST)