Каковы варианты использования необработанных идентификаторов помимо новых ключевых слов?

Как и в Rust 2018, теперь у нас есть необработанные идентификаторы:

Эта функция полезна по нескольким причинам, но основной мотивацией были ситуации между выпусками. Например, try не является ключевым словом в версии 2015 года, но есть в версии 2018 года. Так что если у вас есть библиотека, написанная на Rust 2015 и имеющая try Чтобы вызвать его в Rust 2018, вам нужно использовать необработанный идентификатор.

Есть ли другие преимущества, кроме указанных выше? Есть ли планы сделать ключевые слова контекстными, например, вы можете использовать type как идентификатор для переменных? Почему я должен использовать загадочный синтаксис, такой как r#type вместо ty или что-то другое?

2 ответа

Решение

Почему я должен использовать загадочный синтаксис, такой как r#type вместо ty или что-то другое?

Иногда имена полей используются вне вашей программы Rust. Например, при сериализации данных с помощью Serde в выходных данных используется имя поля (например, JSON). Так что если вам нужен вывод JSON с этим:

"type": 27,

... тогда вам могут помочь необработанные идентификаторы:

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

С другой стороны... у Серде уже есть способ достичь того, чего вы хотите: #[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 из другого издания" - единственный реальный вариант использования необработанных идентификаторов. Впрочем, наличие такого синтаксиса "на всякий случай" - это хорошо.

Ineed с 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.
Другие вопросы по тегам