Зменшуються типи повернення в PHP7


159

PHP 7 представляє декларації типу повернення . Що означає, що тепер я можу вказати, що повернене значення - це певний клас, інтерфейс, масив, що викликається або один із нещодавно підскажуваних скалярних типів, як це можливо для параметрів функції.

function returnHello(): string {
    return 'hello';
}

Часто трапляється так, що значення не завжди є, і ви можете повернути або щось певного типу, або нульове. Хоча ви можете зробити параметри нульовими, встановивши їх значення за замовчуванням на null ( DateTime $time = null), схоже, спосіб зробити це для типів повернення. Це справді так, чи я якось не знаходжу, як це зробити? Вони не працюють:

function returnHello(): string? {
    return 'hello';
}

function returnHello(): string|null {
    return 'hello';
}

8
PHP7 ще не дозволяє нульові типи повернення, але є RFC, який має на меті вирішити це в PHP 7.1 тут . Після цього наголошене позначення будеfunction returnString(?string $stringNull) : ?string { return $stringNull;}
Еліас Ван Оотегем

1
Я в кінцевому підсумку емуляцію зведеності, зловживаючи винятками в моєму додатку. Якщо ви все добре, але також це буде корисно
Jeroen De Dauw

Можливо, можливо, буде більше сенсу використовувати Trowableінтерфейс PHP7 (конкретно, розширюючи TypeError)
Elias Van Ootegem

Відповіді:


258

PHP 7.1 тепер підтримує зворотні типи повернення . Перший RFC, з яким я пов’язаний, - це той, на який вони пішли:

function nullOrString(int $foo) : ?string
{
    return $foo%2 ? "odd" : null;
}

стара відповідь:

Оскільки мій коментар насправді був відповіддю на питання:

PHP 7 ще не підтримує нульові типи повернення, але є RFC , щоб вирішити саме це, він має на меті приземлитися в PHP 7.1. Якщо він передається, синтаксис впливає на всі підказки типу (як типи повернення, так і підказки типу):

public function returnStringOrNull(?array $optionalArray) : ?string
{
    if ($optionalArray) {
        return implode(', ', $optionalArray);//string returned here
    }
    return null;
}

Існує також конкуруючий RFC для додавання типів об'єднання, які могли б зробити те саме, але виглядали б інакше:

public function returnStringOrNull(array|null $optionalArray) : string|null
{
    if ($optionalArray) {
        return implode(', ', $optionalArray);//string returned here
    }
    return null;
}

Поки що, вам доведеться написати:

public function returnStringOrNull( array $optionalArray = null)
{
    if ($optionalArray) {
        return implode(', ', $optionalArray);
    }
}

Або просто поверніть порожній рядок, щоб він відповідав типу повернення, і перевірте значення помилки:

public function returnStringOrNull( array $optionalArray = null) : string
{
    if ($optionalArray) {
        return implode(', ', $optionalArray);
    }
    return '';
}
//call
$string = $x->returnStringOrNull();
if (!$string) {
    $string = $x->returnStringOrNull(range(1, 10));
}

5
PHP 7 won't support nullable return-types just yet, but there's an RFC out to address just that- так, RFC, "тільки поки". Не зрозумійте мене неправильно - я дуже важкий користувач PHP, оскільки справді лукавий PHP3 раз до цього часу немає прогалин, але коли я побачив усі ці RFC, вони відхилили 7, моє враження було просто "WTF ?!". Користувачі бачать безлад і готові прибрати його назад сумісним способом, і вони просто отримують "ні". Чисті методи іменування безладу? Виправлений nullне надто особливий громадянин? Ні, не потрібна. Додати варіант, щоб зробити всі речі чутливими до регістру? Ні .. І тоді, дивуйтеся, що люди переключаються.
Marcin Orlowski

1
@MarcinOrlowski: Підказка щодо зворотного зворотного типу мала б сенс. Я дотримувався пари RFC протягом 7, і я погодився здебільшого з ними відкидаючи багато з них. Зміни, на яких вони були зосереджені, були не стільки на мові, скільки на час виконання та компілятора. Деякі з RFC, які були відхилені, варто прочитати теми обговорення, щоб зрозуміти, чому вони вирішили не застосовувати ці зміни (наприклад, депресія var). Проблема полягає в тому, що натомість вони прийняли занадто багато приємних для себе (наприклад, оператора космічного корабля)
Elias Van Ootegem

@EliasVanOotegem Nullable типи тепер підтримуються належним чином, оскільки 7.1 випущено 1 грудня.
самотній день

@lonesomeday: Дійсно так, додав посилання + основний приклад до основи моєї відповіді
Elias Van Ootegem

ммм іш гарний тип, щоб оновити цю відповідь! тобто тип об'єднання, як видається, не підтримується в PHP 7.1
Dennis

67

Зменшувані типи доступні в PHP 7.1.

Це приклад синтаксису:

public function getName(): ?string
{
    return $this->name; // name can be null
}

PHP 7.1 тепер є GA, і ви можете оновити з PHP 7.0 (є лише кілька невідповідних змін, які вам доведеться перевірити)


22
IMO - це жарт, щоб доставляти декларації типу повернення, не застосовуючи "нульові". Типи повернення є непридатними до тих пір, поки не буде реалізована функція "зведення нанівець".
joonas.fi

2
@ joonas.fi ІМО строго набрані значення повернення завжди повинні бути такого типу, нульове повернення не відповідає цьому контракту, а має радше кидати виняток, надаючи більше значення причині нульового значення.
Стів Бузонас

8
@SteveBuzonas якщо ви розглядаєте метод getAgeInYears () на об'єкті, що представляє особу, як би ви змоделювали людину, яка не сказала нам свого віку? Повернути нуль? Повернути 0? Повернення нуля семантично означає "ми не знаємо", тоді як 0 семантично означає "людині 0 років". Тому я б заперечував getAgeInYears ():? Int бути найкращим дизайном. Закидання винятків має бути зарезервовано для ... виняткових випадків. Незнання віку людини в більшості систем не слід вважати винятковою справою.
joonas.fi

@ joonas.fi дуже правда, і це звичайна практика. Однак тепер для вашої реалізації потрібно усвідомлювати, що поле є нульовим, і явно обробляти відповідно. Що дуже добре може бути x, за винятком випадків, коли null, який так само легко можна реалізувати за допомогою try / catch. Далі, якщо для продовження виконання потрібне значення в цьому нульовому полі дійсно потрібно, виняток, ймовірно, є кращим варіантом.
Стів Бузонас

Я помітив, що цей синтаксис призводить до того, що PHPMD кидає багато помилок. Сподіваємось, вони скоро це виправлять.
Том Джовітт

0

Він працює з будь-яким типом.
Приклад:

public function getOpportunity(): ?Opportunity
{
    return $this->opportunity;
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.