How to use a struct with generic lifetimes and a slice?
In this case first and second would be &&str instead of &str.
Is there any ways of making MyStruct instance to have &'a str and &'b str?
error[E0277]: the size for values of type `str` cannot be known at compilation time
--> src/main.rs:7:12
|
7 | slice: MyStruct<'a, 'b, str>
| ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `str`
note: required by a bound in `MyStruct`
--> src/main.rs:1:25
|
1 | struct MyStruct<'a, 'b, T> {
| ^ required by this bound in `MyStruct`
help: consider relaxing the implicit `Sized` restriction
|
1 | struct MyStruct<'a, 'b, T: ?Sized> {
| ++++++++
General warning, because it cannot be said often enough:
Structs with too many lifetime arguments (or any lifetime arguments, really) can be hard to use. At a minimum, make sure to double-check that you are aware of what “ownership” conceptually is, and that you really want to store – usually shorter-lived – borrows in your struct fields. I.e.: every user of your structs would handle ownership of those values themself, storing the necessary values (e.g. the strings in this use-case) in their own local variables (or in other struct(s) with owning semantics, or another place higher-up on the call-stack), and always drops your MyStruct or Wrapper values before those owners go out of scope. If use-cases don’t look like that, fields that own the values, or shared-ownership with Rc or Arc might be more appropriate.
Also make sure to be even more wary (and double-check again that you got your ownership story clear…[1]) once any &'a MyStruct<'a, …> style values appear in your code, the same lifetime appears both in a type parameter and as the lifetime of a reference borrowing that type, and make sure to (essentially[2]) never let &mut 'a MyStruct<'a, …>, i.e. the same thing with a mutable reference, appear.
Read-only is one part of the equation; even so, use-cases will need to involve the caller of your struct’s APIs to save and keep the String around somewhere. This is most commonly not a problem when your struct only exists for a short time, e.g. as some intermediate state/value in a sequence of function calls.
Of course, your use-case might be fitting. I’m also adding this information for others that might come across this thread, as we’re in a public forum
Another tip I forgot: Writing test cases early, perhaps even while some method implementations are still todo!()-implemented, can help ensure that API one defines that involves a bunch of lifetimes, is actually usable as intended. There is always two parts to function signatures with lifetimes: The implementation needs to support the lifetimes, and the intended use cases need to do so. If the use-cases turn out to be easier to write than the implementation, doing them first is a way to weed out earlier one of the possibilities for error.