Is it possible to define a field with the same name as a keyword?
Asked Answered
C

2

10

I am using Rust to write a REST API and my Flutter client defines the entity like this:

class WordDefinition {
  String type;
  String name;
  List<String> values;

  WordDefinition({
    this.type,
    this.name,
    this.values,
  });
}

The client uses type as a entity field name. In Dart it works fine, but in the server side Rust I could not define the field name like this:

use serde::{Deserialize, Serialize};

#[derive(Deserialize, Serialize)]
pub struct WordDefinition {
    pub type: String,
    pub text: String,
    pub translations: Vec<String>,
}
error: expected identifier, found keyword `type`
 --> src/lib.rs:5:9
  |
4 | pub struct WordDefinition {
  |            -------------- while parsing this struct
5 |     pub type: String,
  |         ^^^^ expected identifier, found keyword

What should I do to avoid the Rust keyword conflict? Is it possible to define a entity name using type like this in Rust?

Catamite answered 7/11, 2021 at 10:19 Comment(2)
Use r#type: play.rust-lang.org/… - or you can use a different field name and use #[serde(rename = "type")]Meredi
Don't know if it was the case when this question was posted, but the current compiler error contains a help annotation showing what you can do: "escape type to use it as an identifier ... pub r#type: String".Microbicide
P
23

You can use "raw identifiers" by prefixing a keyword withr# like this:

struct Foo {
  r#type: String
}

You can also give it one name in your Rust code and use #[serde(rename)] to serialize to a different name. For example, this changes kind into type during serialization:

struct Foo {
  #[serde(rename = "type")]
  kind: String
}

Personally, I prefer the second way, because I find r#type a bit annoying to type and ugly, but that's just preference, there's not a "right" way

Parotic answered 7/11, 2021 at 11:20 Comment(3)
Renaming the field to something completely different might be surprising. Java, for example, uses clazz (for "class"), which is idiomatic, but looks odd. Personally, I'd suffix with an underscore (so type_), but I don't know whether that's idiomatic Rust.Scroll
@RogerLipscombe I replace by kind cause it's a lot used even in std doc.rust-lang.org/std/?search=kind and kind is a synonym of type wordreference.com/enfr/kind. I'm never see type_ and I hate random underscore, like ___python___. clazz look weird and there is no class in Rust anyway. One can use r#type if you really want to use typeIntrusion
Hard to say whether it's idiomatic, it's not a pattern I've seen used much, inside rustc the abbreviation ty is very common, but as an editor pointed out, kind definitely gets used a lot in this contextParotic
D
0

To summarize the comments and the accepted answer, I'd like to cite the Rust repository and note that officially the solution is to use raw identifiers or trailing underscores, based on suggestions from the Rust style team:

When a name is forbidden because it is a reserved word (such as crate), either use a raw identifier (r#crate) or use a trailing underscore (crate_). Don't misspell the word (krate).

b9be3c4/src/doc/style-guide/src/advice.md

Dropout answered 21/4, 2024 at 13:25 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.