满足此条件的函数是:
bool MyClass::is_initialized = false;
void MyClass::lazy_initialize()
{
if (!is_initialized)
{
initialize(); //Should not be called multiple times
is_initialized = true;
}
}
本质上,我可以多次调用此函数,不必担心会多次初始化
MyClass
不符合此条件的函数可能是:
Foo* MyClass::ptr = NULL;
void initialize()
{
ptr = new Foo();
}
多次调用
initialize()
会导致内存泄漏动机
一个简单的单词会很好描述此行为,以便可以适当地注释预期符合此条件的功能(在描述预期被覆盖的接口功能时特别有用)
#1 楼
这种类型的函数/运算称为幂等幂。幂等(英国:/ ˌɪdɛmˈpoʊtəns /,[1]美国:/ˌaɪdəm-/)[2]是某些数学运算的性质以及计算机科学,因此可以多次应用它们,而不会改变结果,超出了最初的应用范围。在数学中,这意味着如果f是幂等的,则f(f(x))= f(x),这与说f∘f= f相同。 />
在计算机科学中,这意味着如果
f(x);
是幂等的,则f(x);
与f(x); f(x);
相同。注意:这些含义似乎有所不同,但在状态的指称语义下,该词实际上,“幂等”在数学和计算机科学中具有相同的确切含义。
评论
评论不作进一步讨论;此对话已移至聊天。
– Maple_shaft♦
19年3月7日在15:23
#2 楼
确切的术语(如Woofas提到的)是幂等的。我想补充一点,尽管您可以将func1
方法称为幂等,但不能将其称为纯函数。纯函数的属性有两个:它必须是幂等的,并且必须没有副作用,也就是说,局部静态变量,非局部变量,可变引用参数或I / O流不会发生变异。 > 我之所以提到这一点,是因为具有副作用的幂等函数也不好,因为从技术上讲幂等是指函数的返回输出,而不是副作用。因此,从技术上讲,您的
func2
方法是幂等的,因为输出不会根据输入而改变。 您很可能希望指定要使用纯函数。一个纯函数的示例可能如下:
int func1(int var)
{
return var + 1;
}
更多阅读内容可以在维基百科文章“ Pure function”中找到。
评论
我认为您对幂等的定义太狭窄,或者换句话说,您使用的是幂等的数学定义,而不是编程方法。例如,精确地将PUT和DELETE HTTP方法称为等幂,因为多次执行它们的副作用与只执行一次具有相同的效果。您说的是“幂等性意味着f∘f= f”,而在编程中,我们的意思是“执行f与执行f; f具有相同的效果”。请注意,您可以通过添加“ world”参数轻松地将第二个含义转换为前一个含义。
–Jörg W Mittag
19年3月4日在8:28
@Neil“幂等性严格来说是一个数学术语。”不,不是,它也用于网络和客户端服务器通信/分布式系统中,正如JörgWMittag所描述的那样。这是一个有用的概念,因为它允许对具有相同操作/消息的服务器/客户端的多个请求,而无需更改原始消息的设置。当您的通信不可靠并且需要重试命令时,此功能很有用,因为客户端消息已丢失或服务器已回复。
– whn
19 Mar 4 '19 at 14:39
您应该更详细地了解纯和幂等之间的区别。您的示例func1不是幂等的,因为func1(1)!= func1(func1(1))。
–特斯拉
19 Mar 4 '19 at 20:29
纯度和幂等性不同。纯函数不必在数学意义上是幂等的(就副作用而言,它显然是幂等的,因为它没有副作用)。幂等(从编程意义上来说)功能不一定是纯函数,例如由OP给出的例子。同样,如opa所述,等幂是有用的特性,其用途与纯度完全不同。您对纯度的定义是“幂等且没有副作用”,这是错误的,或者至少是误导性的,令人讨厌。
–弗拉克斯
19 Mar 4 '19 at 22:55
在编程的上下文中,没有“副作用”,但是如果您要扩展定义以包括它,那么幂等函数和纯函数将具有相同的含义。不,它们根本不是同一件事。幂等,不是纯粹的:void f(int var){someGlobalVariable = var; }。纯而不是幂等的:int func1(int var){return var +1; }。
– JLRishe
19 Mar 5 '19 at 14:39
#3 楼
术语是幂等。下面请注意,幂等函数(递归调用其自身;第二个代码块和数学定义)与功能幂等性(在相同的输入下依次调用;第一个代码块,通常是编程中的术语)之间存在明显区别。具有副作用的函数f被认为在顺序组合f下是幂等的; f如果在使用相同的参数列表进行两次调用时,第二次调用没有副作用,并且返回的值与第一次调用相同[需要引用](假定在第一次调用的末尾与开始之间没有其他过程被调用)例如,请考虑以下Python代码:
x = 0
def setx(n):
global x
x = n
setx(5)
setx(5)
在这里, setx是幂等的,因为第二次调用setx(具有相同的参数)不会更改可见的程序状态:x在第一次调用中已经设置为5,在第二次调用中再次设置为5,因此保持相同的值。请注意,这与函数组合f∘f下的等幂是不同的。例如,在函数组成下,绝对值是幂等的:
def abs(n):
if n < 0:
return -n
else:
return n
abs(-5) == abs(abs(-5)) == abs(5) == 5
#4 楼
在物理学中,我听说过这称为投影:投影是从向量空间到其自身的线性变换P,使得P2 =P。也就是说,每当P为两次应用到任何值,其效果与一次应用(幂等)相同。
从图形上讲,如果看向量投影的卡通,这是有意义的:
图中a1是a到b的投影,就像您的函数的第一个应用一样。 a1在b上的后续投影给出了相同的结果a1。换句话说,当您反复调用投影时,它的效果与调用一次相同。
警告:我从来没有听说过在物理之外使用过,所以除非您有您团队中的这些类型,您可能会使所有人感到困惑。
评论
这确实是一个很好的具体示例,说明了如何可视化幂等函数(在数学上,尤其是在矢量几何/线性代数领域)。尽管软件功能的“幂等”是一个非常接近的概念,但我认为开发人员/计算机科学家通常不会在这种情况下使用“ projection”一词(软件工程中的“ projection function”宁可指代带有对象的功能)并返回派生自该对象的新对象或该对象的属性(例如)
– Pac0
19 Mar 4 '19在22:47
@ Pac0哦,好的。我从事的是科学和编程之间的工作,但没有意识到这个词已经超载了。我可以想到一些在工作中使用该术语的人为设计的示例,但是我承认我与愿意每天忍受科学术语的人们一起工作:-)
–user1717828
19-3-5在1:21
#5 楼
它是确定性算法,因为给定相同的输入(在这种情况下为无输入),它将始终产生相同的输出。在计算机科学中,确定性算法是一种算法,给定特定的输入,将始终产生相同的输出,而基础计算机始终通过相同的状态序列。确定性算法是迄今为止研究最多,最熟悉的一种算法,也是最实用的一种算法,因为它们可以在真实的机器上高效运行。
SQL数据库对确定性函数。
确定性函数在输入相同时总是给出相同的答案。 SQLite中的大多数内置SQL函数都是确定性的。例如,只要输入x相同,abs(X)函数就始终返回相同的答案。
如果函数用于计算索引,则该函数必须是确定性的。 br />
例如,在SQLite中,不能在索引中使用以下非确定性函数:
random()
,changes()
,last_insert_rowid()
和sqlite3_version()
。评论
询问者的func2是确定性的(不涉及随机效应),但已声明违反了他要寻找的属性。
– Draco18s不再信任SE
19 Mar 4 '19 at 22:17
通过重复产生相同的结果与说通过嵌套或链接产生相同的结果不同。确定性函数对于缓存结果非常重要,比索引/散列更重要。
–mckenzm
19 Mar 5 '19 at 5:59
#6 楼
除了其他答案,如果函数的特定输入具有此属性,则它是函数的不动点,不变点或不动点。例如,任何幂的1等于1,所以(1ⁿ)ⁿ=1ⁿ=1。产生自身作为输出的程序的特例是一个奎因。
评论
奎因对软件来说就像坎托对数学:-)一样。当然,quines不是幂等的-它们要么在输出已经存在时失败,要么“笨拙”先前的结果并编写一个新的尽管相同的输出。
–卡尔·威索夫特
19年3月6日在15:17
评论
对接近投票者:的确,所有“以物取物”问题中有99.999%(粗略估计)是题外话,因为它们没有单一,正确,明确,客观的答案,命名纯粹是主观的且基于观点的,这一点确实有一个单一的,正确的,明确的,客观的答案,这是由OP自己给出的。多次调用确实有效果,因为可能会有其他代码在两者之间更改'var'。
如果OP在问的时候知道答案,为什么要问这个问题?除了代表/积分/业力建设之外,还有其他原因吗?
@dotancohen Q / A风格的自我回答是StackExchange上的关键概念之一。
@glglgl:我同意,有优点的问题。这个问题有什么好处?我非常担心,我们将开始让OP询问并立即回答每个CS 101问题,由OP询问并立即定义每个CS术语,然后询问每个基本算法的利弊,然后由OP立即回答(不一定是这个OP)。那是我们希望SoftwareEngineering.SE成为的网站吗?