error[E0599]: no method named `calc` found for struct `std::boxed::Box<dyn std::iter::Iterator<Item = i32>>` in the current scope
--> src/Calc.rs:107:21
|
107 | self.as_ld().calc()
| ^^^^ method not found in `std::boxed::Box<dyn std::iter::Iterator<Item = i32>>`
|
= help: items from traits can only be used if the trait is implemented and in scope
= note: the following trait defines an item `calc`, perhaps you need to implement it:
candidate #1: `Calc::CalcUtils`
I believe the issue is that iterators need to be mutable so I needed to add &mut to this signature: impl<'a> CalcUtils for &mut dyn Iterator<Item=i32>. and the as_ld trait doesn't return that type.
However I tried making as_ld return a mutable Box and I got this error:
Yes, thanks - that makes sense, however it doesn't play well with my other trait that converts str to an iterator of, for simplicities sake, i32. Since I wanted to write an "extension" to string to convert it to an iterable of i32, I wrote a trait. But impl Trait is not allowed in return position on a trait, so I ned to us a boxed dyn trait.
You are right yet again. Thanks for helping me along.
I still haven't gotten to the bottom of this:
Trait
impl<T: Iterator<Item=LDCode>> CalcUtils for T {
...
fn calc_with(&self, lookup: &Lookup) -> i32 {
self.fold(0, |acc, x| {
let mut ret = acc;
if let LDCode::Letter(i) = x {
ret += lookup[i as usize]
}
ret
})
}
...
Error:
error[E0507]: cannot move out of `*self` which is behind a shared reference
--> src/Calc.rs:78:9
|
78 | self.fold(0, |acc, x| {
| ^^^^ move occurs because `*self` has type `T`, which does not implement the `Copy` trait
error: aborting due to previous error
That makes sense. However now my str impl is giving me issues since it is !Sized
error[E0277]: the size for values of type `str` cannot be known at compilation time
--> src/Calc.rs:97:13
|
97 | fn calc(self) -> i32 {
| ^^^^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `str`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= note: all local variables must have a statically known size
= help: unsized locals are gated as an unstable feature
Wow the program works!! Thanks a million.
What happened was that I changed it to &str but I got a conflicting impl error, so I realised that I simply did not need any impl specifically for &str, and I could just use .as_ld().calc() at the call site, which I did and it worked.
only works on Vec/slices it I do ld.into_iter().calc() - ie. only if I move the iterator. Using .iter() gives me the following error:
error[E0599]: no method named `calc` found for struct `std::slice::Iter<'_, LDTypes::LDCode>` in the current scope
--> src/main.rs:46:34
|
46 | let val = ld.iter().calc();
| ^^^^ method not found in `std::slice::Iter<'_, LDTypes::LDCode>`
|
How can I define the impl that it works for .iter() (borrowing)?
I tried this:
impl<'a, T: Iterator<Item=LDCode>> CalcUtils for T {
and it gave me the same error.
Can you please explain to where I'm going wrong?
My goal is for the impl to work on both other iter chains as well as vecs/slices - the trait itself doesn't need ownership to do its job.
I tried both of the following (stringing through the related changes in the code) and I landed up with the same error:
Attempt 1
impl<'a, T: Iterator<Item=&'a LDCode>> CalcUtils for T {
Attempt 2
impl<'a, T: Iterator<Item=&'a LDCode> + 'a> CalcUtils for T {
error[E0599]: no method named `calc` found for struct `std::slice::Iter<'_, &LDTypes::LDCode>` in the current scope
--> src/main.rs:46:34
|
46 | let val = ld.iter().calc();
| ^^^^ method not found in `std::slice::Iter<'_, &LDTypes::LDCode>`
Did I misunderstand what you meant by "use references as the item type in the Iterator."?