В чем разница между? Int $ number и int $ number = null?
Учитывая это объяснение
Обнуляемые типы: объявления типов для параметров и возвращаемых значений теперь могут быть помечены как обнуляемые, если перед именем типа ставится знак вопроса. Это означает, что, как и указанный тип, NULL может передаваться в качестве аргумента или возвращаться в качестве значения соответственно.
https://www.php.net/manual/en/migration71.new-features.php
Следующий код:
public function test(?int $var) {
}
Означает, что test()
можно вызывать с $var
либо как int
, либо как null
.
И следующий код:
public function test(int $var = null) {
}
Означает, что test()
можно вызывать с $var
либо как int
, либо как null
.
Каковы различия между этими двумя методами? Является ли один из них более производительным, чем другой?
Ответы
Ответ 1
Важно различать две обсуждаемые здесь языковые функции: объявления типов и значения аргументов по умолчанию.
Первая функция использует только объявления типов, это означает, что входной аргумент имеет типа int
или NULL
.
Вторая функция использует как объявления типов, так и значения аргументов по умолчанию, это означает, что аргумент имеет типа int
или NULL
, но, если он опущен, по умолчанию будет равен NULL
.
Возьмите свою первую функцию, если вы просто вызвали test()
, ничего не передавая ей, вы получите:
Неустранимая ошибка PHP: Uncaught ArgumentCountError: слишком мало аргументов для функции test() [...]
это правильно, поскольку функция ожидает либо int
, либо NULL
, но не получила ни того, ни другого, а для второго, поскольку вы определили аргумент со значением по умолчанию, он будет работать без ошибок.
Код
function test(?int $var) {
var_dump($var);
}
function test2(int $var = null) {
var_dump($var);
}
test(1); // fine
test(); // error
test2(1); // fine
test2(); // fine
Что касается производительности, то разница, вероятно, ничтожна, ничего достаточно значительного, что могло бы вызвать беспокойство.
Живой пример
Repl
Ответ 2
Если бы язык был разработан сегодня, int $var = null
, вероятно, был бы ошибкой, и он действительно должен быть написан ?int $var = null
. Две части означают разные вещи:
?
указывает, что null
является допустимым значением для этого параметра.
= null
указывает, что null
является значением по умолчанию, если параметр не передан.
Однако до того, как был введен синтаксис ?type
, в языке существовал особый случай: если для параметра задано значение по умолчанию null
, то допустимо передать null
этому параметру, даже если тип В противном случае декларация помешает этому.
Ответ 3
Разница в том, как вы можете вызвать функцию:
// public function test(?int $var)
$foo->test("x"); // does not work (Argument 1 passed to Foo::test() must be of the type int or null, string given)
$foo->test(123); // works
$foo->test(null); // works
$foo->test(); // does not work (Too few arguments to function Foo::test(), 0 passed)
// public function test(int $var = null)
$foo->test("x"); // does not work (Argument 1 passed to Foo::test() must be of the type int or null, string given)
$foo->test(123); // works
$foo->test(null); // works
$foo->test(); // works
Разница в том, что вы не можете вызывать функцию как ->test()
, используя первый синтаксис.