Tipi restituibili nullabili in PHP7


159

PHP 7 introduce dichiarazioni sul tipo di ritorno . Ciò significa che ora posso indicare che il valore restituito è una determinata classe, interfaccia, matrice, richiamabile o uno dei tipi scalari appena stampabili, come è possibile per i parametri di funzione.

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

Accade spesso che un valore non sia sempre presente e che potresti restituire qualcosa di un tipo o null. Sebbene sia possibile rendere nulli i parametri impostando il valore predefinito su null ( DateTime $time = null), non sembra esserci un modo per farlo per i tipi restituiti. È davvero così, o non trovo in qualche modo come farlo? Questi non funzionano:

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

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

8
PHP7 non consentirà ancora tipi di ritorno nullable, ma esiste un RFC che mira a risolvere questo problema in PHP 7.1 qui . La notazione proposta sarebbe quindifunction returnString(?string $stringNull) : ?string { return $stringNull;}
Elias Van Ootegem,

1
Ho finito per emulare la nullità abusando delle eccezioni nella mia applicazione per ora. Se stai bene anche con l'essere sciocco, questo potrebbe essere utile: github.com/JeroenDeDauw/OhMyPhp/blob/master/src/…
Jeroen De Dauw il

Forse potrebbe avere più senso usare l' Trowableinterfaccia PHP7 (in particolare, estendendo TypeError)
Elias Van Ootegem,

Risposte:


258

PHP 7.1 ora supporta tipi di ritorno nullable . Il primo RFC a cui ho collegato è quello per cui sono andati:

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

vecchia risposta:

Dal momento che il mio commento era in realtà una risposta alla domanda:

PHP 7 non supporterà ancora tipi di ritorno annullabili, ma esiste un RFC per risolvere proprio questo, mira a sbarcare in PHP 7.1. Se passa, la sintassi inciderebbe quindi su tutti i suggerimenti di tipo (sia i tipi restituiti che i suggerimenti di tipo):

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

C'è anche un RFC in competizione per aggiungere tipi di unione, che sarebbe in grado di fare la stessa cosa, ma apparirebbe diverso:

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

Per ora, però, dovrai scrivere:

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

O semplicemente restituire una stringa vuota per essere coerente con il tipo restituito e controllare il valore di falsy:

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- Sì, RFC, "appena ancora". Non fraintendetemi: sono un utente PHP molto pesante, dato che fino ad ora sono state davvero pessime volte PHP3, senza lacune, ma quando ho visto tutti questi RFC rifiutati per 7, la mia impressione era solo "WTF ?!". Gli utenti vedono il disordine e sono disposti a ripulirlo in modo compatibile con le versioni precedenti e ottengono semplicemente "no". Metodi puliti che nominano pasticcio? Risolto il nullproblema con il non essere cittadino troppo speciale? No, non necessario. Inserisci un'opzione per rendere tutte le cose sensibili al maiuscolo / minuscolo? Nah .. E poi, sorprendi che la gente cambi.
Marcin Orlowski,

1
@MarcinOrlowski: un suggerimento sul tipo di ritorno nullable avrebbe senso. Ho seguito un paio di RFC per 7 e ho concordato per la maggior parte con loro respingendone molti. Le modifiche su cui si stavano concentrando non erano tanto sul linguaggio quanto sul runtime e sul compilatore. Per alcuni RFC che sono stati rifiutati, vale la pena leggere i thread di discussione per capire perché hanno scelto di non implementare tali modifiche (ad esempio, deprecando var). Quello che è un peccato è che invece hanno accettato uno di quelli troppo carini (ad esempio l'operatore di astronave)
Elias Van Ootegem,

@EliasVanOotegem I tipi nullable sono ora supportati correttamente, poiché 7.1 è stato rilasciato il 1 ° dicembre.
lunedì

@lonesomeday: Anzi, ha aggiunto il link + esempio di base in fondo alla mia risposta
Elias Van Ootegem,

mmm è un buon tipo per aggiornare questa risposta! cioè il tipo di unione non sembra essere supportato in PHP 7.1
Dennis

67

I tipi nullable sono disponibili in PHP 7.1.

Questo è un esempio di sintassi:

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

PHP 7.1 è ora GA ed è possibile eseguire l'aggiornamento da PHP 7.0 (ci sono solo alcune modifiche incompatibili all'indietro che è necessario verificare)


22
IMO è uno scherzo consegnare dichiarazioni sul tipo di reso senza implementare "nullable". I tipi restituiti sono inutilizzabili fino all'implementazione della funzione "nullable".
joonas.fi,

2
@ joonas.fi I valori di ritorno IMO tipizzati in modo rigoroso devono sempre essere di quel tipo, un ritorno nullo non vale per quel contratto e dovrebbe piuttosto generare un'eccezione dando più significato alla ragione di un valore nullo.
Steve Buzonas,

8
@SteveBuzonas se consideri un metodo getAgeInYears () su un oggetto che rappresenta una persona, come modelleresti una persona che non ci ha detto la sua età? Ritorno null? Ritorna 0? Restituire null semanticamente significa "non sappiamo", mentre 0 semanticamente significa "la persona ha 0 anni". Pertanto direi getAgeInYears ():? Int per essere il miglior design. Le eccezioni da lanciare dovrebbero essere riservate a casi ... eccezionali. Non conoscere l'età di una persona nella maggior parte dei sistemi non dovrebbe essere considerato un caso eccezionale.
joonas.fi,

@ joonas.fi è molto vero, e questa è una pratica comune. Tuttavia, l'implementazione ora deve essere consapevole che il campo è nullable e gestire esplicitamente di conseguenza. Che molto bene può essere fare x tranne quando null che potrebbe essere altrettanto facilmente implementato con un tentativo / cattura. Inoltre, se si richiede effettivamente un valore in quel campo nullable per continuare l'esecuzione, un'eccezione è probabilmente un'opzione migliore.
Steve Buzonas,

Ho notato che questa sintassi fa sì che PHPMD generi molti errori. Spero che lo risolvano presto.
Tom Jowitt

0

Funziona con qualsiasi tipo.
Esempio:

public function getOpportunity(): ?Opportunity
{
    return $this->opportunity;
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.