除了新关键字之外,原始标识符的用例还有哪些?

时间:2018-06-23 10:29:24

标签: rust rust-2018

与Rust 2018一样,我们现在有raw identifiers

  

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

除了以上所述,还有其他优势吗?是否有计划使关键字具有上下文相关性,例如您可以使用type作为变量的标识符吗?为什么我应该使用像r#type这样的神秘语法而不是ty或其他东西?

2 个答案:

答案 0 :(得分:4)

  

为什么我应该使用像r#type这样的神秘语法而不是ty或其他东西?

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

"type": 27,

...那么原始标识符可以帮助您:

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

另一方面,Serde已经可以实现您想要的目标:the #[serde(rename = "name")] attribute。保留的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”是原始标识符的唯一实际用例。具有这样的语法“仅适用于案例”是一个不错的选择事情。

答案 1 :(得分:0)

clap_app!内,您可以使用raw_identifiers和其他关键字作为变量/ struct / etc。标识符:

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`
}