方法不会在其范围之外更改对象数组
Method doesn't change object array outside it's scope
据我所知,问题在于范围界定。
在方法 demo()
中,我正在调用方法 removeElement()
从数组中删除一个元素。
问题是当 removeElement()
方法从数组中删除士兵时,它只在该方法的范围内被删除,当我在 $this->removeElement();
行之后的 demo()
方法中检查该数组时,数组保持不变.
我试过 return $elements
数组 removeElement()
方法,但这也无济于事,在这种情况下,它 return 只是数组而不是整个数组更新对象。
我已将问题简化为 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');
}
输出:
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.
我希望 $foo->elements
在经过 Demo::removeElement()
之后少一个元素。
该数组未按引用 return 编辑,因此未“就地”更改。这与 OOP 和 classes 无关,它是对函数和 return 值如何工作的基本理解。
基本上,你有三个选择
在你的Foo
class中公开一个setElements(array $elements)
。您可以在 removeElement()
方法中调用它。 (看到它工作 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);
}
既然你想从外部改变Foo::elements
的内容,你也可以把属性变成public。 public array $elements;
,并完全摆脱 getElements()
。看到它工作 here.
将 getElements()
return 作为参考,这就是您认为正在发生的事情。对我来说似乎有点矫枉过正,但这将是一个简单的“修复”。
public function &getElements():array {
return $this->elements;
}
// and remember to access the dereference the return when using it:
// $elements = & $this->foo->getElements();
看到它有效here
据我所知,问题在于范围界定。
在方法 demo()
中,我正在调用方法 removeElement()
从数组中删除一个元素。
问题是当 removeElement()
方法从数组中删除士兵时,它只在该方法的范围内被删除,当我在 $this->removeElement();
行之后的 demo()
方法中检查该数组时,数组保持不变.
我试过 return $elements
数组 removeElement()
方法,但这也无济于事,在这种情况下,它 return 只是数组而不是整个数组更新对象。
我已将问题简化为 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');
}
输出:
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.
我希望 $foo->elements
在经过 Demo::removeElement()
之后少一个元素。
该数组未按引用 return 编辑,因此未“就地”更改。这与 OOP 和 classes 无关,它是对函数和 return 值如何工作的基本理解。
基本上,你有三个选择
在你的
Foo
class中公开一个setElements(array $elements)
。您可以在removeElement()
方法中调用它。 (看到它工作 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); }
既然你想从外部改变
Foo::elements
的内容,你也可以把属性变成public。public array $elements;
,并完全摆脱getElements()
。看到它工作 here.将
getElements()
return 作为参考,这就是您认为正在发生的事情。对我来说似乎有点矫枉过正,但这将是一个简单的“修复”。public function &getElements():array { return $this->elements; } // and remember to access the dereference the return when using it: // $elements = & $this->foo->getElements();
看到它有效here