2
votes

I just started learning Rust and noticed that the following code works, even though the various options inside the enum seem to get propagated to outside of the enum, thus being in the same namespace as the structs:

enum FooBar { Foo(int), Bar(uint) }
struct Foo { foo: int }
struct Bar { bar: uint }

This however causes a compiler error:

enum FooBar { Foo(int), Bar(uint) }
enum BarBaz { Bar(uint), Baz(f32) }

It almost seems as if structs and enums live in their own parallel universes. I would appreciate an explanation about how struct and enum typenames work in Rust and why this effect arises.

Also, can an already existing type (i.e. a struct) be one of the options inside the enum?

1
Rust's enums are tagged unions, and Foo, Bar, Baz are constructors. Rust's structs are records, with foo and bar as field names. They belong to different categories of names (or namespaces).user824425
@Rhymoid Still this design choice seems weird. You can mess up = Foo(42) with Foo {foo: 42} quite easily...Askaga
True. That's what happens when one tries to throw in the 'familiar' (but broken) C concepts in a new language, while also trying to mix it with modern ideas.user824425

1 Answers

2
votes

There are two namespaces at play here, the namespace for values and that for struct constructors.

Enum variant constructors are functions and thus live in the value namespace, e.g. you can write let f: fn(uint) -> FooBar = Foo; foo(1). It's not legal to declare two functions with the same in the same scope (how would one distinguish between them?).

Struct constructors are not functions or values, e.g. you can't assign them to a variable like the above, this means one can still distinguish between which name is meant because they're used in different context. Thus, there's no need to disallow having a name in two namespaces.

You can mess up = Foo(42) with Foo {foo: 42}

I don't think so... At the very least they are different type, so in most circumstances, the compiler will complain at you about mismatched types.