我如何告诉 Rust 某些东西实现了一个特征?
How do I tell Rust that something implements a trait?
我正在尝试编写一个 returns 迭代器的通用函数。
fn one_to_ten<T: Add>() -> std::iter::Iterator<Item = T> {
(1..5).chain(5..=10)
}
它是通用的,因为它需要为 u8
到 u128
工作,最好也为 i8
到 i128
工作,对于以下代码:
let mut sum: u64 = 0;
for x in one_to_ten() {
sum += x;
}
不幸的是,Rust 抱怨:
= help: the trait std::marker::Sized
is not implemented for (dyn std::iter::Iterator<Item = T> + 'static)
error[E0277]: the size for values of type dyn std::iter::Iterator<Item = _>
cannot be known at compilation time
和
error[E0308]: mismatched types
expected trait std::iter::Iterator, found struct std::iter::Chain
我在这里无法理解。当我试图实现一个通用函数时,Rust 似乎认为我正在尝试实现一个动态调度函数。 (并且,出于某种原因,我的链式迭代器不被接受为迭代器——我的猜测是我指定的是类型而不是特征,但是 std::iter::Iterator
是特征,而不是类型。)
我的代码应该是什么样的?
特征未确定大小,因此您不能 return 特征类型的值。相反,您必须 return 实现该特征的类型的值:
fn one_to_ten<T: Add>() -> impl std::iter::Iterator<Item = T> {
(1..5).chain(5..=10)
}
不幸的是,这带来了另一个问题,即 (1..5)
代码构建了一个整数范围,而不是 T
。您可以使用自定义特征来解决这个问题,因为 std::iter::Step
仍然不稳定。
pub trait MyRange: Sized {
type Iter: std::iter::Iterator<Item = Self>;
fn new(a: i32, b: i32) -> Self::Iter;
fn new_incl(a: i32, b: i32) -> Self::Iter {
Self::new(a, b + 1)
}
}
impl MyRange for i8 {
type Iter = std::ops::Range<Self>;
fn new(a: i32, b: i32) -> Self::Iter {
(a as i8 .. b as i8) //check overflow?
}
}
pub fn one_to_ten<T: Add + MyRange>() -> impl std::iter::Iterator<Item = T> {
T::new(1, 5).chain(T::new_incl(5, 10))
}
然后为您需要的每个整数类型实现 MyRange
特性。
我正在尝试编写一个 returns 迭代器的通用函数。
fn one_to_ten<T: Add>() -> std::iter::Iterator<Item = T> {
(1..5).chain(5..=10)
}
它是通用的,因为它需要为 u8
到 u128
工作,最好也为 i8
到 i128
工作,对于以下代码:
let mut sum: u64 = 0;
for x in one_to_ten() {
sum += x;
}
不幸的是,Rust 抱怨:
= help: the trait
std::marker::Sized
is not implemented for(dyn std::iter::Iterator<Item = T> + 'static)
error[E0277]: the size for values of typedyn std::iter::Iterator<Item = _>
cannot be known at compilation time
和
error[E0308]: mismatched types
expected trait std::iter::Iterator, found structstd::iter::Chain
我在这里无法理解。当我试图实现一个通用函数时,Rust 似乎认为我正在尝试实现一个动态调度函数。 (并且,出于某种原因,我的链式迭代器不被接受为迭代器——我的猜测是我指定的是类型而不是特征,但是 std::iter::Iterator
是特征,而不是类型。)
我的代码应该是什么样的?
特征未确定大小,因此您不能 return 特征类型的值。相反,您必须 return 实现该特征的类型的值:
fn one_to_ten<T: Add>() -> impl std::iter::Iterator<Item = T> {
(1..5).chain(5..=10)
}
不幸的是,这带来了另一个问题,即 (1..5)
代码构建了一个整数范围,而不是 T
。您可以使用自定义特征来解决这个问题,因为 std::iter::Step
仍然不稳定。
pub trait MyRange: Sized {
type Iter: std::iter::Iterator<Item = Self>;
fn new(a: i32, b: i32) -> Self::Iter;
fn new_incl(a: i32, b: i32) -> Self::Iter {
Self::new(a, b + 1)
}
}
impl MyRange for i8 {
type Iter = std::ops::Range<Self>;
fn new(a: i32, b: i32) -> Self::Iter {
(a as i8 .. b as i8) //check overflow?
}
}
pub fn one_to_ten<T: Add + MyRange>() -> impl std::iter::Iterator<Item = T> {
T::new(1, 5).chain(T::new_incl(5, 10))
}
然后为您需要的每个整数类型实现 MyRange
特性。