Non riesco a cogliere la logica di valutazione nel codice elencato di seguito. Qualcuno sa perché PHP valuta $b
e $b = $b
diversamente in questo caso?
Ho letto una serie di domande qui su SO e ho controllato il Manuale PHP. Così facendo, sono arrivato a capirlo "PHP non specifica (nel caso generale) in quale ordine viene valutata un'espressione" e quello "il comportamento può cambiare tra le versioni di PHP o in base al codice circostante". Non credo che ciò si applichi a questa situazione. O lo fa?
Essere il primo ad ammettere che questo potrebbe non essere il tuo problema quotidiano di codifica, sono ancora curioso. Ci siamo imbattuti in esso cercando di fare un po ' codice golf.
$a = [[00, 01, 02, 03],
[10, 11, 12, 13],
[20, 21, 22, 23],
[30, 31, 32, 33]];
$b = 2;
echo $a[$b][$b++], PHP_EOL;
$b = 2;
echo $a[$b=$b][$b++], PHP_EOL;
Output - PHP 5.5.14:
32
22
risposte:
10 per risposta № 1Questo sembra l'esempio nel Manuale usato per dimostrare Ordine di valutazione indefinito. Dal manuale:
La precedenza e l'associatività degli operatori determinano solo il modo in cui le espressioni sono raggruppate, non specificano un ordine di valutazione. PHP non (nel caso generale) specifica inquale ordine viene valutata un'espressione e il codice che presuppone uno specifico ordine di valutazione deve essere evitato, poiché il comportamento può cambiare tra le versioni di PHP o in base al codice circostante.
Enfasi aggiunta
L'esempio che danno:
<?php
$a = 1;
echo $a + $a++; // may print either 2 or 3
$i = 1;
$array[$i] = $i++; // may set either index 1 or 2
?>
Stai ottenendo l'output che sei perché nel primo esempio, l'indice $b++
è stato determinato primo, mentre nel secondo l'indice $b=$b
è il primo
NB
Quanto a perché questo è, credo che una possibile ragione sia spiegata da questa nota sulla stessa pagina di manuale:
Sebbene = abbia una precedenza inferiore rispetto alla maggior parte degli altri operatori, PHP consentirà comunque espressioni simili alla seguente: if (! $ A = foo ()), nel qual caso il valore di ritorno di foo () viene messo in $ a.
Credo che ci manchi un'ultima parola cruciale lì: primo (senza, a me leggere la nota perde un po 'di significato).
Seguendo le stesse regole di PHP, e assumiamo un ordine FIFO, !$a
dovrebbe essere valutato prima Se $a
è attualmente null
o undefined
, poi !$a
sarà uguale true
(sarà valutato e il risultato sarà gettato via). Seguendo quello, foo()
sarà valutato e verrà assegnato il suo valore di ritorno $a
(anche se assumiamo FIFO, foo()
deve essere valutato per primo se il risultato deve essere assegnato a qualcosa). Il risultato di questo incarico sarà valutato da if
e si tradurrà esattamente nel valore opposto che l'autore voleva.
Non sono un esperto di C, ma un po 'di ricerca mi porta anche a questo risposta che cita lo standard C90:
(C90, 6.3) "Tranne come indicato dalla sintassi o altrimenti specificato in seguito (per gli operatori di chiamata di funzione (), &&, ||,?:, E virgola). L'ordine di valutazione delle sottoespressioni e l'ordine in cui gli effetti collaterali prendono i posti sono entrambi non specificati "
Poiché PHP è basato su C, ha senso che erediti alcune delle sue eccentricità.