I am struggling to understand lifetimes, especially with the concept of transitive lifetimes. Despite watching all videos and reading many articles, I still encounter significant difficulties.
Specifically, I need help with a problem involving transitive lifetimes. Here's a summary of the traits I'm working with:
Fields: This trait iterates over fields.
Cells: This trait returns a list of cells for a row and is deducible from Fields.
TableRows: This trait, also based on Fields, returns a list of rows, unlike Cells.
So, there is a transitive lifetime relationship: Fields -> Cells -> TableRows.
Could you please help me understand if this setup is correct and guide me through the lifetimes involved?
Certainly not; you are using way too many explicit lifetimes. That's a red flag in itself. In particular, you are putting lifetime parameters on a trait and then annotating the &self parameter with that lifetime – that's almost always nonsensical. If you want to express a relationship between lifetimes of the arguments and return type of a function, you shouldn't additionally constrain them with some other, external lifetime.
I'll try to fix this, but I can't guarantee anything will come out of it.
Edit 1:This compiles, but it still contains a ton of unnecessary cruft.
for<'a> Cow<'a, Cell>: From<<Row as Fields<CellKey>>::Value<'a>>,
How is that supposed to work? I used for<'a>, but that caused a problem in a in the outer code. It made the compiler think a temporary value was created when, in fact, it wasn’t. However, your suggestion might work; I will try it.
Sorry, I don't get what you are trying to say. Please show actual code.
It's not the main trick, no, but it is pretty much a necessary component. The main problem was that you over-constrained the lifetimes. The associated type is necessary because a type parameter doesn't allow you to name the lifetime parameter in the specific way it is being used here.
It's not the main trick, no, but it is pretty much a necessary component. The main problem was that you over-constrained the lifetimes. The associated type is necessary because a type parameter doesn't allow you to name the lifetime parameter in the specific way it is being used here.
I see. That is a problem with your solution. Both K and V need to be parameters, not associated types. Otherwise, the type for which Fields is implemented will be bound to a single type of V, but the same struct can have many implementations of Fields, not necessarily one as your implementation requires. I'm trying to rewrite your solution without using associated types.