具有 return 迭代器的函数的特征
trait with functions that return an iterator
我正在尝试使用 return 迭代器的函数构建特征。
我的简单示例如下所示:
pub trait TraitA {
fn things(&self) -> Iterator<Item=&u8>;
}
fn foo<A: TraitA>(a: &A) {
for x in a.things() { }
}
这不起作用,因为迭代器大小类型在编译时未知。
基于另一个 question,我认为最好的方法是将 Iterator 定义为特征类型,如下所示:
pub trait TraitA<'a> {
type I1: Iterator<Item=u8>;
type I2: Iterator<Item=&'a u8>;
fn iter_i1(&self) -> Self::I1;
fn iter_i2(&self) -> Self::I2;
}
fn foo<'a, A: TraitA<'a>>(a: &A) {
for x in a.iter_i1() { }
for x in a.iter_i2() { }
}
Rust 的 libstd 有一个实现,特性 IntoIterator
。
/// Conversion into an `Iterator`
pub trait IntoIterator {
/// The type of the elements being iterated
type Item;
/// A container for iterating over elements of type `Item`
type IntoIter: Iterator<Item=Self::Item>;
/// Consumes `Self` and returns an iterator over it
fn into_iter(self) -> Self::IntoIter;
}
trait 具有这种特殊的按值 (self
) 公式,正好能够表达“进入迭代器”和“借用迭代器”语义。
由 HashMap 的 IntoIterator
实现展示。 (他们使用 hashmap 的迭代器结构 Iter
和 IntoIter
。)这里有趣的是,特征是为类型 &HashMap<K, V, S>
实现的,以表达“借用迭代器”。
impl<'a, K, V, S> IntoIterator for &'a HashMap<K, V, S>
where K: Eq + Hash, S: HashState
{
type Item = (&'a K, &'a V);
type IntoIter = Iter<'a, K, V>;
fn into_iter(self) -> Iter<'a, K, V> {
self.iter()
}
}
impl<K, V, S> IntoIterator for HashMap<K, V, S>
where K: Eq + Hash, S: HashState
{
type Item = (K, V);
type IntoIter = IntoIter<K, V>;
/// Creates a consuming iterator, that is, one that moves each key-value
/// pair out of the map in arbitrary order. The map cannot be used after
/// calling this.
fn into_iter(self) -> IntoIter<K, V> {
/* ... */
}
}
我正在尝试使用 return 迭代器的函数构建特征。
我的简单示例如下所示:
pub trait TraitA {
fn things(&self) -> Iterator<Item=&u8>;
}
fn foo<A: TraitA>(a: &A) {
for x in a.things() { }
}
这不起作用,因为迭代器大小类型在编译时未知。
基于另一个 question,我认为最好的方法是将 Iterator 定义为特征类型,如下所示:
pub trait TraitA<'a> {
type I1: Iterator<Item=u8>;
type I2: Iterator<Item=&'a u8>;
fn iter_i1(&self) -> Self::I1;
fn iter_i2(&self) -> Self::I2;
}
fn foo<'a, A: TraitA<'a>>(a: &A) {
for x in a.iter_i1() { }
for x in a.iter_i2() { }
}
Rust 的 libstd 有一个实现,特性 IntoIterator
。
/// Conversion into an `Iterator`
pub trait IntoIterator {
/// The type of the elements being iterated
type Item;
/// A container for iterating over elements of type `Item`
type IntoIter: Iterator<Item=Self::Item>;
/// Consumes `Self` and returns an iterator over it
fn into_iter(self) -> Self::IntoIter;
}
trait 具有这种特殊的按值 (self
) 公式,正好能够表达“进入迭代器”和“借用迭代器”语义。
由 HashMap 的 IntoIterator
实现展示。 (他们使用 hashmap 的迭代器结构 Iter
和 IntoIter
。)这里有趣的是,特征是为类型 &HashMap<K, V, S>
实现的,以表达“借用迭代器”。
impl<'a, K, V, S> IntoIterator for &'a HashMap<K, V, S>
where K: Eq + Hash, S: HashState
{
type Item = (&'a K, &'a V);
type IntoIter = Iter<'a, K, V>;
fn into_iter(self) -> Iter<'a, K, V> {
self.iter()
}
}
impl<K, V, S> IntoIterator for HashMap<K, V, S>
where K: Eq + Hash, S: HashState
{
type Item = (K, V);
type IntoIter = IntoIter<K, V>;
/// Creates a consuming iterator, that is, one that moves each key-value
/// pair out of the map in arbitrary order. The map cannot be used after
/// calling this.
fn into_iter(self) -> IntoIter<K, V> {
/* ... */
}
}