gpt4 book ai didi

rust - 如何将Rc >转换为具体类型?

转载 作者:行者123 更新时间:2023-12-03 11:37:05 26 4
gpt4 key购买 nike

我想制作一个文本输出可以显示在控制台上或存储在内部缓冲区中的结构。如果文本是缓冲的,那么我需要一个可以退还文本内容的方法。
为了这个目的,我使用了一个名为writer的属性,它是dyn std::io::Write(包装到Rc<RefCell<>>中,因为我的真实代码需要它)。然后在结构构造上,我为此属性创建一个io::stdout()实例或Vec::<u8>::new()实例。

use std::rc::Rc;
use std::cell::RefCell;
use std::io;

struct A {
// Rc<RefCell<>> is needed in my real code
writer: Rc<RefCell<dyn io::Write>>,
}

impl A {
pub fn new() -> Self {
Self { writer: Rc::new(RefCell::new(io::stdout())) }
}

pub fn new_buffered() -> Self {
Self { writer: Rc::new(RefCell::new(Vec::<u8>::new())) }
}

pub fn write(&self, s: &str) {
let mut writer = self.writer.borrow_mut();
writeln!(writer, "{}", s).unwrap();
}

/// Returns None if the struct is not buffered, otherwise a copy of the buffered output.
pub fn get_buffer(&self) -> Option<String> {
match GET_VEC_U8() { // <- Unable to implement this line
Some(vec_u8) => {
Some(String::from_utf8(vec_u8.clone()).unwrap())
},
None => None,
}
}
}

fn main() {
let a = A::new();
a.write("foo");
println!("Buffer: {:?}", a.get_buffer());

let b = A::new_buffered();
b.write("bar");
println!("Buffer: {:?}", b.get_buffer());
}
问题
但是当作者是 get_buffer()时,我不知道如何提取文本内容(方法 Vec<u8>)。我该怎么做 ?
我的尝试
我试图将属性包装成 Box:
struct A {
writer: Rc<RefCell<Box<dyn io::Write>>>,
}
然后在上面使用 Box::downcast():
impl A {
pub fn get_buffer(&self) -> Option<String> {
let writer = self.writer.borrow();
match (*writer).downcast::<Vec<u8>>() {
Ok(vec_u8) => Some(String::from_utf8(vec_u8.clone()).unwrap()),
Err(_) => None,
}
}
}
但是我得到这个错误:
error[E0599]: no method named `downcast` found for struct `std::boxed::Box<dyn std::io::Write>` in the current scope
--> src/main.rs:27:25
|
27 | match (*writer).downcast::<Vec<u8>>() {
| ^^^^^^^^ method not found in `std::boxed::Box<dyn std::io::Write>`

最佳答案

正如@SvenMarnach在评论中所写,根据io::Write编写自定义特征可以是一种解决方案

use std::rc::Rc;
use std::cell::RefCell;
use std::io::{self, Stdout};

trait MyWrite: io::Write {
fn get_buffer(&self) -> Option<String>;
}

impl MyWrite for Stdout {
fn get_buffer(&self) -> Option<String> {
None
}
}

impl MyWrite for Vec<u8> {
fn get_buffer(&self) -> Option<String> {
Some(String::from_utf8(self.clone()).unwrap())
}
}

struct A {
// Rc<RefCell<>> is needed in my real code
writer: Rc<RefCell<dyn MyWrite>>,
}

impl A {
pub fn new() -> Self {
Self { writer: Rc::new(RefCell::new(io::stdout())) }
}

pub fn new_buffered() -> Self {
Self { writer: Rc::new(RefCell::new(Vec::<u8>::new())) }
}

pub fn write(&self, s: &str) {
let mut writer = self.writer.borrow_mut();
writeln!(writer, "{}", s).unwrap();
}

/// Returns None if the struct is not buffered, otherwise a copy of the buffered output.
pub fn get_buffer(&self) -> Option<String> {
let writer = self.writer.borrow();
writer.get_buffer()
}
}

fn main() {
let a = A::new();
a.write("foo");
println!("Buffer: {:?}", a.get_buffer());

let b = A::new_buffered();
b.write("bar");
println!("Buffer: {:?}", b.get_buffer());
}

关于rust - 如何将Rc <RefCell <dyn io::Write >>转换为具体类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63501407/

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