rfc:spread_operator_for_array
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
rfc:spread_operator_for_array [2018/10/28 03:29] – jhdxr | rfc:spread_operator_for_array [2019/05/13 12:45] (current) – Implemented nikic | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Spread Operator in Array ====== | + | ====== Spread Operator in Array Expression |
- | * Version: 0.1 | + | * Version: 0.2 |
* Date: 2018-10-13 | * Date: 2018-10-13 | ||
* Author: CHU Zhaowei, jhdxr@php.net | * Author: CHU Zhaowei, jhdxr@php.net | ||
- | * Status: | + | * Status: |
* First Published at: http:// | * First Published at: http:// | ||
===== Introduction ===== | ===== Introduction ===== | ||
- | PHP has already supported [[rfc: | + | PHP has already supported [[rfc: |
===== Proposal ===== | ===== Proposal ===== | ||
- | An array pair prefixed by ... will be expanded in places during array definition. Only arrays and objects who implement Traversable can be expanded. | + | An array pair prefixed by '' |
For example, | For example, | ||
Line 22: | Line 22: | ||
Spread operator works for both array syntax('' | Spread operator works for both array syntax('' | ||
+ | |||
+ | It's also possible to unpack array returned by a function immediately. | ||
+ | |||
<code php> | <code php> | ||
$arr1 = [1, 2, 3]; | $arr1 = [1, 2, 3]; | ||
Line 27: | Line 30: | ||
$arr3 = [0, ...$arr1]; //[0, 1, 2, 3] | $arr3 = [0, ...$arr1]; //[0, 1, 2, 3] | ||
$arr4 = array(...$arr1, | $arr4 = array(...$arr1, | ||
- | </code> | + | $arr5 = [...$arr1, ...$arr1]; |
- | It's possible to unpack arrays with string keys. When unpacking multiple arrays with same string key, the later value for that key will overwrite the previous one. | + | function getArr() { |
+ | return ['a', | ||
+ | } | ||
+ | $arr6 = [...getArr(), ' | ||
- | For arrays with numeric keys, they will be renumbered with incrementing keys starting from zero. So if unpack multiple arrays with same numeric key, the later value will be appended instead of overwriting the previous one. | + | $arr7 = [...new ArrayIterator([' |
- | It's possible to unpack arrays with mixed string and numeric keys. | + | function arrGen() { |
- | <code php> | + | for($i = 11; $i < 15; $i++) { |
- | $arr1 = [' | + | yield $i; |
- | $arr2 = [11 => 11, 22 => 22, 33 => 33]; | + | } |
- | $arr3 = [111 => 9, 22 => 8, ' | + | |
- | var_dump([...$arr1, ...$arr2]); | + | |
- | /* | + | |
- | array(6) { | + | |
- | | + | |
- | | + | |
- | [" | + | |
- | int(2) | + | |
- | [" | + | |
- | int(3) | + | |
- | [0]=> | + | |
- | int(11) | + | |
- | [1]=> | + | |
- | int(22) | + | |
- | [2]=> | + | |
- | int(33) | + | |
} | } | ||
- | */ | + | $arr8 = [...arrGen()]; //[11, 12, 13, 14] |
- | var_dump([...$arr1, ...$arr3]); | + | |
- | /* | + | |
- | array(5) { | + | |
- | [" | + | |
- | int(1) | + | |
- | [" | + | |
- | int(2) | + | |
- | [" | + | |
- | int(7) | + | |
- | [0]=> | + | |
- | int(9) | + | |
- | [1]=> | + | |
- | int(8) | + | |
- | } | + | |
- | */ | + | |
- | var_dump([...$arr2, | + | |
- | /* | + | |
- | array(6) { | + | |
- | | + | |
- | int(11) | + | |
- | [1]=> | + | |
- | int(22) | + | |
- | [2]=> | + | |
- | int(33) | + | |
- | [3]=> | + | |
- | int(9) | + | |
- | [4]=> | + | |
- | int(8) | + | |
- | [" | + | |
- | int(7) | + | |
- | } | + | |
- | */ | + | |
</ | </ | ||
+ | |||
+ | |||
+ | ==== String keys ==== | ||
+ | |||
+ | In order to make the behavior consistent with [[rfc: | ||
==== By-reference passing ==== | ==== By-reference passing ==== | ||
Line 93: | Line 56: | ||
<code php> | <code php> | ||
$arr1 = [1, 2, 3]; | $arr1 = [1, 2, 3]; | ||
- | $arr2 = [...& | + | $arr2 = [...& |
</ | </ | ||
Line 115: | Line 78: | ||
*/ | */ | ||
</ | </ | ||
- | |||
- | |||
===== Backward Incompatible Changes ===== | ===== Backward Incompatible Changes ===== | ||
This change should not break anything. | This change should not break anything. | ||
+ | |||
+ | ===== Q & A ===== | ||
+ | ==== Advantages over array_merge ==== | ||
+ | - Spread operator should have a better performance than '' | ||
+ | - '' | ||
+ | <PHP> | ||
+ | // Before | ||
+ | array_merge(iterator_to_array($iter1), | ||
+ | |||
+ | // Or to generalize to all iterables | ||
+ | array_merge( | ||
+ | is_array($iter1) ? $iter1 : iterator_to_array($iter1), | ||
+ | is_array($iter2) ? $iter2 : iterator_to_array($iter2) | ||
+ | ) | ||
+ | |||
+ | // After (handles both cases) | ||
+ | [ ...$iter1, ...$iter2 ] | ||
+ | |||
+ | //Thanks Rowan for providing this example | ||
+ | </ | ||
+ | |||
+ | ==== ... should be preserved for other use (e.g. map concat) ==== | ||
+ | This is kind of out of scope here to discuss other concat / merge operation. The important thing is we should make the behavior of same operator consistent and not to confuse userland developer. It's also why I changed the behavior for string keys in this revised version. | ||
===== Proposed PHP Version(s) ===== | ===== Proposed PHP Version(s) ===== | ||
Line 126: | Line 110: | ||
===== RFC Impact ===== | ===== RFC Impact ===== | ||
==== To Opcache ==== | ==== To Opcache ==== | ||
- | I'm not sure if this RFC will have any impact on Opcache. I'll check it after I finish | + | Some changes in opcache to support |
+ | ===== Vote ===== | ||
+ | Voting started 2019-04-22 and ends 2019-05-06. A 2/3 majority is required. | ||
- | ===== Proposed Voting Choices ===== | + | <doodle title=" |
- | As this is a language change, a 2/3 majority is required. | + | * Yes |
+ | * No | ||
+ | </doodle> | ||
===== Patches and Tests ===== | ===== Patches and Tests ===== |
rfc/spread_operator_for_array.1540697353.txt.gz · Last modified: 2018/10/28 03:29 by jhdxr