Generics with struct type


#1

Hi all,

Are the traits the only way to express genericity for functions ?

For example, I can’t use a generic type for this:

struct S {
    x: usize,
    y: usize,
}

fn f1<T>(s: T) {
    let u = s.x;
}

fn main() {
    let s = S { x:1, y:1 };
    let f = f1(s);
}

   Compiling playground v0.0.1 (file:///playground)
error[E0609]: no field `x` on type `T`
 --> src/main.rs:7:15
  |
7 |     let u = s.x;
  |               ^

error: aborting due to previous error

error: Could not compile `playground`.

To learn more, run the command again with --verbose.

except when defining a trait bound for T. But as T is a struct, is the only way to achieve this to define getters for each member used (e.g.: for x here) in a trait and bound it to T?

Thanks for your help.


#2

The struct itself can be generic, like struct S<T> { x: T, y: T }, but otherwise no, there’s no way to have generic field access.


#3

Thanks @cuviper, that’s what I expected.

If we could restrict the T type to a specific set (for example: T is S or V, if V is another struct) , the compiler could check it and it might be possible (but there’re possibly other more complicated situations where it would be difficult to check).


#4

I’m not sure this is the right way but what I normally do is add a property that stores T.

struct Foo<T> {
  bar: ...,
  baz: T
}

so then in the code I can do:

  let u = s.baz.x;

#5

Right now, you can manually accomplish this with a custom enum capturing the predefined types you expect. However, there’s been some discussion about allowing anonymous sum types:


#6

FYI, this thread just opened on the internals forum:


#7

Thanks @cuviper, worth following it.