Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何要求Rust方法的通用移动参数与对象一样有效?_Rust_Lifetime - Fatal编程技术网

如何要求Rust方法的通用移动参数与对象一样有效?

如何要求Rust方法的通用移动参数与对象一样有效?,rust,lifetime,Rust,Lifetime,我正在编写一个包含Lua解释器的Rust程序,我需要将几种类型的对象保存到Lua管理的内存(userdata)中,以便Lua调用这些对象上的方法。通常,它们类似于Rc,并且会注册知道正确类型的适当方法包装器 如果一次只接受一种类型,我可以安全地将对象传递到Lua状态: struct Foo<'a> { badref: &'a u32, } struct LuaState<T> { /* ... */ _foo: PhantomData&l

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

如果一次只接受一种类型,我可以安全地将对象传递到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);
    }
}
…它不会为任何
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) {}
}
trait LuaAble LuaAble{}
结构LuaState>,
}
恳求{
fn隐藏{}
这再次允许编译隐藏的悬挂引用案例,因为生命期不再绑定在一起


有没有什么方法可以防止通过价值观将不能活得像自己一样长的东西传递到方法中?我对任何想法都持开放态度,无论他们在特征、寿命方面做了聪明和/或糟糕的事情,因为你可以在
LuaState中嵌入一个假的寿命
'a
, } 恳求{
fn hide它不会为任何
t
编译,其中包含的引用不超过
LuaState
-也许我累了,但这似乎有太多的负面条件。只有在
LuaState
中存储的所有引用都超过该状态时,您才希望编译它(“状态存在时,状态中的所有引用均有效”),不是吗?是的,听起来不错。这看起来很有希望,也比我一直担心的要简单!我稍后会有一个剧本。我没有意识到
t:
是合法的。谢谢!我在铁锈书或参考资料中找不到任何关于
t:
的提及;它似乎在本RFC中有定义:
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> {}
struct LuaState<'a> {
    _foo: PhantomData<&'a ()>,
}

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