- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
阅读时the answer for another question , 我看到了这个结构 [1]:
struct Clipboard {
marker: PhantomData<()>,
}
虽然我见过 PhantomData
的其他用途,它们都被一个有趣的类型参数化了,比如 PhantomData<&'a [u8]>
或 PhantomData<T>
.您为什么要创建结构,使其表现就好像它包含一个空元组一样?
[1]:有点诗意,因为我实际上写了另一个答案,但被要求解释为什么我做了我所做的。评论太长了。
最佳答案
在这种情况下,剪贴板是一个全局共享资源,在您打开它时不会给您任何标记。不先打开剪贴板就尝试使用它是一件坏事。如果您做了直接的事情并创建了一个空结构,那么您可能忘记调用正确的构造函数方法:
struct Clipboard;
impl Clipboard {
fn new() -> Clipboard {
println!("Clipboard opened");
Clipboard
}
fn copy(&self) -> String { "copied".into() }
}
let c = Clipboard::new(); // Correct
println!("{}", c.copy());
let c = Clipboard; // Nope, didn't open the clipboard properly
println!("{}", c.copy()); // But can still call methods!?!?!
让我们尝试一个内部有虚拟值的元组结构:
struct ClipboardWithDummyTuple(());
impl ClipboardWithDummyTuple {
fn new() -> ClipboardWithDummyTuple {
println!("Clipboard opened");
ClipboardWithDummyTuple(())
}
fn copy(&self) -> String { "copied".into() }
}
let c = ClipboardWithDummyTuple::new(); // Correct
println!("{}", c.copy());
let c = ClipboardWithDummyTuple;
println!("{}", c.copy()); // Fails here
// But because `c` is a method, not an instance
这样更好,但错误发生的时间比我们希望的要晚;它仅在我们尝试使用剪贴板时发生,而不是在我们尝试构建它时发生。让我们尝试创建一个具有命名字段的结构:
struct ClipboardWithDummyStruct {
// warning: struct field is never used
dummy: (),
}
impl ClipboardWithDummyStruct {
fn new() -> ClipboardWithDummyStruct {
println!("Clipboard opened");
ClipboardWithDummyStruct { dummy: () }
}
fn copy(&self) -> String { "copied".into() }
}
let c = ClipboardWithDummyStruct::new(); // Correct
println!("{}", c.copy());
let c = ClipboardWithDummyStruct; // Fails here
// But we have an "unused field" warning
所以,我们更接近了,但这会产生一个关于未使用字段的警告。我们可以使用#[allow(dead_code)]
关闭该字段的警告,或者我们可以将该字段重命名为_dummy
,但我相信有更好的解决方案 — PhantomData
:
use std::marker::PhantomData;
struct ClipboardWithPhantomData {
marker: PhantomData<()>,
}
impl ClipboardWithPhantomData {
fn new() -> ClipboardWithPhantomData {
println!("Clipboard opened");
ClipboardWithPhantomData { marker: PhantomData }
}
fn copy(&self) -> String { "copied".into() }
}
let c = ClipboardWithPhantomData::new(); // Correct
println!("{}", c.copy());
let c = ClipboardWithPhantomData; // Fails here
这不会生成任何警告,并且 PhantomData
用于指示正在发生“不同”的事情。我可能会对结构定义发表一些评论,以说明我们为何以这种方式使用 PhantomData
。
这里的很多想法都源于一个半相关的Rust issue about the correct type for an opaque struct .
关于rust - 为什么我要创建一个只有 `PhantomData<()>` 成员的结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34603635/
我有一个看起来像这样的特质: trait Handler { fn handle(&self, msg: &Message, connection: &mut C); } 实例应该被链接起来,
阅读时the answer for another question , 我看到了这个结构 [1]: struct Clipboard { marker: PhantomData, } 虽然我
我正在尝试开发一种批处理系统。在其中我想使用某种 Process 结构,它拥有所有与流程相关的部分。当前的实现使用 PhantomData 来强制执行类型约束: pub struct Process,
我想创建一个通用元组结构 Producer可以容纳任何类型 P它实现了特征 Produce ,定义如下。这会产生(预期的)注释错误: trait Produce { fn get(&mut s
这是拍摄 out of context所以看起来有点奇怪,但我有以下数据结构: use std::marker::PhantomData; pub struct Map { data: Vec
我发现 PhantomData 的概念在 Rust 中相当困惑。我在基于 FFI 的代码中广泛使用它来限制对象的生命周期,但我仍然不确定我是否正确地执行了此操作。 这是我经常最终使用它的人为示例。例如
我的结构包含不安全代码和指向另一种结构的原始可变指针。不安全结构只能在另一个结构的生命周期内使用,但不能为指针指定生命周期。我发现 std::marker::PhantomData 可以用于这个未使用
我在查看一些 Rust 源代码时发现了一种名为 PhantomData 的数据类型。我正在浏览 Rust 文档并在互联网上搜索了很多。但是,我无法理解这种数据类型在 rust 中的实际用途。如果可能的
PhantomData与 Copy 互动以一种令人惊讶的方式: use std::marker::PhantomData; #[derive(Copy, Clone)] pub struct Seco
我知道下面的代码是 hacky,但它可以被称为安全和惯用的 Rust 吗?有更好的方法吗? // needs to do 'rustup default nightly' to run under v
This question already has answers here: Why is it useful to use PhantomData to inform the compiler t
在 Rustonomicon's guide to PhantomData ,有一部分是关于如果 Vec 会发生什么-like struct 有 *const T字段,但没有 PhantomData
我正在尝试创建一种类型,它通过网络发送和接收数据并将字节序列化/反序列化为声明的类型。为此,我一直在使用 PhantomData输入 std .但是,我最近遇到了一种情况,我想让我的方法采用 &mut
在this question有人评论说您可以使用 PhantomData 添加绑定(bind)到结构内原始指针的生命周期。我想我会尝试在我一直在处理的现有代码段上执行此操作。 这是我们的(最小化)起点
我知道 PhantomData旨在使用数据类型定义中的生命周期或类型参数,否则这些参数将不会被使用。我最近在查看 Rc 的定义在Rust std lib并注意到它似乎使用了 PhantomData ,
这个问题在这里已经有了答案: Deriving a trait results in unexpected compiler error, but the manual implementation
我是一名优秀的程序员,十分优秀!