用于描述修改其调用对象的功能/方法的术语是什么?


12

对不起,通用问题。我到处搜索,发现了很多此类似的线程,但是没有一个可以回答我的特定问题-也许是因为我要查找的术语甚至不存在。

我的一个朋友正在学习编程,特别是JavaScript,他问我为什么这样做不起作用:

var a = "Hello World";
a.replace("Hello", "Goodbye");

console.log(a)  // Logs "Hello World"

原因是因为replace不修改a,因为字符串在JavaSript中是不可变的。因为它返回一个字符串,所以您需要执行以下操作...

var a = "Hello World";
a = a.replace("Hello", "Goodbye");

console.log(a);  // Logs "Goodbye World"

但是,替代方法是类似JavaScript的函数reverse(),因为它会修改任何调用它的函数。例如:

var fruits = ["Apples", "Oranges", "Bananas"];
fruits.reverse();

console.log(fruits)  // ["Bananas", "Oranges", "Apples"]

当我的朋友问我为什么他replace不工作时,我意识到我在说一个我不知道的词(据我所知)...

“您必须将字符串设置为“字符串点替换”,因为替换功能是________。”

您无需将数组设置为等于“数组点反向”,因为反向是________。

我不熟悉原型函数,但我不相信这是我要找的单词。谁能帮我填补这些空白?


6
也许这个词是“变种人”?如:中You don't need to set an array equal to "array dot reverse", because reverse is a mutator function。我我已经听说过该术语指代“变异”调用它们的实例的函数。但是您可能应该在其他地方再次检查。
FrustratedWithFormsDesigner

赞赏!我只是读了一些关于Mutator Methods的文章,我认为它确实很适合本次对话。当然在我要寻找的领域。
桑迪

我很困惑:在标题,你问一个函数修改调用它,但在你的例子,你表明修改他们被称为对象方法的对象,即标题正好相反。这是哪两个呢?
约尔格W¯¯米塔格

可以肯定的是,它用30行详细说明了。我会修改标题以使其准确无误,谢谢大家的注意!
桑蒂

Answers:


12

您要寻找的一对概念是可变/不可变的参数以及就地/返回结果。

在您的示例中:

您必须将字符串设置为“字符串点替换”,因为replace函数对在python中不可变的字符串进行操作,因此replace函数返回新的字符串。

对于C / C ++程序员而言,这更熟悉,因为参数“通过值传递”而不是“通过引用传递”,这使它们不可变并返回结果。

您不需要将数组设置为等于“ array dot reverse”,因为反向操作是可变的数组,因此可以在返回之前就地进行更改。

在诸如C / C ++之类的语言中,这称为参数“通过引用传递”,即传递地址,如果未经修改const,则允许函数更改,变异该地址的内容,从而在返回之前就地改变结果。

当然,具有通过两种机制返回结果的函数并不罕见,例如,int SomeFn(int p1, int p2, int *ErrCode)可以在返回值和修改的内容中潜在地返回结果ErrCode

第三种方法

为了完整起见,返回结果的第三种机制是副作用全局机制,即修改文件范围,程序范围,共享或环境值。这通常被视为坏消息,因为除非有充分的记录,否则您只有通过仔细阅读代码才能找出正在更改的内容。在诸如C / C ++之类的语言中,通过使用具有给定名称的外部范围变量(甚至可能在另一个模块中)并且不掩盖相同名称的局部范围变量,也是如此容易做到。在Python中,虽然您可以读取外部作用域中的值的值,但除非将外部作用域值显式设置为可用于使用global 关键字,尝试修改外部作用域变量会自动创建相同名称的本地。


嗯,尽管我不确定是否有一个实际的词来描述函数本身,但我对这些术语很熟悉。就像,(The reverse function is a _______ function.)话虽如此,这与我最终给我的朋友的回答几乎是相同的,因此,感谢您的确认-尽管我仍然想知道是否有特定的用语。我将让这个问题开放一段时间,但是如果这些词根本不存在,我肯定会接受这个作为答案。
桑蒂

2
在某些语言(例如python)中,您还可以具有可自行修改的类-在某些情况下,这种“猴子修补”在许多情况下被认为是一件好事,因此被视为“自我修改代码”,因此被禁止。您还可以使用“进化代码”,其中代码片段被随机地“突变”和/或组合,然后以某种方式被测试并选择为“最佳”性能。
史蒂夫·巴恩斯

-1。字符串是可变的还是不可变的与在其上操作的函数无关。该函数不是可变的或不变的,也不是“返回或就地”。函数可以修改其参数,并且仍然返回。
Miles Rout

@MilesRout补充说,仍在修改的函数仍会返回,并且一些C / C ++示例为清楚起见,并附带了副作用以确保完整性。
史蒂夫·巴恩斯

4

我首选的表达方式是:

  • Array reverse方法正在变异。这是一个变种人。常见的特殊情况是二传手

  • String replace方法是不可变的。它不是变种人。如果不修改任何东西,它的无副作用。常见的特殊情况是吸气剂

  • 由于JavaScript字符串是不可变的,因此String方法不能进行突变。

    “ Hello World” .replace(“ Hello”,“再见”);

    应该让你不舒服。它不会修改字符串文字。它丢弃结果。静态代码分析器有时可以检测到此类错误。

  • 由于JavaScript数组是可变的,因此Array方法可以进行变异。JavaScript倾向于将Arrays用作本地存储箱,易于修改且很少复制。

2

有时,在纯函数式编程中使用时,我听说过一些函数会修改输入值(因此不是纯函数),称为destructive。不过,我不确定这是否正确。

就您而言,您会说:

您必须将字符串设置为“字符串点替换”,因为替换功能不是破坏性的

您不需要将数组设置为等于“ array dot reverse”,因为reverse是破坏性的


1

您所寻找的单词也许纯粹是?

replace()是纯净的(或看起来是纯净的),因为它看起来没有任何副作用(即,修改字符串),而reverse()纯净的是因为它会更改数组的状态。


这是一个相关的概念,但也包含其他属性(例如,不访问全局状态,并且对于相同的输入始终产生相同的输出)。
雅各布·赖勒

1

这些通常会分为功能和方法(其中方法是功能的子集)。函数是可以单独调用的代码部分,而方法具有在其上操作的当前“上下文”的概念。方法的操作会更改其上下文的状态。

在面向对象的编程中,上下文是函数在其上进行操作的实例。


0

我不知道有一个正式的答案,但是您可能想要两个。

程序

仅仅是因为这看起来像是对这个问题的好答案,但看起来很像您的问题,顺便说一句,您应该检查一下。

原地一元运算

查看此页面:java.util.function。它为各种原型的委托人(输入/输出签名)提供一种虚构的名称,例如,接受参数但不返回任何内容的委托人称为使用者

现在,作为一个精通OOP的学生,您应该意识到,方法只是一个带有隐藏参数this)的函数。由于它是作为参考提供的,因此它既可以用作输入参数,也可以用作输出参数。

根据这些Java专家(他们看起来很聪明)的说法,接受单个输入并返回相同类型值的委托称为一元运算符

现在,在的情况下array::Reverse(),数组不是不可变的,并且可能会占用大量空间,因此就地执行操作会更加高效和便捷。因此Reverse()就地一元运算符

但是对我来说,“运算符”是一个特殊符号(例如加法运算符,也称为+)或数学关键字,例如mod。因此,我更愿意称它为OPERAT 离子,产生就地一元运算


您正在混淆概念。Reverse()是不是一个操作符,一元运算符不必返回相同类型的值(例如!deletetypeof),和运营商不委托。但是“就地”是修改其实例的方法的好术语。[我没有拒绝投票,但似乎有人拒绝了所有答案,即使它们都很有用。]
Jerry101,2017年

不确定您正在关注。任何原型都可以由委托代表。“运算符”对我不起作用(如我所说),所以我说“运算符”,是的,确实Reverse()是一元运算。但是总的来说,我同意这有点奇怪,但是我在逐字使用链接文档中的术语,该文档似乎是由一些非常聪明的人编写的。至少它总比没有好。
约翰·吴

原来如此!请注意,为了将lambda改造为Java,它们基于功能接口(只有一种方法的Java接口)的思想,因此我们可以传递普通的Java对象以用作“功能”。(Brian Goetz进行了有关添加lambda的技术讲座。他多次说“显而易见的方法会烂透了。”)在创建用于流处理对象的功能接口时,它们会滥用诸如“运算符”之类的术语。太混乱了!他们一定没有好名声。我认为这不是修改/不修改接收者对象的OOP方法的良好术语来源。
Jerry101 '17
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.