我想分支并决定在运行时在函数中使用的 Trait 实现(请参阅poly_read
在下面的代码示例中)。 Trait 对象是在 if 表达式的分支臂内部构造的,并且只需要在 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);
}
正如@Shepmaster 所指出的,有一种方法可以做到这一点,类似于这个答案 https://stackoverflow.com/a/28220053/155423 from a 上一个问题 https://stackoverflow.com/questions/28219519/are-polymorphic-variables-allowed.
解决这个问题的方法是预先声明two必要变量:aFile
, and a BufReader
:
fn poly_read(from_file: bool) {
// These two variables are predeclared so that they are in scope as
// long as `reader` is
let mut file_reader;
let mut buf_reader;
let mut reader = if from_file {
file_reader = File::open(&Path::new(PATH)).unwrap();
&mut file_reader as &mut Reader
} else {
buf_reader = BufReader::new(BYTES);
&mut buf_reader as &mut Reader
};
read(&mut reader);
}
另请参阅Rust 围栏上的这段代码。 http://is.gd/ZfSlC1.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)