与 Rust 2018 一样,我们现在有了原始标识符:
此功能很有用有几个原因,但主要动机是跨版本情况。例如,
try不是 2015 版中的关键字,而是 2018 版中的关键字。因此,如果您有一个用 Rust 2015 编写的库并且有一个try函数,要在 Rust 2018 中调用它,您需要使用原始标识符。
除了上面提到的还有其他优点吗?是否有计划使关键字与上下文相关联,例如您可以type用作变量的标识符?为什么我应该使用像r#type代替ty或其他东西这样的神秘语法?
为什么我应该使用像
r#type代替ty或其他东西这样的神秘语法?
有时字段的名称在 Rust 程序之外使用。例如,当使用 Serde 序列化数据时,在输出中使用字段名称(例如 JSON)。因此,如果您需要这样的 JSON 输出:
"type": 27,
Run Code Online (Sandbox Code Playgroud)
...然后原始标识符可以帮助您:
#[derive(Serialize)]
struct Foo {
r#type: u32,
}
Run Code Online (Sandbox Code Playgroud)
在另一方面... SERDE已经有一种方式来实现你想要的:该#[serde(rename = "name")]属性。保留 Rust 关键字是引入此属性的原因之一。
#[derive(Serialize)]
struct Foo {
#[serde(rename = "type")]
ty: u32,
}
Run Code Online (Sandbox Code Playgroud)
同样,Debug输出也在其输出中使用字段名称。所以如果你想要 output Foo { type: 27 },你可以使用原始标识符:
#[derive(Debug)]
struct Foo {
r#type: u32,
}
Run Code Online (Sandbox Code Playgroud)
另一方面......如果确切的Debug输出对你来说很重要,你可以简单地自己实现它:
impl fmt::Debug for Foo {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Foo")
.field("type", &self.ty)
.finish()
}
}
Run Code Online (Sandbox Code Playgroud)
所以在实践中,我不明白为什么要为此目的使用原始标识符,因为r#在使用该名称的任何地方都必须使用奇怪的语法。以另一种方式解决这个特定问题可能更容易。
因此,在我看来,“使用另一个版本的 API”是原始标识符的唯一真正用例。不过,拥有这样一个“仅适用于案例”的语法是一件好事。