Я хотел бы разветвиться и выбрать реализацию Trait для использования в функции во время выполнения (см. poly_read
в примере кода ниже). Трейт-объект строится внутри ветвей выражения if и должен жить только в течение жизни poly_read
, но мне нужно Box
его, потому что трейт не может быть заимствован из ветви выражения, вплоть до привязки, которую я Пытаюсь присвоить.
Я логически понимаю, почему заимствование заканчивается слишком рано, но кажется, что средство проверки заимствования должно иметь возможность расширить заимствование до окружающей области, когда значение выражения if привязано. Я понимаю, что это, вероятно, наивное представление, но я хотел бы больше понять, почему это невозможно.
Я немного недоволен решением, которое у меня есть сейчас, потому что оно требует выделения кучи, хотя я чувствую, что мне это не нужно, так как я держусь за коробку только на время жизни функции. Я полагаю, это потому, что мы не знаем размер reader
, который потребуется в стеке до тех пор, пока не будет взята ветвь, но нельзя ли просто представить его как объединение в компиляторе, поскольку мы, по крайней мере, знаем максимальный размер .
Кроме того, я на самом деле не знаю, насколько обоснованно мое беспокойство по поводу того, что Box
выделяется в куче, с самого начала. В целом, насколько дорогая стоимость бокса?
#![feature(io)]
#![feature(path)]
const BYTES: &'static [u8] = &[1u8, 2, 3, 4, 5];
const PATH: &'static str = "/usr/share/dict/words";
use std::old_io::{File, Reader, BufReader};
fn read(r: &mut Reader) {
let some_bytes = r.read_exact(5).unwrap();
assert!(some_bytes.len() == 5);
println!("{:?}", some_bytes);
}
fn poly_read(from_file: bool) {
// Is there any way to extend the lifetime of the ``&mut Reader`` in these branch arms without
// boxing them as I'm doing now. It seems wasteful to do a heap allocation when the actual
// borrow only needs to happen for body of poly_read?
let mut reader = if from_file {
Box::new(File::open(&Path::new(PATH)).unwrap()) as Box<Reader>
// Would like to say:
// File::open(&Path::new(FILE)).unwrap() as &mut Reader
} else {
Box::new(BufReader::new(BYTES)) as Box<Reader>
// Would like to say:
// BufReader::new(BYTES) as &mut Reader
};
// It feels like I'd like the lifetime of values returned from if expressions to be of the
// surrounding scope, rather than the branch arms.
read(&mut reader);
}
fn main() {
poly_read(true);
poly_read(false);
}