之间有什么区别
private void DoSomething(int value) {
value++;
}
和
private int DoSomething(int value) {
return value++;
}
用作
时DoSomething(value);
与
value = DoSomething(value);
答案 0 :(得分:44)
您所说的是通过引用传递和传递值之间的区别,这在概念上类似于值类型与引用类型的概念强>
如果您将值类型传递给方法,则必须使用第二个示例;否则你只是递增一个存在于DoSomething()范围内的整数。试一试:如果执行第一个例子,在运行DoSomething()之后,int的值将保持不变。
但是,如果您传递的不是值类型(例如对象foo),则实际上将引用传递给原始对象。你在DoSomething()中做的任何事情都会在方法之外生效,因为你仍然指的是同一个对象。
您可以通过编写以下内容来完成您在第一个示例中尝试的内容:
void DoSomething(ref int value)
指示.NET传递对项的引用,而不管它是否为值类型。
在MSDN上的 Value Types vs Reference Types 上查看此文章,了解更详细的信息。
此外,作为zodoz points out(适当地提升),通过返回value++
,您将返回然后递增。要返回递增的值,请使用++value
。
答案 1 :(得分:28)
返回一个值。
为什么?
正确性,可读性和自我文档
有意且易于理解的代码优于副作用代码。考虑:
float area = pi * Square(r);
VS
Square(r);
float area = pi * r;
// ... intervening code
float x = r * 5; // did you mean to use the original r or r-squared here?
在第一个例子中,还要考虑通过可组合性的简洁性的优点。
考虑方法本身,比较:
int DoSomething(int value)
{ return value+1; }
这显然是正确的。 VS
void DoSomething(int value)
{ value++; }
这似乎是正确的,并且编译得很好,但实际上只是一个无操作。你真正想要的是:
void DoSomething(ref int value)
{ value++; }
// client code:
DoSomething(ref a);
变量便宜
许多命名良好的变量优于少数重用的通用变量。抵制过早优化的诱惑,您需要减少局部变量的数量以提高系统性能的可能性非常小。 再次,变量便宜,不要重复使用变量!
<强>可测强>
考虑:
Assert.IsTrue(Square(2) == 4);
VS
float a = 2;
Square(a);
Assert.IsTrue(a == 4);
避免突变优先于返回值还有许多其他优点。数学将函数定义为输入值与输出值的映射不仅仅是偶然的。
答案 2 :(得分:6)
其他人似乎都在暗示变量传递的差异,但我发现了一些不同的东西:
如果您显示的示例代码是您正在查看的内容的简化,那么您可能需要在第二个示例中注意:
private int DoSomething(int value) {
return value++;
}
value
将返回然后增量。因此,如果您执行以下操作:
public Main() {
int val = 1;
Console.writeln(DoSomething(val));
}
您的输出将为1
。
让我知道这是否有帮助。
答案 3 :(得分:5)
只是第一个不起作用,因为你正在使用价值副本。
您可以执行类似
的操作private int DoSomething(ref int value)
{
value++;
}
并将其称为
DoSomething(ref value);
这会更改要通过引用传递的值。但实际上,唯一的理由就是如果你想从函数中返回多个东西。通常有更好的方法。
对于额外的奖励知识,还有out关键字与ref类似,但不需要首先初始化值。
答案 4 :(得分:2)
在第一个示例中,int参数value
递增,但在方法结束时被销毁,除非使用ref或{{3},否则无法获取方法外的值关键字。
例如:
private int DoSomething(ref int value) {
return value++;
}
// ...
int myValue = 5;
DoSomething(ref myValue);
// Now myValue is 6.
Ref和out参数传递模式用于允许方法更改方法调用者传入的变量。 ref和out之间的主要区别可能很微妙但很重要。
每个参数传递模式都旨在满足不同的编程需求。
采用 out 参数的方法的调用者不需要分配给在调用之前作为out参数传递的变量;但是,方法需要在返回之前分配给out参数。
考虑输出参数的一种方法是它们就像方法的附加返回值。当方法返回多个值时,它们很方便。
ref 参数会导致参数通过引用传递。结果是,当控制传递回调用方法时,方法中参数的任何更改都将反映在该变量中。
不要将引用传递的概念与引用类型的概念混淆。
这两个概念无关;一个方法参数可以通过ref修改,无论它是值类型还是引用类型,当通过引用传递时,没有值类型的装箱。
答案 5 :(得分:0)
对于大多数编程语言,您需要通过参数传递参数来更改void函数。函数通常不能改变其参数的值;相反,它会创建参数的副本并使用它。
为了使用实际变量,您必须更改函数标题以接受对变量的引用,并使用前面的&符号(&amp;),如下所示:
private void DoSomething(int &value)
希望有所帮助!
答案 6 :(得分:0)
由于您使用的是postfix ++,因此返回的值是该数字的原始值。此外,由于您传递的是数字的副本而不是数字本身(即通过引用),因此对值所做的更改不会影响您传递的变量。
所以这样的程序:
int value=1;
std::cout<<value<<std::endl;
value = DoSomething(value);
std::cout<<value<<std::endl;
DoSomething(value);
std::cout<<value<<std::endl;
输出如下:
1
1
1
如果您在返回时使用前缀++,或者如果您要在非返回函数中通过引用传递,则相同的程序将输出如下。
1
2
3
希望这会有所帮助。