Newtype tuple structs and generic data types

I'm pretty sure I'm missing something basic here. I have a

pub struct A(usize);

Now, code like this works fine:

fn foo(a: &A) {
	println!("{}", a.0);
}
fn main() {
	let a = A(5);
	foo(&a);
}

But, I want to define foo like this, instead (for reasons left out of the mix here):

fn foo<T>(a: &T) {
	println!("{}", a.0);
}

When I try this, I get:

error[E0609]: no field `0` on type `&T`

This is not a big surprise -- how would the compiler know that T is a tuple-struct. Now, if I were trying to do this for a type that simply implemented a defined trait, this would be easy to solve. My signature would look like:

fn foo<T:Bar>(a: &T) {

and so, for instance, if Bar defined some function bar(), then a.bar() could be called, and all would be well. But I can't figure out how to translate that for a tuple-struct. Does a tuple-struct implement some trait, such that I could say

fn foo<T:TupleStruct>(a: &T) {

and then the a.0 would magically work? I can't even figure out how to make something like the canonical 'let' pattern work:

   let T(arg) = a;

though it's not surprising that something like this would be no more likely to work than a.0. Perhaps I could create a trait, such that I could do:

fn foo<T:MyTupleStructTrait>(a: &T) {

and just call the function that simply returns the a.0, but that seems a little long-winded... is there a better way?

Thanks in advance. I've only just started learning Rust, and this is my first ever request for help. I appreciate your patience with my ignorance; I'm guessing I'm missing something pretty easy and fundamental here. :slight_smile:

You cannot, neither you should. A "tuple struct" is not something meaningful we can say about a type; it's a choice of ergonomics. Whether a struct is tuple or record should not affect semantics. If you want a tuple struct where the first field expresses something, use a trait.

1 Like

Wow, what a fast reply. Thank you. If I'm understanding you correctly, you're guiding me to engage in my final "idea" - to create a trait, and then use foo<T:MyTrait>(a: &T), within which, I'd call a.whatever(), which would access .0. Something like that? Even though it "seems" long-winded?

You can also use a getter in the trait to get the value. But the important thing is that it has meaning and not just based on the position of the field in the struct declaration.

Thank you. I figured out something that works, but that takes me one ring out in my quest, and I'd like to know if the pattern/design I employ is sound, and Rustic. However, I don't want to pollute this thread, so I'll post it as another topic.