Да, несмотря на все плюсы модели памяти Rust, все же приходится признать – это для очень упорных программистов. В крайнем случае у меня создалось именно такое ощущение в процессе выяснения в “рассылке” как же мне написать функции доступа к элементам кортежа. В сам язык встроена следующая возможность:
...
let (l, r) = foo();
io::println(fmt!("Left value = %u, write value = %u", l, r));
В то же время, мне хотелось получить доступ к элементу кортежа без дополнительных “приседаний”, где-то так:
io::println(fmt!("Left value = %u, write value = %u",
pair._1(), pair._2()));
Идея как это реализовать пришла в голову довольно быстро:
fn _1() -> T;
fn _2() -> T;
}
impl <T>(T, T): TupleVal<T> {
fn _1() -> T {
let (a, _) = self;
a
}
fn _2() -> T {
let (_, b) = self;
b
}
}
Что само собой не скомпилировалось, так как компилятор отказался возвращать ссылку на элемент кортежа без указания времени жизни самого кортежа. Тоесть, компилятору необходимо “сказать” о том, что возвращаемый элемент кортежа будет жить не больше чем сам кортеж, что можно сделать так:
fn _1(&self) -> &self/T;
fn _2(&self) -> &self/T;
}
impl <T>(T, T): TupleVal<T> {
fn _1(&self) -> &self/T {
match *self { (ref a, _) => a } // Первый способ получить значения кортежа
}
pure fn _2(&self) -> &self/T {
let &(_, ref b) = self; // Второй способ получить значения кортежа
b
}
}
Во втором случае используется ключевое слово
Следующим не очевидным для меня моментом было использование ключевого слова
Да, вариант 2 не будет работать как минимум до Rust 0.7.
А к такому как вы относитесь?
let a = 5;
let a = 7;
Нормально отношусь…