I was looking through Rust's source code to better acquaint myself with the language. I came across this snippet.
// Collect program arguments as a Vec<String>.
let cmd: Vec<_> = env::args().collect();
// Some unrelated code omitted here.
match subcommand::parse_name(&cmd[1][..]) {
// It did some stuff here.
}
I didn't understand the [..]
. So, I went and checked out the declaration of parse_name
:
pub fn parse_name(name: &str) -> Option<Box<Subcommand>>
It's what I expected, but I still don't get the [..]
. What does it mean in this context? Isn't it just passing the first String
in cmd
as a &str
? If so, is this equivalent to just writing cmd[1]
? Why did they do it this way?
This is just a way to explicitly coerce from
String
to&str
. In this case, the[..]
is actually unnecessary asDeref
coercions means thatparse_name(&args[1])
is valid too:&String
will borrow to&str
implicitly.The
[ ]
indexing operator is calling thestd::ops::Index
trait, and the..
syntax is creating astd::ops::RangeFull
value.cmd
is aVec<String>
, sincestd::env::args()
returns anIterator
overString
s.Hence, the
foo[..]
syntax is calling the implementation ofIndex<RangeFull>
forString
(which you can see in the list of Implementors on theIndex
page). The implementation looks like:The
&*self.vec
is borrowing theString
's internalVec<u8>
to&[u8]
, and then thetransmute
is explicitly casting that to a&str
, which is safe becauseString
's API ensures that the internalVec<u8>
is valid UTF-8, which is whatstr
requires.Two periods (
..
) is the range operator. You can find this in the Operators and Symbols Appendix of the Rust book. There are six flavors:Range
:1..10
RangeFrom
:1..
RangeTo
:..10
RangeFull
:..
RangeInclusive
:1..=10
RangeToInclusive
:..=10
When no item occupies an end position, the range goes on "forever" in that direction.
This combines with the
Index
trait (orIndexMut
, if mutation is required). In your example, you have a string slice (kind of, see next point) that you are applying indexing to:"foo"[2..]
.Specifically,
&str
implementsIndex
asThen there's a third bit of ergonomics happening:
Deref
(orDerefMut
in similar cases).String
implementsDeref
by returning a&str
, so any method available to a&str
is available to aString
.