&str,tuples and structs

why can we use &str in tuples, but we have to specify lifetime in structs

There’s also a lifetime when used in a tuple.

struct Foo;

type UsingTuple<'a> = (&'a str, Foo);

struct MyStruct<'a> {
	string_slice_ref: &'a str,
	more_data: Foo,

type UsingStruct<'a> = MyStruct<'a>;

either of the type aliases UsingTuple/UsingStruct will need a lifetime parameter to be defined. It’s only a syntactic question whether the lifetime parameter is used as an argument to the struct directly as in MyStruct<'a> because the struct prescribes the &'_ str type and only leaves the lifetime to be chosen, or whether the lifetime is given in the reference type directly and that type is then used as an argument to the tuple type like in (&'a str, Foo).

In fact, structs with type arguments work more like tuples in this regard

struct StructWithTypeParameter<T> {
	field: T,
	more_data: Foo,

type UsingDifferentStruct<'a> = StructWithTypeParameter<&'a str>;

In case this doesn’t answer your question, please explain what you’re actually asking about; your question is remarkably short and imprecise.

why can we write

let tup:(u8,&str,bool)=(12,"string",true)

but we can't write

struct Person{

You are comparing apples with oranges in terms of your example of using &str “in tuples” vs ”in structs“.

Lifetimes can be inferred in type annotations (in let statements, or e.g. in turbofish-style arguments), but need to be explicit in struct / enum / type-alias definitions. (For completeness: There’s a third possibility: in function signatures (and a few more similar places) lifetimes cannot be inferred but elided which means that the aren’t determined by the type-checked picking something that fits, but by a small set of well-defined default rules that make sense in most use-cases..)

Your examples aren’t a tuples vs. structs distinction. One example happens to use a tuple type in a type annotation, the other defines a struct type. You cannot define a tuple type (since its a thing that already exists) so there’s no way to compare that to tuples; you can use structs in type annotations and it will look similar to using tuples.

Depending on whether the lifetime is a lifetime argument to the struct or to a type argument, e.g. using my structs from above, this could look as follows

let x: MyStruct<'_> = MyStruct {
	string_slice_ref: "string",
	more_data: Foo,

or as follows

let x: StructWithTypeParameter<&str> = StructWithTypeParameter {
	field: "string",
	more_data: Foo,

Admitted, there is a slight difference in that the '_ is missing for the &str type (though writing &'_ str explicitly would have the same effect)[1], but that’s just because &str (or &T and &mut T types in general) is/are well-known to always have a lifetime, so it makes sense to be less even more concise there.

  1. and in fact, it’s also possible to write x: MyStruct instead, dropping the whole <'_> part, but I would discourage using this syntax as it can lead to confusion, especially if used in function signatures instead of type signatures of local types ↩︎

1 Like

thank you very mutch

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.