gpt4 book ai didi

rust - 如何要求 Rust 方法的泛型移动参数与对象一样长?

转载 作者:行者123 更新时间:2023-11-29 08:14:35 25 4
gpt4 key购买 nike

我正在编写一个包含 Lua 解释器的 Rust 程序,我需要将几种类型的对象保存到 Lua 管理的内存(用户数据)中,以便 Lua 调用它们的方法。通常它们会类似于 Rc<T>。 , 以及知道正确类型的适当方法包装器将被注册。

如果我一次只接受一种类型,我可以安全地将对象传递给 Lua 状态:

struct Foo<'a> {
badref: &'a u32,
}

struct LuaState<T> {
/* ... */
_foo: PhantomData<T>,
}

impl<T> LuaState<T> {
fn hide(&mut self, foo: T) {}
}

fn main() {
let mut l = LuaState{_foo: PhantomData};
{
let n = 7u32;
let foo = Foo { badref: &n };
/* Correctly fails to compile, since l can keep a (hidden)
* reference to n after its scope ends */
l.hide(foo);
}
}

我真的很想要LuaState不需要类型参数,而是有一个通用的 hide方法:

struct LuaState {
/* ... */
}
impl LuaState {
fn hide<T>(&mut self, foo: T) {}
}

...它不会为任何 T 编译的地方其中包含不超过 LuaState 的引用,就像我在上面一次可以使用一种类型一样。我接近了:

trait LuaAble<'a> {}
impl<'a> LuaAble<'a> for Foo<'a> {}

struct LuaState<'a> {
marker: PhantomData<LuaAble<'a>>,
}

impl<'a> LuaState<'a> {
fn hide<T: LuaAble<'a>>(&mut self, foo: T) {}
}

这几乎可以工作;它停止了上面的悬垂引用示例,但也有可能错误地实现了特征:

impl<'a, 'b> LuaAble<'b> for Foo<'a> {}

由于生命周期不再绑定(bind)在一起,这再次让隐藏的悬挂引用案例得以编译。

有什么方法可以防止按值将不能活到&self 的东西传递给方法吗? ?我对任何想法都持开放态度,无论他们在特征、生命周期方面做了一些聪明和/或糟糕的事情,for<'a> ,重组我的代码等。

最佳答案

你可以嵌入一个假的生命周期'aLuaState<'a>并要求 T: 'ahide() :

struct LuaState<'a> {
_foo: PhantomData<&'a ()>,
}

impl<'a> LuaState<'a> {
fn hide<T: 'a>(&mut self, foo: T) {}
}

我不是 100% 确定这是正确的,但它似乎适用于您提供的示例。 (full playpen)

消除 PhantomData缺点是编译器不再理解 LuaState逻辑上拥有一个 Rc<T>对于各种T .如果(看起来)丢弃 LuaState,这可能会导致健全性问题可能会下降 T值(value)观。

关于rust - 如何要求 Rust 方法的泛型移动参数与对象一样长?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35952391/

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