dongweicha6077 2019-07-14 14:22
浏览 109

如何将闭包的返回值赋值给变量by-reference,即使闭包返回by-value?

I have a method which gets a callable as an argument. The callable is called with some arguments which can be gotten by-value or by-reference, and it may return a value, either by-value or by-reference, or not. In the case of returning a value, it must be returned from the closure by the method as exactly as is. If the value is by-reference, the method must return it by-reference, and vice versa.

The problem is that there is no way to determine whether the value is returned by-reference or not. Yes, it can be detected whether the closure returns any values or not; but when I try to get the reference of a closure's return value which is returned by-value, I will get the following notice:

PHP Notice:  Only variables should be assigned by reference in ... on line xxx

Again, the method returns the closure's return value as is (i.e. dynamically). This is what I try to achieve:

class Example
{
    protected $data = 15;

    // Pay attention to this, returning by-reference
    protected function &doOnData(callable $function)
    {
        return $function($this->data);
    }

    public function increment(): void
    {
        // No notices, because the closure is defined to return by-reference
        $data = &$this->doOnData(function &(&$data) {
            return $data;
        });
        $data++;
    }

    public function get()
    {
        // Notice, why you defined the closure to return by-value?
        // Defining the closure to return by-reference fixes the problem
        // temporarily (i.e. defining as: function &($data))
        return $this->doOnData(function ($data) {
            return $data;
        });
    }

    public function printData()
    {
        echo $this->data;
    }
}

$example = new Example();

$example->increment();
$example->printData(); // Prints: 16

$data = $example->get(); // Notice!
echo $data; // Prints: 16

As you see in the example, the notice will only be produced when you pass a returning-by-value closure to Example::doOnData(), and you cannot get its return value reference. In this case, the above notice will be generated (should it be generated? I don't know!).

A solution might be using the @ (at sign) operator, which is stupidly bad (see: 1 and 2). Saving the reference of the closure to a variable, and then returning the variable doesn't change anything (AFAIK). Also, adding an ampersand (&) before the closure inside Example::get(), as described in code comments, is not a solution for that, and have some side effects (e.g. every closure must be defined to return by-reference to prevent the notice, too bad, the user doesn't know that). So, please don't suggest these things!

Is there any way to prevent the notice? Am I doing something wrong? Generally speaking, can I determine whether the value is returned by-value or by-reference (i.e. something like is_reference())? Is there any other solutions to get it done?

  • 写回答

0条回答 默认 最新

    报告相同问题?

    悬赏问题

    • ¥30 seata使用出现报错,其他服务找不到seata
    • ¥15 怎么实现输入一个要删除的数后删除后显示剩余数再输入再删除显示剩余数(语言-c语言)
    • ¥35 引用csv数据文件(4列1800行),通过高斯-赛德尔法拟合曲线,在选取(每五十点取1点)数据,求该数据点的曲率中心。
    • ¥20 程序只发送0X01,串口助手显示不正确,配置看了没有问题115200-8-1-no,如何解决?
    • ¥15 Google speech command 数据集获取
    • ¥15 vue3+element-plus页面崩溃
    • ¥15 像这种代码要怎么跑起来?
    • ¥15 安卓C读取/dev/fastpipe屏幕像素数据
    • ¥15 pyqt5tools安装失败
    • ¥15 mmdetection