PHP变量是通过值还是通过引用传递的?
我正在寻找一个清晰,简洁和准确的答案.
理想情况下,作为实际答案,虽然欢迎链接到良好的解释.
这也适用于VB.Net,但关键字是不同的 - ByRef和ByVal.
谁有权决定?
编辑:显然我没有成功地完善我的问题.
我不是在问Java的论证是如何传递的.我知道看起来像持有对象的变量实际上是一个包含对象引用的变量,并且该引用是按值传递的.这里有很多很好的解释(在链接的线程和其他线程中)和其他地方.
问题是关于术语传递的技术含义.(结束编辑)
我不确定这是否是SO的正确问题,如果没有道歉,但我不知道更好的地方.在这里的其他问题中已经说了很多,例如Java是"传递参考"还是"传递价值"?并通过引用或通过值传递?,但我没有找到该术语含义的权威答案.
我认为"通过引用传递"意味着"将引用(通常是指针)传递给对象",因此被调用者可以修改调用者看到的对象,而"按值传递"意味着复制对象,并让被调用者玩得开心(显而易见的问题:如果对象包含引用,深层复制或浅层).
唱FW变成了很多 的 地方 说: "按引用传递"的意思只是说,这里有一些说法,这意味着更多的,但仍然定义读
一种ParameterPassing模式,其中将实际参数的引用(或者如果你想在政治上不正确,指针)传递给形式参数; 当被调用者需要形式参数时,它取消引用指针以获取它.
我没有发现许多地方给出了更强的术语定义,在这个页面上,我发现"形式参数的左值设置为实际参数的左值".并且,如果我理解正确,这里使用相同的定义("形式参数仅作为实际参数的别名.")
事实上,我发现使用更强定义的唯一地方是反对这样一种观点,即在Java中,对象是通过引用传递的(这可能是由于我缺乏google-fu).
所以,如果我把事情弄清楚,那就是通过参考传递
class Thing { ... }
void byReference(Thing object){ ... }
Thing something;
byReference(something);
Run Code Online (Sandbox Code Playgroud)
根据第一个定义大致对应(在C中)
struct RawThing { ... };
typedef RawThing *Thing;
void byReference(Thing object){
// do something
}
// ...
struct RawThing whatever = blah();
Thing something = &whatever;
byReference(something); // pass whatever by reference …Run Code Online (Sandbox Code Playgroud) 考虑到在Ruby编程语言中,一切都被称为对象,我安全地假设将参数传递给方法是通过引用完成的.然而,下面这个小例子让我困惑:
$string = "String"
def changer(s)
s = 1
end
changer($string)
puts $string.class
String
=> nil
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,原始对象未被修改,我希望知道为什么,以及如何实现所需的行为,即.获取方法实际更改其参数引用的对象.
我是Java的新手(多年来一直在写其他东西),除非我遗漏了一些东西(我很高兴在这里错了)以下是一个致命的缺陷......
String foo = new String();
thisDoesntWork(foo);
System.out.println(foo);//this prints nothing
public static void thisDoesntWork(String foo){
foo = "howdy";
}
Run Code Online (Sandbox Code Playgroud)
现在,我很清楚(相当差的措辞)概念,在java中,一切都是通过"值"而不是"引用"传递的,但String是一个对象,有各种各样的花里胡哨,所以,人们会期待与int不同,用户可以对传递给方法的东西进行操作(并且不会被overloaded =设置的值所困).
有人可以向我解释这个设计选择背后的原因是什么?正如我所说,我不是想在这里,也许我错过了一些明显的东西?
可能重复:
通过引用传递或通过值传递?
在C++中通过引用/值传递
我遇到了pass-by-value-result方法的问题.我理解通过引用传递和传递值,但我不太清楚传值值的结果.通过值有多相似(假设它是相似的)?
这是代码
#include <iostream>
#include <string.h>
using namespace std;
void swap(int a, int b)
{
int temp;
temp = a;
a = b;
b = temp;
}
int main()
{
int value = 2;
int list[5] = {1, 3, 5, 7, 9};
swap(value, list[0]);
cout << value << " " << list[0] << endl;
swap(list[0], list[1]);
cout << list[0] << " " << list[1] << endl;
swap(value, list[value]);
cout << value << " " << list[value] << …Run Code Online (Sandbox Code Playgroud) 不熟悉c#我在不同线程之间传递SqlDataReader时遇到了这个"难题".在没有太多细节的情况下,我们的想法是让一个主线程从数据库中获取数据(一个大的记录集),然后让一个帮助程序任务按记录运行这个记录并根据这个内容做一些事情.没有对记录集的反馈,它只是等待直到没有记录.这工作正常,但考虑到手头工作的性质,应该可以将这个工作分布在不同的线程(CPU)上以最大化吞吐量(执行顺序没有意义).那么问题就变成了,当我在SqlDataReader中传递这个记录集时,我是否必须使用ref?这有点归结为一个问题:如果我在没有指定ref的情况下传递对象,那么'赢了' 它在内存中创建新副本并处理n次记录?或者,我不是冒险将记录位置向前移动而不是所有字段都已完全读取了吗?后者似乎更像是一个"数据竞争"问题,可能是由lock()机制所覆盖(或不是?).
我对这个问题的初步看法是,它并没有真正伤害使用ref传递变量,但正如一位同事所说的那样:"当你做错事时你只需要参考"=)另外使用ref限制我应用一个使用()结构也不是很好.因此,我创建了一个"基本"项目,解决了相同的方法,但没有引用.到目前为止的测试表明,它使用任意数量的线程在Core2Duo(2cpu)上完美运行,但我仍然有点谨慎......你有什么专家对此的看法?是否使用ref?
你可以在这里找到测试项目,因为我似乎无法直接将它上传到这个问题?!?
ps:它只是一个测试项目而且我是c#的新手,所以在打破代码时请对我保持温和= P
我认为当你将对象传递给Java中的方法时,它们应该是有价值的.
这是我的代码:
public class MyClass{
int mRows;
int mCols;
Tile mTiles[][]; //Custom class
//Constructor
public MyClass(Tile[][] tiles, int rows, int cols) {
mRows = rows;
mCols = cols;
mTiles = new Tile[mRows][mCols];
for (int i=0; i < mRows; i++) {
for (int j=0; j < mCols; j++) {
mTiles[i][j] = new Tile();
mTiles[i][j] = tiles[i][j];
}
}
}
Run Code Online (Sandbox Code Playgroud)
此时,mTiles对象的任何更改都会反映回tiles对象.任何想法如何解决这一问题?
谢谢大家.
我有两个代码片段:
第一
class PassByTest{
public static void main(String... args){
PassByTest pbt=new PassByTest();
int x=10;
System.out.println("x= "+x);
pbt.incr(x);//x is passed for increment
System.out.println("x= "+x);//x is unaffected
}
public void incr(int x){
x+=1;
}
}
Run Code Online (Sandbox Code Playgroud)
在此代码中,值x不受影响.
第二
import java.io.*;
class PassByteTest{
public static void main(String...args) throws IOException{
FileInputStream fis=new FileInputStream(args[0]);
byte[] b=new byte[fis.available()];
fis.read(b);//how all the content is available in this byte[]?
for(int i=0;i<b.length;i++){
System.out.print((char)b[i]+"");
if(b[i]==32)
System.out.println();
}
}
}
Run Code Online (Sandbox Code Playgroud)
在这里,文件的所有内容都可以在byte[] b.
怎么样,为什么?