5

与 Rust 2018 一样,我们现在拥有原始标识符

出于几个原因,此功能很有用,但主要动机是跨版本情况。例如,try不是 2015 年版中的关键字,而是 2018 年版中的关键字。因此,如果您有一个用 Rust 2015 编写的库并且有一个try函数,要在 Rust 2018 中调用它,您将需要使用原始标识符。

除了上面所说的,还有其他的好处吗?是否有计划使关键字与上下文相关,例如您可以type用作变量的标识符?为什么我应该使用一种神秘的语法,比如r#type代替ty或其他东西?

4

2 回答 2

7

为什么我应该使用一种神秘的语法,比如r#type代替ty或其他东西?

有时字段的名称会在 Rust 程序之外使用。例如,使用 Serde 序列化数据时,在输出中使用字段名称(例如 JSON)。因此,如果您需要 JSON 输出:

"type": 27,

...然后原始标识符可以帮助您:

#[derive(Serialize)]
struct Foo {
    r#type: u32,
}

另一方面...... Serde 已经有一种方法可以实现您想要的:#[serde(rename = "name")]属性。保留的 Rust 关键字是引入此属性的原因之一。

#[derive(Serialize)]
struct Foo {
    #[serde(rename = "type")]
    ty: u32,
}

同样,Debug输出也使用其输出中的字段名称。所以如果你想要输出Foo { type: 27 },你可以使用原始标识符:

#[derive(Debug)]
struct Foo {
    r#type: u32,
}

另一方面......如果确切的Debug输出对你来说很重要,你可以简单地自己实现它:

impl fmt::Debug for Foo {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("Foo")
            .field("type", &self.ty)
            .finish()
    }
}

所以在实践中,我不明白为什么要为此目的使用原始标识符,因为在r#使用该名称的任何地方都必须使用奇怪的语法。以另一种方式解决这个特定问题可能更容易。

因此,据我所知,“使用另一个版本的 API”是原始标识符的唯一真实用例。不过,拥有这样的语法“只为案例”是一件好事。

于 2018-06-23T10:54:43.317 回答
0

如果需要,raw_identifiers您可以使用type和其他关键字作为变量/结构/等。身份标识:

#![feature(rust_2018_preview)]
#![feature(raw_identifiers)]

struct r#let {} // just warnings: struct is never used: `let` and type `let` should have a camel case name such as `Let`

fn main() {
    let r#type = 0; // just warning: unused variable: `type`
}

但是,它不适用于每个关键字:

let r#super = 0; // error: `r#super` is not currently supported.
于 2018-06-23T10:33:10.583 回答