В чем разница между? 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(), используя первый синтаксис.