简体   繁体   English

方法不会在 scope 之外更改 object 数组

[英]Method doesn't change object array outside it's scope

Problem is, as far as I can tell, in scoping.据我所知,问题在于范围界定。

In method demo() I'm calling method removeElement() which removes an element from the array.在方法demo()中,我调用方法removeElement()从数组中删除一个元素。

Problem is when removeElement() method removes soldier from array it's only removed in that method's scope, when I check that array in demo() method after $this->removeElement();问题是当removeElement()方法从数组中删除士兵时,它仅在该方法的 scope 中被删除,当我在$this->removeElement();之后的demo()方法中检查该数组时; line, the array remains unchanged.行,数组保持不变。

I've tried to return $elements array in removeElement() method but that doesn't help either and it that case it returns only array not entire updated object.我试图在removeElement()方法中返回$elements数组,但这也无济于事,在这种情况下,它只返回数组而不是整个更新的 object。

I've reduced the problem to this minimum example :我已将问题简化为这个最小示例

class Foo
{
    private array $elements = [];

    public function __construct(int $howMany)
    {
        for ($i = 0; $i < $howMany; $i++) {
            $this->elements[] = random_int(1, 100);
        }
    }


    public function getElements(): array
    {
        return $this->elements;
    }
}

class Demo
{
    public Foo $foo;

    public function __construct(int $howMany)
    {
        $this->foo = new Foo($howMany);
    }

    public function demo(): void
    {
        echo "\nWe start with ", count($this->foo->getElements()), " soldiers in \$foo->elements\n"; 
        $this->removeElement();

        echo "\nWe have ", count($this->foo->getElements()), " soldiers in \$foo->elements\n"; 
    }

    private function removeElement(): void
    {
        $elements = $this->foo->getElements();
        array_splice($elements, 2, 1);
        echo "\nWe have ", count($elements), " soldiers in local \$elements\n"; 

    }
}

$init = random_int(4,10);
$demo = new Demo($init);
$demo->demo();

$remaining = count($demo->foo->getElements());

if ($init-1 !== $remaining) {
    throw new UnexpectedValueException('Wrong number of elements, application is broken');
}

Which outputs:哪些输出:

We start with 10 soldiers in $foo->elements

We have 9 soldiers in local $elements

We have 10 soldiers in $foo->elements

Fatal error: Uncaught UnexpectedValueException: Wrong number of elements, application is broken in /in/3cnhl:54
Stack trace:
#0 {main}
  thrown in /in/3cnhl on line 54

Process exited with code 255.

I would expect $foo->elements to have one element less after going through Demo::removeElement() .我希望$foo->elements在通过Demo::removeElement()之后少一个元素。

The array is not returned by reference, so it's not changed "in place".该数组不是通过引用返回的,因此它不会“就地”更改。 This has nothing to do with OOP and classes, it's basic understanding of how functions and return values work.这与 OOP 和类无关,它是对函数和返回值如何工作的基本理解。

You have, basically, three options基本上,你有三个选择

  • Expose a setElements(array $elements) in your Foo class. You could call this in your removeElement() method.在您的Foo class 中公开一个setElements(array $elements) 。您可以在您的removeElement()方法中调用它。 (see it working here ) (看到它在这里工作)

     private function removeElement(): void { $elements = $this->foo->getElements(); array_splice($elements, 2, 1); echo "\nWe have ", count($elements), " soldiers in local \$elements\n"; $this->foo->setElements($elements); }
  • Since you want to change the contents of Foo::elements from outside, you could just as well make the property public.由于您想从外部更改Foo::elements的内容,您也可以将该属性公开。 public array $elements; , and get rid of getElements() altogether. ,并完全摆脱getElements() See it working here .看到它在这里工作。

  • Make getElements() return a reference, which is what it appears you thought was happening.使getElements()返回一个引用,这就是您认为正在发生的事情。 Seems overkill to me, but it would be an easy "fix".对我来说似乎有点矫枉过正,但这将是一个简单的“修复”。

     public function &getElements():array { return $this->elements; } // and remember to access the dereference the return when using it: // $elements = & $this->foo->getElements();

    See it working here看到它在这里工作

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM