5
5
6
6
# Summary
7
7
8
- Replace ` slice.tail() ` , ` slice.init() ` with new methods ` slice.shift_first () ` ,
9
- ` slice.shift_last () ` .
8
+ Replace ` slice.tail() ` , ` slice.init() ` with new methods ` slice.split_first () ` ,
9
+ ` slice.split_last () ` .
10
10
11
11
# Motivation
12
12
@@ -20,10 +20,10 @@ remaining methods that panic without taking an explicit index.
20
20
A conservative change here would be to simply change ` head() ` /` tail() ` to return
21
21
` Option ` , but I believe we can do better. These operations are actually
22
22
specializations of ` split_at() ` and should be replaced with methods that return
23
- ` Option<(T,&[T])> ` . This makes the common operation of processing the first/last
24
- element and the remainder of the list more ergonomic, with very low impact on
25
- code that only wants the remainder (such code only has to add ` .1 ` to the
26
- expression). This has an even more significant effect on code that uses the
23
+ ` Option<(& T,&[T])> ` . This makes the common operation of processing the
24
+ first/last element and the remainder of the list more ergonomic, with very low
25
+ impact on code that only wants the remainder (such code only has to add ` .1 ` to
26
+ the expression). This has an even more significant effect on code that uses the
27
27
mutable variants.
28
28
29
29
# Detailed design
@@ -32,21 +32,21 @@ The methods `head()`, `tail()`, `head_mut()`, and `tail_mut()` will be removed,
32
32
and new methods will be added:
33
33
34
34
``` rust
35
- fn shift_first (& self ) -> Option <(& T , & [T ])>;
36
- fn shift_last (& self ) -> Option <(& T , & [T ])>;
37
- fn shift_first_mut (& mut self ) -> Option <(& mut T , & mut [T ])>;
38
- fn shift_last_mut (& mut self ) -> Option <(& mut T , & mut [T ])>;
35
+ fn split_first (& self ) -> Option <(& T , & [T ])>;
36
+ fn split_last (& self ) -> Option <(& T , & [T ])>;
37
+ fn split_first_mut (& mut self ) -> Option <(& mut T , & mut [T ])>;
38
+ fn split_last_mut (& mut self ) -> Option <(& mut T , & mut [T ])>;
39
39
```
40
40
41
41
Existing code using ` tail() ` or ` init() ` could be translated as follows:
42
42
43
43
* ` slice.tail() ` becomes ` &slice[1..] `
44
44
* ` slice.init() ` becomes ` &slice[..slice.len()-1] ` or
45
- ` slice.shift_last ().unwrap().1 `
45
+ ` slice.split_last ().unwrap().1 `
46
46
47
47
It is expected that a lot of code using ` tail() ` or ` init() ` is already either
48
48
testing ` len() ` explicitly or using ` first() ` / ` last() ` and could be refactored
49
- to use ` shift_first ()` / ` shift_last ()` in a more ergonomic fashion. As an
49
+ to use ` split_first ()` / ` split_last ()` in a more ergonomic fashion. As an
50
50
example, the following code from typeck:
51
51
52
52
``` rust
@@ -57,7 +57,7 @@ if variant.fields.len() > 0 {
57
57
can be rewritten as:
58
58
59
59
``` rust
60
- if let Some ((_ , init_fields )) = variant . fields. shift_last () {
60
+ if let Some ((_ , init_fields )) = variant . fields. split_last () {
61
61
for field in init_fields {
62
62
```
63
63
@@ -71,14 +71,14 @@ let args_ = args.tail();
71
71
can be rewritten as:
72
72
73
73
``` rust
74
- let (argv0 , args_ ) = args . shift_first (). unwrap ();
74
+ let (argv0 , args_ ) = args . split_first (). unwrap ();
75
75
```
76
76
77
77
(the ` clone() ` ended up being unnecessary).
78
78
79
79
# Drawbacks
80
80
81
- The expression ` slice.shift_last ().unwrap().1 ` is more cumbersome than
81
+ The expression ` slice.split_last ().unwrap().1 ` is more cumbersome than
82
82
` slice.init() ` . However, this is primarily due to the need for ` .unwrap() `
83
83
rather than the need for ` .1 ` , and would affect the more conservative solution
84
84
(of making the return type ` Option<&[T]> ` ) as well. Furthermore, the more
@@ -95,17 +95,3 @@ function names should be (the current names are considered suboptimal).
95
95
Just deprecate the current methods without adding replacements. This gets rid of
96
96
the odd methods today, but it doesn't do anything to make it easier to safely
97
97
perform these operations.
98
-
99
- # Unresolved questions
100
-
101
- Is the name correct? There's precedent in this name in the form of
102
- [ ` str::slice_shift_char() ` ] [ slice_shift_char ] . An alternative name might be
103
- ` pop_first() ` /` pop_last() ` , or ` shift_front() ` /` shift_back() ` (although the
104
- usage of ` first ` /` last ` was chosen to match the existing methods ` first() ` and
105
- ` last() ` ). Another option is ` split_first() ` /` split_last() ` .
106
-
107
- Should ` shift_last() ` return ` Option<(&T, &[T])> ` or ` Option<(&[T], &T)> ` ?
108
- I believe that the former is correct with this name, but the latter might be
109
- more suitable given the name ` split_last() ` .
110
-
111
- [ slice_shift_char ] : http://doc.rust-lang.org/nightly/std/primitive.str.html#method.slice_shift_char
0 commit comments