PHP 7.1 - Почему нет предупреждения о возвращаемом значении void?

примечания к руководству по PHP это в обзоре нового возвращаемого типа void, добавленного в PHP 7.1:

Попытка использовать возвращаемое значение функции void просто оценивается как NULL без каких-либо предупреждений. Причина этого в том, что предупреждения подразумевают использование общих функций более высокого порядка.

Что имеется в виду под «предупреждения могут подразумевать использование функций более высокого порядка»?


person Scott Buchanan    schedule 14.09.2018    source источник
comment
Функции более высокого порядка принимают другие функции в качестве параметров или возвращают функцию в качестве результата.   -  person Madhur Bhaiya    schedule 14.09.2018
comment
Я понимаю, что такое функции более высокого порядка, но мой вопрос больше касался того, что имеется в виду под импликацией функций более высокого порядка.   -  person Scott Buchanan    schedule 14.09.2018


Ответы (3)


Функция высшего порядка (HOF) — это функция, которая соответствует хотя бы одному из следующих условий:

  • Принимает одну или несколько функций в качестве аргументов
  • Возвращает функцию как результат

источник

А затем из PHP Void RFC:

С return; и return null; технически эквивалентны в PHP; когда возвращаемое значение не указано, PHP выдаст вам null. Однако выбор одного из двух предполагает намерение. Если вы укажете значение, это предполагает, что значение является значимым. В функции void возвращаемое значение не имеет значения: оно всегда одно и то же и не имеет реальной пользы. Явное указание с возвратом null; бессмысленно, потому что на самом деле не имеет значения, какое значение будет возвращать функция.

(Мои основные моменты)

Следовательно, просто нет необходимости предоставлять предупреждение, и потребуется просто использовать другую функцию и дополнительные значительные накладные расходы времени компиляции, чтобы уведомить об ошибке возврата в части кода, который преднамеренно предназначен не возвращаться .

Подумайте об этом так:

  • Я буду держать много губок наготове на случай, если опрокинется пустой пакет из-под молока.

Коробка всегда будет пустой, так что нет необходимости идти в магазин и покупать 12 супервпитывающих губок!


Чтобы узнать, какие именно функции будут вызываться, попробуйте изучить (с открытым исходным кодом) логику обработки ошибок во время компиляции PHP 7; чтобы увидеть, какие функции будут вызываться для обработки функции, вызывающей аналогичную ошибку (например, возвращающую нераспознанный или неправильный тип).

Эти функции будут теми, которые не вызываются, автоматически возвращая null вместо ошибки в PHP 7.1, предназначенных для возвращаемых типов void.

person Martin    schedule 14.09.2018

Проблемой являются такие случаи:

class Forwarder {
    public $obj; // Some object
    public function __call($method, $args) {
        return $this->obj->$method(...$args);
    }
}

class Obj {
    public function returnsVal(): int { return 42; }
    public function returnsVoid(): void { return; }
}

$fwd = new Forwarder;
$fwd->obj = new Obj;

// We want both of these calls to work
$val = $fwd->returnsVal();
$fwd->returnsVoid();

Этот код может обрабатывать как недействительные, так и непустые функции. Если бы использование возвращаемого значения функции void выдавало предупреждение, то мы не смогли бы написать этот код и вместо этого должны были бы сделать что-то вроде этого:

class Forwarder {
    public $obj; // Some object
    public function __call($method, $args) {
        if (returns_void($this->obj, $method)) {
            $this->obj->$method(...$args);
        } else {
            return $this->obj->$method(...$args);
        }
    }
}

Это много ненужного шаблонного кода, не говоря уже о том, что «returns_void» пришлось бы реализовывать с использованием дорогостоящих вызовов отражения.

person NikiC    schedule 19.09.2018
comment
Отличный практический пример. Это подтверждает мое подозрение, поскольку я отметил в своем комментарии к @Sammitch, что в руководстве было использовано неправильное слово (подразумевается). - person Scott Buchanan; 19.09.2018

В качестве дополнения к ответу Мартина я считаю, что следующий раздел Void RFC также полезен для прояснения проблемы:

Использование функций void в выражениях

В некоторых других языках, таких как C, функция void не может использоваться в выражении, только как оператор. Поскольку этот RFC добавляет способ указания функции void в синтаксисе PHP, можно было бы ожидать, что такое же ограничение теперь будет применяться и в PHP. Однако это не соответствовало бы прецеденту. С самого начала в PHP были своего рода «недействительные функции» в виде встроенных функций, которые в руководстве обозначены как «недействительные». Такие функции можно использовать в выражениях, в отличие от C.

Мы могли бы изменить правила PHP для void-функций и запретить их использование в выражениях, но это создало бы проблему обратной совместимости: не исключено, что существующий PHP-код полагается на возможность вызова встроенных void-функций в выражениях и на большое количество кода. предполагает, что вы можете получить возвращаемое значение произвольной функции PHP (возможно, обратный вызов).

Более того, IDE и другие инструменты могут предупреждать пользователя, когда используется возвращаемое значение функции void. Самому языку не обязательно покрывать это.

https://wiki.php.net/rfc/void_return_type#use_of_void_functions_in_expressions

TL;DR

В PHP уже было void встроенных функций, которые можно было использовать в выражениях, и изменить их сейчас было бы большим прорывом в BC.

person Sammitch    schedule 14.09.2018
comment
Я склоняюсь к мысли, что это правильный ответ на то, что подразумевалось под этим в руководстве по PHP, но в руководстве используется неправильное слово. Подразумевать означает вовлекать как следствие. Ответ Мартина указывает на внутренние функции PHP, которые участвуют в обработке предупреждений, но это кажется странным обсуждать в руководстве пользователя. Интересно, имело ли руководство в виду что-то вроде предотвращения вместо вовлечения. - person Scott Buchanan; 15.09.2018