Description
Here's example code showing ideal code I'd like to write:
fn example( pattern: &str ) {
match pattern.split( '*' ).collect() {
[head, tail] => println!( "{:?} {:?}", head, tail ),
_ => ()
};
}
and here's the code Rust forces me to write:
fn example( pattern: &str ) {
let items: ~[&str] = pattern.split( '*' ).collect();
let items_ref: &[&str] = items;
match items_ref {
[head, tail] => println!( "{:?} {:?}", head, tail ),
_ => ()
};
}
Notice the useless items
and items_ref
vars. They only exist to placate the compiler. I understand that pattern.split( '*' ).collect()
returns a std::iter::FromIterator<&str>
and that conversions need to happen, but I'm currently forced to use vars to achieve this. The as
keyword for casting only works with primitive numeric types or pointers, so I know of no way to get a ~[&str]
out of pattern.split( '*' ).collect()
(and then a &[&str]
out of that) with an expression.
The match
makes this a very pathological example, but here's something more common:
fn takes_ref_vec( items: &[int] ) {
println!( "{:?}", items )
}
#[test]
fn takes_ref_vec_tests() {
// Doesn't compile!
takes_ref_vec( [1, 2, 3].iter().map( |&x| x ).collect() )
// Infinite sadness...
let useless: ~[int] = [1, 2, 3].iter().map( |&x| x ).collect();
takes_ref_vec( useless );
}
I know I'm unlikely to convince the Rust devs to accept implicit casts, but could we make explicit casts possible with an expression? Something like as
for numeric types? Having to introduce a new variable name only for the sake of a cast is not very user-friendly and only leads to boilerplate code. Also, being forced to use a statement to cast a type feels quite un-functional and needlessly breaks my expression chains.
I'm a complete Rust newbie, so apologies if I'm missing some obvious solution to the above problems.
This is all using the latest Rust nightly.