我试图理解通过引用传递。这可能是一个不好的类比,但它像牛顿第三定律(动作-反应对)吗?
例如,对于以下代码
$a = 4;
$b = 2;
$n = 42;
$a = &$b;
是
$a=$n
一样$b=$n
吗?$a
和的值不是$b
存放在同一个地址吗?
我试图理解通过引用传递。这可能是一个不好的类比,但它像牛顿第三定律(动作-反应对)吗?
例如,对于以下代码
$a = 4;
$b = 2;
$n = 42;
$a = &$b;
是
$a=$n
一样$b=$n
吗?$a
和的值不是$b
存放在同一个地址吗?
如果您正常分配这些变量:
$a = 1;
$b = 2;
$c = 3;
然后关联将如下所示:
a --> 1
b --> 2
c --> 3
现在,如果您$c
引用$a
,如下所示:
$a = 1;
$b = 2;
$c = &$a;
然后关联将如下所示:
a --> 1 <--.
b --> 2 |
c --------/
换句话说,$a
和$c
指向相同的值。因为它们都指向同一个值,我们可以更改其中任何一个变量,它们都将指向新值。
$a = 5;
echo "$a $c"; // Output: "5 5"
$c = 10;
echo "$a $c"; // Output: "10 10"
是的,分配$n
给后$a
,$b
会点$n
。
这是因为在两者都执行后,并引用了同一个内存位置,变成了引用变量()$a=&$b
$a
$b
is_ref=1
。并且该特定内存位置的引用计数 ( refcount
) 增加1
. 现在,您分配给任何这些引用的任何值都将指向相同的值。
执行$a=$n
意味着的值$n
将存储到 引用的位置$a
。这是与 相同的位置$b
。
请参阅此处的示例。
$a
, $b
,$n
指向不同的位置
php > $a = 4;
php > $b = 2;
php > xdebug_debug_zval('a'); // they are pointing different location
a: (refcount=1, is_ref=0)=int(4)
php > xdebug_debug_zval('b'); // they are pointing different location
b: (refcount=1, is_ref=0)=int(2)
php > $n = 42;
php > xdebug_debug_zval('n');
n: (refcount=1, is_ref=0)=int(42)
$a 和$b
两者现在都成为参考
php > $a = &$b;
php > xdebug_debug_zval('b');
b: (refcount=2, is_ref=1)=int(2)
php > xdebug_debug_zval('a'); // a too
a: (refcount=2, is_ref=1)=int(2)
分配新值,而不是对任何$a
和的引用$b
php > $a = $n;
php > xdebug_debug_zval('a'); // a holds $n's value '42' now
a: (refcount=2, is_ref=1)=int(42)
php > xdebug_debug_zval('b'); // same for b
b: (refcount=2, is_ref=1)=int(42)
通常,当您创建一个变量$a
和时$b
,每个变量都有一个唯一的内存地址来存储其数据。
但是,如果您告诉解释器$a = &$b
,这意味着 $a 和 $b 现在具有相同的内存地址。如果您将任何内容分配给 $a 或 $b,它们都将回显相同的值,因为它们将数据存储在内存中的相同位置。
如果你想试验,我建议从命令行启动 PHP 交互式解释器:
php -a
php > $a = 1;
php > $b = 2;
php > echo $a . ' ' . $b;
1 2
php > $a = &$b;
php > echo $a . ' ' . $b;
2 2
php > $a = 1;
php > echo $a . ' ' . $b;
1 1
php > $b = 2;
php > echo $a . ' ' . $b;
2 2
$a = $b
&$b = $n
具有相同的值但不同,因为该值是原始类型并且primitive types pass by value
.
测试代码是否使用引用的最快速方法是更改源 var 的值并查看目标 var 是否更改了他的值。
$n = 1;
$a = $n;
$b = $n;
echo $a; // 1
echo $b; // 1
echo $n; // 1
$n = 2;
echo $a; // 1
echo $b; // 1
echo $n; // 2
然而objects always are passed by reference
$n = new Object(1);
$a = $n;
$b = $n;
$n->newValue(5);
$a->printValue(); // 5
$b->printValue(); // 5
$a->newValue(7);
$b->printValue(); // 7