除了新关键字之外,原始标识符的用例有哪些?
What are the use cases of raw identifiers besides new keywords?
与 Rust 2018 一样,我们现在有 raw identifiers:
This feature is useful for a few reasons, but the primary motivation was inter-edition situations. For example, try
is not a keyword in the 2015 edition, but is in the 2018 edition. So if you have a library that is written in Rust 2015 and has a try
function, to call it in Rust 2018, you'll need to use the raw identifier.
除了上面说的,还有其他的优势吗?是否有计划使关键字与上下文相关,例如您可以使用 type
作为变量的标识符吗?为什么我应该使用像 r#type
这样的神秘语法而不是 ty
或其他东西?
需要 raw_identifiers
,您可以使用 type
和其他关键字作为 variable/struct/etc。标识符:
#![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.
Why I should use a cryptic syntax like r#type
instead of ty
or something else?
有时字段名称会在 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#
语法。以另一种方式解决这个特定问题可能更容易。
因此,据我所知,"using API from another edition" 是原始标识符的唯一真实用例。 具有这样的语法 "just for the case" 是不过,这是一件好事。
与 Rust 2018 一样,我们现在有 raw identifiers:
This feature is useful for a few reasons, but the primary motivation was inter-edition situations. For example,
try
is not a keyword in the 2015 edition, but is in the 2018 edition. So if you have a library that is written in Rust 2015 and has atry
function, to call it in Rust 2018, you'll need to use the raw identifier.
除了上面说的,还有其他的优势吗?是否有计划使关键字与上下文相关,例如您可以使用 type
作为变量的标识符吗?为什么我应该使用像 r#type
这样的神秘语法而不是 ty
或其他东西?
需要 raw_identifiers
,您可以使用 type
和其他关键字作为 variable/struct/etc。标识符:
#![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.
Why I should use a cryptic syntax like
r#type
instead ofty
or something else?
有时字段名称会在 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#
语法。以另一种方式解决这个特定问题可能更容易。
因此,据我所知,"using API from another edition" 是原始标识符的唯一真实用例。 具有这样的语法 "just for the case" 是不过,这是一件好事。