繁体   English   中英

生锈中的PhantomData类型用法

[英]PhantomData type usage in rust

我正在浏览一些生锈的源代码,我找到了一个名为PhantomData的数据类型。 我正在浏览生锈文档,并在互联网上搜索了很多。 但是,我无法理解这种数据类型的实际使用情况。 如果可能的话,有人可以用简单的方式向我解释一下吗?

pub struct GPIOD {
   _marker: PhantomData<*const ()>,
}

PhantomData结构用于向编译器发出信号,表明正在以某种方式使用对编译器透明的类型或生命周期。

引用文档:

向您的类型添加PhantomData字段会告诉编译器您的类型就像存储类型T的值一样,即使它不是真的。 在计算某些安全属性时使用此信息。

例如,如果我们查看切片[T]的迭代器类型: std::slice::Iter<'a, T> 及其使用src按钮的声明,我们将看到它实际上是这样声明的:

struct Iter<'a, T: 'a> {
    start: *const T,
    end: *const T,
    _phantom: PhantomData<&'a T>,
}

std经常使用指针算法来使优化更容易获得(虽然这并不支持在用户代码中使用指针算法)。 在这种情况下,我们需要向自己保证,两个原始指针(没有生命周期)所指向的数据比结构更长, 所以我们保留一个PhantomData<&'a T>来告诉编译器就像如果Iter拥有一个&'a T因此强制执行生命周期规则。

除了另一个答案,我想补充一个例子。 如在另一个答案中所述, PhantomData允许在2个结构之间添加任意的寿命依赖性。

假设您有一个结构来管理带有消息接收器的日志记录工具,以及一个结构,它表示向管理器发送消息的实际记录器。 虽然记录器不直接依赖于管理器,但管理器必须比记录器寿命长,以防止发送错误。

天真的代码不会在2个结构之间产生任何依赖:

struct LogManager {
    // ...
}

impl LogManager {
    fn logger(&self) -> Logger {
        // returns a fresh `Logger` that holds no reference to `LogManager`...
    }
}

struct Logger {
    // ...
}

现在,如果Logger拥有一个幻像引用,我们可以在两个结构之间强制依赖:

struct Logger<'a> {
    // ...
    _marker: PhantomData<'a ()>,
}

并在impl块中:

impl LogManager {
    fn logger(&self) -> Logger {
        Logger {
            // ...
            // Here, `Logger` will have a lifetime dependent of the `LogManager`'s
            // lifetime due to `PhantomData`:
            _marker: PhantomData,
        }
    }
}

现在,没有Logger实例可以比它来自的LogManager更长。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM