幂等元和确定性函数之间有什么区别?

时间:2016-10-28 00:29:23

标签: deterministic idempotent

它们(幂等函数和确定性函数)是否只是在给定相同输入的情况下返回相同结果的函数?

或者是否有我失踪的区别? (如果有区别,请你帮我理解它是什么)

3 个答案:

答案 0 :(得分:8)

用更简单的术语来说:

  • 确定性函数:输出完全且仅基于输入值而不是其他内容:没有其他(隐藏)输入或状态依赖于生成其输出。< / LI>
  • Idempotency :实际的定义是你可以安全地多次调用同一个函数,而不用担心负面的副作用。更正式地说:后续相同的呼叫之间没有状态的变化

幂等性并不意味着确定性(因为函数可以在第一次调用时改变状态而在后续调用中是幂等的),但是所有确定性函数本身都是幂等的(因为在调用之间没有内部状态持续存在)。

确定性

例如,在SQL UCASE(val)或C#/ .NET String.IndexOf中都是确定性的,因为输出仅取决于输入。请注意,在实例方法(例如IndexOf)中,实例对象(即隐藏的this参数)计为输入,即使它是“隐藏”的:

"foo".IndexOf("o") == 1 // first cal
"foo".IndexOf("o") == 1 // second call
// the third call will also be == 1

然而在SQL NOW()或C#/ .NET DateTime.UtcNow中不确定,因为即使输入保持不变,输出也会发生变化(请注意,.NET中的属性getter等同于除了隐式this参数外,不接受任何参数:

 DateTime.UtcNow == 2016-10-27 18:10:01 // first call
 DateTime.UtcNow == 2016-10-27 18:10:02 // second call

幂等性

.NET中的一个很好的例子是Dispose()方法:请参阅Should IDisposable.Dispose() implementations be idempotent?

  

Dispose方法应该可以多次调用而不会抛出异常。

因此,如果父组件X初次调用foo.Dispose(),那么它将调用处理操作,X现在可以考虑处置foo。执行/控制然后传递给另一个组件Y,然后在foo调用Y之后尝试处理foo.Dispose(),它也可以预期foo被处置(它是),即使X已经处理它。这意味着Y无需检查是否已经处置foo,从而节省了开发人员的时间 - 并且还消除了第二次调用Dispose可能引发异常的错误,例如

另一个(一般)示例在REST中:HTTP1.1的RFC声明GETHEADPUTDELETE是幂等的,但是{{ 1}}不是(https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

  

方法也可以具有“幂等性”的特性(除了错误或期满问题之外)N的副作用> 0个相同的请求与单个请求相同。方法GET,HEAD,PUT和DELETE共享此属性。此外,方法OPTIONS和TRACE不应该有副作用,因此本质上是幂等的。

因此,如果您使用POST,那么:

DELETE

所以你在上面的例子中看到Client->Server: DELETE /foo/bar // `foo/bar` is now deleted Server->Client: 200 OK Client->Server DELETE /foo/bar // foo/bar` is already deleted, so there's nothing to do, but inform the client that foo/bar doesn't exist Server->Client: 404 Not Found // the client asks again: Client->Server: DELETE /foo/bar // foo/bar` is already deleted, so there's nothing to do, but inform the client that foo/bar doesn't exist Server->Client: 404 Not Found 是幂等的,因为服务器的状态在最后两个DELETE请求之间没有变化,但它不是确定性的,因为服务器返回了{{ 1}}表示第一个请求,DELETE表示第二个请求。

答案 1 :(得分:7)

确定性函数只是数学意义上的一个函数。给定相同的输入,您总是得到相同的输出。另一方面,幂等函数是满足身份的函数

f(f(x)) = f(x) 

作为一个简单的例子。如果UCase()是将字符串转换为大写字符串的函数,那么显然UCase(Ucase(s)) = UCase(s)

幂等函数是所有函数的子集。

答案 2 :(得分:3)

确定性函数将为相同的输入返回相同的结果,而不管您调用它多少次。

幂等函数可能不会返回相同的结果(它将以相同的形式返回结果,但值可能不同,请参见下面的http示例)。仅保证它不会有副作用。换句话说,它不会改变任何东西。

例如,GET动词在HTTP协议中是幂等的。如果您呼叫“〜/ employees / 1”,它将以特定格式返回ID为1的员工的信息。它不应更改任何内容,而只是返回员工信息。如果您将其命名为10、100左右,则返回的格式将始终相同。但是,它决不是确定性的。也许如果您第二次调用它,则员工信息已更改,或者甚至不再存在。但绝不应该有副作用或以其他格式返回结果。

我的意见

幂等词很奇怪,但是知道其起源可能会非常有帮助, idem 意为 same ,而 potent 意为 power 。换句话说,这意味着具有相同的功效,但这显然并不意味着没有副作用,因此不确定其来源。 的经典示例在计算机科学中,只有两项困难的事情:缓存失效和命名。为什么他们不能只使用只读?哦,等等,他们想听起来更聪明吗?也许像圈复杂度