如何在Rust中声明对泛型类型的结构体的引用?

0x6upsns  于 2023-08-05  发布在  其他
关注(0)|答案(1)|浏览(88)

我刚接触生 rust ,这很难用我的话来表达,但这里有一些代码:

use super::application::Application; // this is a trait

static mut sessions: Vec<&Session</* what to put in here?*/>> = Vec::with_capacity(8);

pub struct Session<T: Application> {
    app: Box<T>,
}

pub fn create_session<T: Application>(ini_file: &str, app: T) -> Session<T> {
    let session = Session {
        app: Box::new(app),
    };
    sessions.append(session);
    session
}

字符串
编译器需要泛型的类型,但实际上我认为它不应该,因为大小在引用中无关紧要,我希望这对任何实现应用程序的结构都是泛型的。
我应该如何声明sessions Vec?
我试过了
static mut sessions: Vec<&Session<T: Application>> = Vec::with_capacity(8);
static mut sessions: Vec<&Session> = Vec::with_capacity(8);
static mut sessions: Vec<&Session<dyn Application>> = Vec::with_capacity(8);(即使我认为不需要动态调度,也许我错了。
我也尝试了同样的拳击,而不是参考,但得到了同样的问题。

5kgi1eie

5kgi1eie1#

你的代码有很多问题,所以我已经解决了这些问题,以产生这个。

use std::sync::Mutex;

pub trait Application {}

pub trait SessionApplication: Sync {}
impl<T: Application + Sync> SessionApplication for Session<T> {}

static SESSIONS: Mutex<Vec<&dyn SessionApplication>> = Mutex::new(Vec::new());

pub struct Session<T> {
    pub app: T,
}

pub fn create_session<T>(app: T) -> &'static Session<T>
where
    T: Application + Sync,
{
    let session = Session { app };
    let session = Box::new(session);
    let session = Box::leak(session);
    SESSIONS.lock().unwrap().push(session);
    session
}

字符串

修复

不能在静态声明中分配,因此Vec::with_capacity是禁止的。我用的是Vec::new
Vec::append应该是Vec::push。如果你来自Python,list.append相当于Vec::push,而list.extend就像Vec::appendVec::extend
如果你使用的是static mut,那么create_session就会变得不安全,并且很容易被误用。我已经添加了一个互斥体,这样它就不需要可变性,这使得这里的一切都是安全的。
您可以创建一个Vec<Session<dyn Application>>或类似的值,但这样就不能从create_session返回任何包含T的值。我保留了Session<T>返回值,并添加了一个新的trait SessionApplication。这也使得Session中的Box变得不必要,所以我删除了它。

注意事项

这使用了Box::leak,它会泄漏内存。如果您从未从Vec中删除项目,那么这并不重要,因为该内存将永远使用,但如果您删除项目,您将需要大量的机器来回收该内存。
Box::leak是将会话置于静态状态并同时返回会话的唯一合理方法。你不能给予静态所有权,因为它会在Vec重新分配时移动项目,你不能返回所有权,因为它会被释放,而对它的引用仍然存在于Vec中。
我建议不使用静态或trait对象(dyn)的人新生 rust 。相反,把你的状态放在一个结构体中,并分别使用枚举。

相关问题