一些编程语言允许您更改作为参数传递给方法的对象。但这可能会导致其他使用该代码的程序员根本没有预料到的副作用。
这是JS中的一个例子
let hierarchy = []; // Массив объектов
let hierarchyStack = []; // Массив объектов
let endConnection = function(currentConnection) {
addConnToParent(currentConnection);
addToHierarchy(currentConnection);
addPointsToConnection (currentConnection);
};
let addToHierarchy = function(currentConnection) {
currentConnection = {'foo': 'bar'};
hierarchy.push(currentConnection);
};
let addConnectionToParent = function(currentConnection) {
let parentConn = hierarchyStack[hierarchyStack.length - 2];
// ... some code
parentConn.children.push(currentConnection); // children - массив объектов
};
let addPointsToConnection = function(connection) {
// ... some code
connection.points = schemaData.slice(2, 4); // points - массив объектов
};
在每个方法中,都修改了传递的对象。结果,在原来的方法中,经过三种方法,原来的阵列可能根本不像自己,被肢解得面目全非。
这是Java
class Test {
public int hello = 111;
}
//....
public static void main (String[] args) throws java.lang.Exception {
Test a = new Test();
System.out.println(a.hello);
changeObjectValue(a);
System.out.println(a.hello);
}
public static void changeObjectValue(Test b) {
changeObjectValue2(b);
}
public static void changeObjectValue2(Test c) {
changeObjectValue3(c);
}
public static void changeObjectValue3(Test d) {
d.hello= 888;
}
底线:通过所有这些方法,这个对象“浮出水面”发生了变化。并且在不同的类中可以有不止一种这样的方法。
如果在流类型方法中不使用这个对象,那么这样使用和编写方法是否正确?什么时候返回修改后的参数而不产生副作用是正确的?
在什么情况下你可以改变论点并且它会很方便?
不,这本身并不是坏习惯。关键是您和其他用户应该以一种明显的方式(最好从名称中)理解该功能究竟发生了什么变化。
例如,如果函数具有签名
那么很明显,这样的函数除了副作用之外不能做任何事情,它建立了一个连接,并且只需要改变它的参数。
如果函数看起来像一个纯函数,只从参数接收信息,并且只将结果作为返回值返回,那么它应该有相应的行为。例如,这里是加法函数:
(熟悉,嗯?)完全没用。
我建议不要混淆概念,并尝试制作这样的功能:
然而,这不是教条:例如,一个外在的纯函数可以在里面安排缓存。主要的是混合语义不应该是函数的公共契约。