Я пытаюсь реализовать черту для любой последовательности элементов, чтобы она работала для векторов, массивов и слайсов.До сих пор я пробовал несколько подходов, но не могу скомпилировать ни один из них: (
У меня есть эта черта, и функция, которая ее использует, и базовый тип данных, реализующий эту черту:
trait Hitable {
fn hit(&self, val: f64) -> bool;
}
fn check_hit<T: Hitable>(world: &T) -> bool {
world.hit(1.0)
}
struct Obj(f64);
impl Hitable for Obj {
fn hit(&self, val: f64) -> bool {
self.0 > val
}
}
Я хотел бы иметь возможность реализовать эту черту для последовательности Obj
. Она прекрасно работает, если я просто ограничу ее векторами:
impl<T> Hitable for Vec<T>
where
T: Hitable,
{
fn hit(&self, val: f64) -> bool {
self.iter().any(|h| h.hit(val))
}
}
fn main() {
let v = vec![Obj(2.0), Obj(3.0)];
println!("{}", check_hit(&v));
}
Но я хочусделать его более универсальным, чтобы он работал для массивов и слайсов, как я могу это сделать?
Я попробовал следующие четыре попытки:
Попытка # 1: для итератора на Hitables.
// It's not clear how to call it:
// vec.iter().hit(...) does not compile
// vec.into_iter().hit(...) does not compile
//
impl<T, U> Hitable for T
where
T: Iterator<Item = U>,
U: Hitable,
{
fn hit(&self, val: f64) -> bool {
self.any(|h| h.hit(val))
}
}
Попытка № 2: для чего-то, что можно превратить в итератор.
// Does not compile as well:
//
// self.into_iter().any(|h| h.hit(val))
// ^^^^ cannot move out of borrowed content
//
impl<T, U> Hitable for T
where
T: IntoIterator<Item = U>,
U: Hitable,
{
fn hit(&self, val: f64) -> bool {
self.into_iter().any(|h| h.hit(val))
}
}
Попытка № 3: для срезов.
// This usage doesn't compile:
// let v = vec![Obj(2.0), Obj(3.0)];
// println!("{}", check_hit(&v));
//
// It says that Hitable is not implemented for vectors.
// When I convert vector to slice, i.e. &v[..], complains about
// unknown size in compilation time.
impl<T> Hitable for [T]
where
T: Hitable,
{
fn hit(&self, val: f64) -> bool {
self.iter().any(|h| h.hit(val))
}
}
Попытка № 4: для итератора+ Клон
// let v = vec![Obj(2.0), Obj(3.0)];
// println!("{}", check_hit(&v.iter()));
//
// does not compile:
// println!("{}", check_hit(&v.iter()));
// ^^^^^^^^^ `&Obj` is not an iterator
//
impl<T, U> Hitable for T
where
T: Iterator<Item = U> + Clone,
U: Hitable,
{
fn hit(&self, val: f64) -> bool {
self.clone().any(|h| h.hit(val))
}
}
ссылка на игровую площадку