它们(幂等函数和确定性函数)是否只是在给定相同输入的情况下返回相同结果的函数?
或者是否有我失踪的区别? (如果有区别,请你帮我理解它是什么)
答案 0 :(得分:8)
用更简单的术语来说:
幂等性并不意味着确定性(因为函数可以在第一次调用时改变状态而在后续调用中是幂等的),但是所有确定性函数本身都是幂等的(因为在调用之间没有内部状态持续存在)。
例如,在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声明GET
,HEAD
,PUT
和DELETE
是幂等的,但是{{ 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 。换句话说,这意味着具有相同的功效,但这显然并不意味着没有副作用,因此不确定其来源。 的经典示例在计算机科学中,只有两项困难的事情:缓存失效和命名。为什么他们不能只使用只读?哦,等等,他们想听起来更聪明吗?也许像圈复杂度 ?