gpt4 book ai didi

rust - 我可以在运行时选择特征对象而不使用 Box 吗?

转载 作者:行者123 更新时间:2023-11-29 07:55:38 25 4
gpt4 key购买 nike

我想分支并决定在运行时在函数内使用的 Trait 实现(参见下面代码示例中的 poly_read)。 trait 对象是在 if 表达式的分支臂内部构造的,只需要在 poly_read 的生命周期内存在,但我需要 Box 它,因为 trait 不能从表达式臂中借用,直到我试图将其分配给的绑定(bind)。

我从逻辑上理解为什么借用过早结束,但当 if 表达式的值被绑定(bind)时,借用检查器似乎应该能够将借用扩展到周围的范围。我意识到这可能是一个幼稚的想法,但我想更多地了解为什么这是不可能的。

我对现在的解决方案有点不满意,因为它需要堆分配,尽管我觉得我不应该需要一个,因为我只在函数的生命周期内保留该框。我想这是因为我们不知道在采用分支之前堆栈上所需的 reader 的大小,但它不能只在编译器中表示为联合,因为我们至少知道最大尺寸。

顺便说一句,我实际上并不知道我对堆分配的 Box 的担忧从一开始就有多大意义。一般装箱的值(value)是多少?

#![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 所指出的,有一种类似于 this answer 的方法可以做到这一点来自previous question .

解决这个问题的方法是预先声明两个必要的变量:一个File和一个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);
}

另见 this code on the Rust playpen. .

关于rust - 我可以在运行时选择特征对象而不使用 Box<Trait> 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28264349/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com