zoukankan      html  css  js  c++  java
  • PHP 函数的“引用返回”概念释疑(转)

    很多时候我们会看到这样的代码(出自 CI 框架源码):

    1 $class =& load_class('a','b');

    我们都知道其中的'&'是指引用,但是它的作用是什么呢?它能够解决什么样的问题呢?带着这些问题,我们开始了解下“引用返回”。

    引用返回

    手册里是这么写的:引用返回用在当想用函数找到引用应该被绑定在哪一个变量上面时。不要用返回引用来增加性能,引擎足够聪明来自己进行优化。仅在有合理的技术原因时才返回引用!要返回引用,使用此语法:

    01 <?php
    02 class foo {
    03     public $value = 42;
    04  
    05     public function &getValue() {
    06         return $this->value;
    07     }
    08 }
    09  
    10 $obj new foo;
    11 // $myValue is a reference to $obj->value, which is 42.
    12 // $myValue 是 $obj->value 的引用,它们的值都是 42
    13 $myValue = &$obj->getValue();
    14 // 对 $obj->value 重新复制,会影响到 $myValue 的值
    15 $obj->value = 2;
    16 // prints the new value of $obj->value, i.e. 2.
    17 echo $myValue;  // 程序输出 2
    18 ?>

    本例中 getValue() 函数所返回的对象的属性将被赋值,而不是拷贝,就和没有用引用语法一样。

    参数传递不同,这里必须在两个地方都用 & 符号——指出返回的是一个引用,而不是通常的一个拷贝,同样也指出 $myValue 是作为引用的绑定,而不是通常的赋值。

    如果试图这样从函数返回引用:return ($this->value);,这将不会起作用,因为在试图返回一个表达式的结果而不是一个引用的变量。只能从函数返回引用变量——没别的方法。如果代码试图返回一个动态表达式或 new 运算符的结果,自 PHP 4.4.0 和 PHP 5.1.0 起会发出一条 E_NOTICE 错误。

    似懂非懂?那么我们来改写一下程序吧,让它变成一个常规的函数:

    01 <?php
    02 class foo {
    03     public $value = 42;
    04  
    05     public function getValue() {
    06         return $this->value;
    07     }
    08 }
    09  
    10 $obj new foo;
    11 $myValue $obj->getValue();
    12 $obj->value = 2;
    13  
    14 echo $obj->value;  // 程序输出 2
    15 echo $myValue;  // 程序输出 42
    16 ?>

    现在能理解“引用返回用在当想用函数找到引用应该被绑定在哪一个变量上面时”这句话了吧,函数 &getValue() 把引用绑定在成员变量 $value 上了。正常来说,$obj = new foo; 产生的 $obj 是一个copy,它的成员变量 $value 与函数 getValue() 不存在“别名”(引用)关系。

    一些简单的例子

    看下面的简单例子,尝试去理解引用返回。

    01 <?php
    02  
    03 function &test()
    04 {
    05     // 声明一个静态变量
    06     static $b = 0;
    07  
    08     $b $b+1;
    09     echo $b;
    10     return $b;
    11 }
    12  
    13 $a = test();    //这条语句会输出 $b 的值为 1
    14  
    15 $a = 5;
    16 $a = test();    //这条语句会输出 $b 的值为2
    17  
    18 $a = &test();   //这条语句会输出 $b 的值为3
    19  
    20 $a = 5;
    21 $a = test();    //这条语句会输出 $b的值 为6
    22  
    23 ?>

    程序运行结果:

    1 1
    2 2
    3 3
    4 6
    •  
      尽管函数声明方式是 function &test() 这样,但我们通过这种方式 $a = test() 的函数调用得到的其实不是函数的引用返回,这跟普通的函数调用没有区别。PHP 规定通过 $a = &test() 这种方式得到的才是函数的引用返回。

    用上面的例子来解释就是,$a = test() 这种方式调用函数,只是将函数的值赋给 $a 而已,而$a做任何改变都不会影响到函数中的$b。

    而通过 $a = &test() 方式调用函数呢,它的作用是将 return $b 中的 $b 变量的内存地址与 $a 变量的内存地址指向了同一个地方。即产生了相当于这样的效果 ($a=&$b), 所以改变 $a 的值也同时改变了 $b 的值。所以在执行了

    1 $a = &test();
    2 $a = 5;

    以后,$b的值变为了5。

    再来个程序例子加深理解:

    01 <?php
    02 /*
    03 ** 值传递和引用传递,值传递传递的是值的一个复本,引用传递传递的是值指向的内存地址
    04 */
    05  
    06 // 函数的引用,定义时也要加上 &
    07 function &func($a,$b){ 
    08     // 这里为了更直观看到效果,定义一个静态变量
    09     static $result = 0;    
    10     $result+=$a+$b;
    11     echo $result.'<br />';
    12     return $result;
    13 }
    14   
    15 $a $b = 10;
    16  
    17 // PHP里这样写函数的引用调用,和调用普通函数没有区别(只是将函数的返回值复制给$c这个变量,$c做任何改变不会影响上面函数中的$result)
    18 // 要记住:PHP里的函数引用定义及调用都要在函数名前加上 &
    19 $c = func($a,$b);
    20 // 第一次执行func(),其静态变量$result的值变为 20(10+10)
    21  
    22 // 改变$c的值,不会对下面一行语句产生影响
    23 $c = 666; 
    24 // 第二次执行func(),其静态变量$result的值变为 40(20+10+10)
    25 $c = func($a,$b);
    26  
    27 echo '<hr />';
    28  
    29 // 这样才是PHP中引用函数的调用方式
    30 $d = &func($a,$b); 
    31 // 第三次执行func(),其静态变量$result的值变为 40(40+10+10)
    32 $d = 888;
    33 // 第四次执行func(),其静态变量$result的值变为 908(888+10+10)
    34 $d = func($a,$b);
    35  
    36 ?>
  • 相关阅读:
    【题解】CodeChef
    【题解】AT1984 Wide Swap(拓扑排序)
    【题解】CF917D Stranger Trees(prufer序列+二项式反演)
    【题解】UVA
    【题解】P3980 [NOI2008]志愿者招募(费用流求线性规划)
    【题解】AT2064 Many Easy Problems(转换+NTT)
    【题解】AT1983 BBQ Hard (格路)
    【总结】不同卷积如何来搞
    【瞎讲】 Cayley-Hamilton 常系数齐次线性递推式第n项的快速计算 (m=1e5,n=1e18)
    计算几何小结计算几何小结
  • 原文地址:https://www.cnblogs.com/xingmeng/p/3230267.html
Copyright © 2011-2022 走看看