我见过多次std::string::operator[]不做任何边界检查.甚至string :: at和string :: operator []之间有什么区别?,在2013年询问,答案说operator[]不做任何边界检查.
我的问题是,如果我在[string.access]中查看标准(在本例中为草案N3797)
Run Code Online (Sandbox Code Playgroud)const_reference operator[](size_type pos) const; reference operator[](size_type pos);
- 要求:
pos <= size().- 返回:
*(begin() + pos)ifpos < size().否则,返回对charT具有value 的类型对象的引用charT(),其中修改对象会导致未定义的行为.- 投掷:没什么.
- 复杂性:恒定时间.
这使我相信operator[]必须进行某种边界检查以确定它是否需要返回字符串的元素或默认值charT.这个假设是否正确,operator[]现在需要进行边界检查?
注意:本地服务器 PHP 版本 8.1.4,composer.json 文件中的 laravel 项目有“php”:“^7.2.5”,版本&“laravel/framework”:“^7.0”
PHP 致命错误:继承 ArrayAccess 期间:未捕获 ErrorException:Illuminate\Support\Collection::offsetExists($key) 的返回类型应与 ArrayAccess::offsetExists(mixed $offset): bool 兼容,或 #[\ReturnTypeWillChange ] 属性应该用来暂时抑制通知
首先,来自ole'手册的引用ArrayAccess::offsetSet():
此函数不是通过引用在赋值中调用,也不是通过ArrayAccess重载的数组维度的间接更改(在某种意义上是间接的,不是通过直接更改维度,而是通过更改子维度或子属性或分配数组维度通过引用另一个变量).而是调用ArrayAccess :: offsetGet().只有当该方法通过引用返回时,该操作才会成功,这只能从PHP 5.3.4开始.
我有点困惑.看来这表明(从5.3.4开始)可以定义offsetGet()在实现类中通过引用返回,从而通过引用处理赋值.
所以,现在是一个测试片段:
(无视验证和isset()检查)
class Test implements ArrayAccess
{
protected $data = array();
public function &offsetGet($key)
{
return $this->data[$key];
}
public function offsetSet($key, $value)
{
$this->data[$key] = $value;
}
public function offsetExists($key) { /* ... */ }
public function offsetUnset($key) { /* ... */ }
}
$test = new Test();
$test['foo'] = 'bar';
$test['foo'] = &$bar; // Fatal error: Cannot …Run Code Online (Sandbox Code Playgroud) 我能想到的最好的是
function is_array_alike($array) {
return is_array($array) || (is_object($array) && $array instanceof ArrayAccess && $array instanceof Traversable && $array instanceof Serializable && $array instanceof Countable);
}
Run Code Online (Sandbox Code Playgroud)
啊.还有更漂亮的东西吗?
编辑:测试is_object似乎没必要.我已经在PHP手册的实例中添加了一个关于它的部分.
考虑:
int sum(const int numbers[], const int size){
if (size == 0)
return 0;
else
return numbers[0] + sum(numbers+1, size-1);
}
Run Code Online (Sandbox Code Playgroud)
这是一个简单的递归函数,来自MIT 6.096,用于添加任意数量的整数,并且它可以工作.
我无法理解的是在最后一行:
如何numbers+1工作,给定numbers[]是一个int数组,你不应该能够将一个整数添加到int[]常量?
有没有办法使用array_merge(),array_pop()..函数与ArrayAccess一起使用?
从现在开始,我尝试过Iterate界面和__set_state()魔术方法,但没有成功.
给出错误:array_replace_recursive() [<a href='function.array-replace-recursive'>function.array-replace-recursive</a>]: Argument #1 is not an array.
只是记录,gettype()返回object和is_array()返回false,我在PHP版本5.3.8
我通常可以按照语法在文档页面上“向下钻取/切片”为具有多个维度(并展平)的数组。一个非常酷的功能。例如给出:
my @a=[[1,2,3],
[4,5,6],
[7,8,9]];
Run Code Online (Sandbox Code Playgroud)
我可以使用以下方法选择上述的第2列
say @a[0,1,2;1]; #This output (2,5,8)
Run Code Online (Sandbox Code Playgroud)
是否有可能以类似的紧凑语法提取对角线(1,5,9)?
正如你们许多人所知,PHP 5.4 alpha已经发布.我对以下问题有疑问.
简化的字符串偏移读数.
$str[1][0]现在是一个法律结构.
$str[1][0]工作究竟如何?
是否可以允许Array或实现ArrayAccess的对象?
例如:
class Config implements ArrayAccess {
...
}
class I_Use_A_Config
{
public function __construct(Array $test)
...
}
Run Code Online (Sandbox Code Playgroud)
我希望能够传入Array或ArrayAccess.
除了手动检查参数类型之外,还有一种干净的方法吗?
这是我正在编写测试套件的类的构造函数(它扩展了mysqli):
function __construct(Config $c)
{
// store config file
$this->config = $c;
// do mysqli constructor
parent::__construct(
$this->config['db_host'],
$this->config['db_user'],
$this->config['db_pass'],
$this->config['db_dbname']
);
}
Run Code Online (Sandbox Code Playgroud)
Config传递给构造函数的类实现了arrayaccessphp内置的接口:
class Config implements arrayaccess{...}
Run Code Online (Sandbox Code Playgroud)
我如何模拟/存根Config对象?我应该使用哪个以及为什么?
提前致谢!