我正在学习铁 rust ,并想深入研究标记特征.官方文件中的定义对我来说不清楚:https://doc.rust-lang.org/std/marker/index.html

定义:

表示类型的基本属性的原始特征和类型.铁 rust 类型可以根据其内在特性以各种有用的方式进行分类.这些分类被表示为特征.

  1. 为什么我们要定义一组特殊的性状,并将这组性状称为"标记性状"?这些特征有什么特别之处?

  2. 我是否正确理解了所有这些特征都有默认实现,并且我们可以在没有实现的情况下为我们的定制 struct 派生这些特征?

你能用例子回答吗?

推荐答案

标记性状用于mark个类型,约有property个.它们通常没有任何关联的类型和方法,用来告诉编译器有关类型的某些属性.请注意,其中一些特征是auto traits,这意味着编译器将自动为类型实现它们,如果这样做是安全的(您仍然可以手动实现它们,但它可能需要unsafe个关键字).

目前std::marker模组有5个 solidity 状(rustc 1.70.0).它们有以下含义.如果类型T实现:

  • Copy表示使用按位复制可以是Cloned
  • 它意味着类型T的值可以跨线程边界发送
  • Sync它意味着类型T的值可以在线程之间共享(即&TSend)
  • Sized表示类型T的大小在编译时是已知的
  • Unpin表示类型T的值可以在其为pinned之后移动

在以上SendSyncUnpin中,有三个是汽车特性.在std::panic模块中还有两个更稳定的汽车特性.

来回答你们的问题.

为什么我们要定义一组特殊的性状,并将这组性状称为"标记性状"?这些特征有什么特别之处?

我们将这些特征称为"标记",以区分接口的实现和向编译器提供有关类型属性的信息,这两者都是通过特征来完成的.然而,它们并不是special.这些都是正常的特征,就像所有其他特征一样.这只是我们人类的一个语义名称.

我是否正确理解了所有这些特征都有默认实现,并且我们可以在没有实现的情况下为我们的定制 struct 派生这些特征?

严格地说,它们没有default implementation个,因为按照这个术语,我们理解特征方法的默认实现,该方法与实现给定特征的所有类型共享,并且可以被它们覆盖.比如std::io::Write::write_all.

但是,因为它们没有任何方法,所以我们可以简单地为我们的类型实现它们,只需说明该类型实现了这一特性.例如,我们可以像这样为我们的类型实现Copy(我们将使用#[derive(Clone)],这样我们就不必手动实现它,因为CloneCopysupertrait):

#[derive(Clone)]
struct Foo {
    a: i32,
    b: f32,
    c: bool,
}

impl Copy for Foo {}

您还可以实现自动特征,这是编译器没有自动实现的.例如,任何包含raw pointer的类型都会自动标记为!Send(negative implementations是编译器使用的不稳定特性).但是,如果在线程之间发送这种类型是safe,则可以为其显式实现Send(请注意,您必须使用unsafe关键字,因为错误的Send实现可能会导致未定义的行为:

struct Bar {
    ptr: *const (),
}

unsafe impl Send for Bar {}

但是,一个例外是特征Sized,它只能由编译器实现.try 手动实现它将导致E0322错误.

Rust相关问答推荐

为什么我需要在这个代码示例中使用&

从Rust调用C++虚拟方法即使在成功执行之后也会引发Access违规错误

将内部类型作为参数的泛型 struct 上的方法

在泛型 struct 的字段声明中访问关联的Conant

如何在 struct 的自定义序列化程序中使用serde序列化_WITH

如何为 struct 字段设置新值并在Ruust中的可变方法中返回旧值

如何高效地将 struct 向量中的字段收集到单独的数组中

`*mut[T]`与`*mut T`的区别

是否提供Bundle 在可执行文件中的warp中的静态文件?

Rust ndarray:如何从索引中 Select 数组的行

获取已知数量的输入

为什么特征默认没有调整大小?

如何将一个矩阵的列分配给另一个矩阵,纳尔代数?

为什么是&mut发送?线程如何在安全的 Rust 中捕获 &mut?

将引用移动到线程中

decltype、dyn、impl traits,重构时如何声明函数的返回类型

Rust 中的自动取消引用是如何工作的?

从 Axum IntoResponse 获取请求标头

预期的整数,找到 `&{integer}`

Cargo:如何将整个目录或文件包含在功能标志中?