为什么如此多的编程语言使函数可以修改作为参数传递给它的对象,而不需要某种语法来使调用者清楚。例如,考虑:
SomeObject A(15), B
B = DoSomething(A)
print(A + " " + B + "\n)
读取该代码时,您会希望输出类似于“15 75”,即A是您构造它的内容。但是,大多数语言都可以让DoSomething更改A的值。在C ++中,您可以通过查看DoSomething的声明来判断它是否可能,例如通过查看是否将参数定义为非const引用。然而,在许多语言中,例如Python,如果没有阅读函数的代码以确保它永远不会改变A,就没有办法说出来。
我曾经被一些人咬过,特别是在尝试使用其他人使用此行为的代码时,通常会逐行检查整个代码片段以尝试查找更改参数的内容。
为什么语言通常不需要一些明确的语法来调用“是的,这个对象可以修改”,例如说“B = DoSomething(inout A)”?
除了“永远不会修改传递给函数的参数”之外,是否有任何代码标准有助于防止出现问题?
答案 0 :(得分:1)
“编码标准”因语言和用户/团队而异。 C ++具有const-correctness,正确使用时将其视为编码标准。对于明显的情况,C#具有out
和ref
参数。我要说的是,在各种语言中唯一真正的一致性是参数修改应始终记录在函数的后置条件中。
答案 1 :(得分:1)
如果你看一下Java,一个方法不能真正改变参数(Java只有输入参数)。但是参数通常只是对某个对象的引用,这意味着该方法可以以任何可能的方式更改对象。这使得语义(不看文档)的推理很难,与函数编程完全相反。
你是对的,这是不可取的,但在短期内它使事情变得更容易。不幸的是,大多数情况下,短期内重要的是,所以我们仍在使用支持隐藏副作用的语言......
答案 2 :(得分:1)
我首选的设计模式是不可变数据类。
对于可变类,您必须考虑它是否被修改。
澄清一点,根据我的理解,Python就像Java和C(没有修饰符)一样通过值传递。但是你传递的东西通常是一个可变对象。
(编辑:现在几乎所有主流语言都遵循这些语义。最突出的例外是Lisp,您不仅可以修改可变对象,还可以重新分配变量指向的值。)
答案 3 :(得分:0)
这并没有直接使你的代码片段更清晰,但我想提一下:我们正在使用参数的命名约定来准确显示你想要的内容。我们使用'in','out'和'io'前缀。所以DoSomething声明看起来像DoSomething(ioSomeObject inA)。使用Visual Assist在Visual Studio中工作时,您将获得一个包含参数类型和名称的弹出窗口,并记录可能的副作用。在我看来,这比记录后置条件更清楚。
此致
Sebastiaan