Hello. Another lifetime problem in generics I struggle to solve. I use, but don't understand associated types of such kind
type Key<'k> where Self: 'k;
What does it say and why is it necessary to use here? Appreciate help.
Hello. Another lifetime problem in generics I struggle to solve. I use, but don't understand associated types of such kind
type Key<'k> where Self: 'k;
What does it say and why is it necessary to use here? Appreciate help.
Iām not sure why this happens or if it applies to every case, but this solution fixes the problem. Maybe someone can explain why?
Borrowed: 'static
Why this bound must be applied and why is not it obstacle for compiler to compile?
bounds on associated types are exactly the same as bounds on any other type.
T: 'static
implies T: 'a
for all possible 'a
, since 'static
is the longest possible lifetime.
However, it probably makes no sense for a borrowed type to require 'static
because it will then become useless (it can't then contain any temporary references, only 'static
references, or no references at all ā effectively, it'll become an owned type, not a borrowed one).
Hello. Thanks for answer. But why does it compile and work with 'static
?
Again, because Borrowed: 'static
satisfies the requirement Borrowed: 'v
(no matter what 'v
is).
I'm confused because I don't understand why then it's allowed for parameter Borrowed
to be types having references...
The immediate source of the error in the OP playground is that Self: 'a + Borrow<Borrowed>
doesn't imply Borrowed: 'a
. There are ways around it -- at least to some extent -- if you make your trait specific to one lifetime. But I don't know if it's worth it for your use case. If you don't care about Vec<BorrowedThings>
, maybe the 'static
workaround will be enough for you.
(I'll write it up if you want, but it may just lead you down some convoluted path you don't need.)
Incidentally what to the parameters K
and V
represent here?
pub trait Fields<K, V> {
type Key<'k> where Self: 'k;
type Val<'v> where Self: 'v;
fn fields(&self) -> impl IteratorTrait<Item = (Self::Key<'_>, Self::Val<'_>)>;
}
It can't be "implementor is a collection mapping K
to V
", because that's not what you have attempted to implement:
// different types vvvvvvvvv v
impl<V, Borrowed> Fields<usize, &Borrowed> for Vec<V>
And it can't be "thing you want to iterate over", based on the signature of the method -- that's Val<'_>
.
fn fields(&self) -> impl IteratorTrait<
Item = (Self::Key<'_>, Self::Val<'_>)
>;
Is it just some sort of marker so you can have multiple implementations for the same type (Vec<V>
)?
Asking because it's hard to give advice without understanding the design (or XY goal).
Hello. I see.
And it can't be "thing you want to iterate over", based on the signature of the method -- that's
Val<'_>
.
That's right.
Is it just some sort of marker so you can have multiple implementations for the same type (
Vec<V>
)?
Not marker, Key
for key and Val
for value.
Purpose of trait Fields
to iterate over fields convertible to a specified type within an entity. Both key and val are parameters and same entity could have several Fields
implemented for it.
f you don't care about
Vec<BorrowedThings>
, maybe the'static
workaround will be enough for you.
But currently Vec<BorrowedThings>
works.
fn test(a: &str, b: &str) {
let collection: Vec<&str> = vec![a, b];
let got: Vec<(usize, &str)> = Fields::<usize, &str>::fields(&collection).collect();
assert_eq!(got.len(), 2);
}
Or I misunderstand something? Is not that Vec<BorrowedThings>
?
I didn't forget about this but haven't had time to circle back. (I believe I made some mental misstep and something I didn't think would work, does work.) I'll try to come back to it again later.
Maybe it's a bug of compiler?
I don't think there's a bug here.
it's never a compiler bug.
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.