Rfcs: Numeric struct fields

Created on 27 Apr 2016  路  13Comments  路  Source: rust-lang/rfcs

E.g.,

struct Foo {
    0: String,
    42: i32,
}

fn main() {
    let foo = Foo { 42: 0, 0: "Hello".to_owned() };
    let x: i32 = foo.42;
}

Helps bridge the gap between structs and tuples.

cc @nikomatsakis

T-lang

All 13 comments

I dislike this, since I do not see an actual usecase.

This is a part of https://github.com/rust-lang/rfcs/pull/1506, that RFC doesn't permit explicit numeric fields in struct definitions though.

To clarify, #1506 allows tuple struct's fields to be referenced (by index) in a braced expression. This issue is about identifying braced struct fields by number

This issue is about identifying braced struct fields by number

I see. I don't see much motivation for this though.

I like this, because it simplifies the language. Would this allow for:

struct Foo {
    0: String,
    1: i32,
}

let _ = Foo("hi".to_string(), 20);

?

@bjz,
I think rust already support tuple like struct using :

struct Foo(String,i32);
let _ = Foo("hi".to_string(), 20);

I think if we allow numeric struct field, we must specify the field name like current rules because struct can have field like this:

struct Foo {
   1: i32,
   bar: i32,
   0: String
}

In my humble opinions, numeric struct field is weird... At least I never see such feature in other language

numeric struct field is weird... At least I never see such feature in other language

I believe the precedent would be ML, where tuples are sugar for records.

@bjz: I don't think that this would or should enable the named tuple construction syntax, since a tuple constructor is a function, and thus in the value namespace, which a struct constructor is not.

Creating entries in a namespace just based on the naming of its fields seems weird.

I've been vaguely in favor of this, because I feel like it makes things more uniform, and is a further step closer to unifying "tuple-like" structs and "named field" structs.

For example, if I have a struct like

struct Foo(X);

I could now convert it to the following:

struct Foo { 0: X }
fn Foo(x: X) -> Foo { ... }

in a (more) backwards compatible way.

(Patterns might still behave differently, I believe, though one could imagine saying that Foo(pat) where Foo is a struct name should be short-hand for Foo { 0: pat }.)

I would have to see actual compelling use cases to put this into positive territory in my evaluation. Otherwise I think the sheer weirdness of it outweighs the theoretical improvement in uniformity. ("Everything that is syntactically legal, that the compiler will accept, will eventually wind up in your code base." Like, I'd be fine with allowing it, for uniformity, if people had the good sense to not actually use it, but...)

Non-consecutive numeric fields as in the first example are _especially_ weird and would be a new thing entirely.

There's a concrete benefit to this unification: currently there's no way to perform field access without the potential for autodereferencing kicking in. When using a macro to wrap an unsafe pattern into a safe macro call, any unintentional dereferencing can break the safety guarantees.

(For an example, see offset_of!() from the field-offset crate)

The only way to prevent autodereferencing is to use destructuring syntax:

let Foo { ref field, .. } = x

But this destructuring only works for normal structs. You can't destructure a tuple struct in the same way, at least not without knowing the length of the tuple.

Triage ping @nrc

I think this is not really worth doing - like if it were free I'd take it (probably) but I don't think it is even worth the effort to discuss an RFC and/or review a patch.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

steveklabnik picture steveklabnik  路  4Comments

3442853561 picture 3442853561  路  4Comments

mqudsi picture mqudsi  路  3Comments

marinintim picture marinintim  路  3Comments

mqudsi picture mqudsi  路  3Comments