调用trait的关联函数时如何指定关联类型<Item=...>?
How to specify associated type <Item=...> when calling associated function of a trait?
我有这个 rust 代码 playground:
use itertools::{repeat_n,RepeatN};
pub trait MyIterator: Iterator {
fn fill1(elem: Self::Item, n1: usize) -> RepeatN<Self::Item>
where
Self::Item: Clone,
{
repeat_n(elem, n1)
}
}
我的问题是我无法调用此方法,因为 rustc 无法推断类型。
// error[E0284]: type annotations needed
// let r: RepeatN<char> = MyIterator::fill1('a', 5);
// ^^^^^^^^^^^^^^^^^ cannot infer type
// note: cannot satisfy `<_ as Iterator>::Item == _`
let r: RepeatN<char> = MyIterator::fill1('a', 5);
我试过了,但没有编译:
// error[E0229]: associated type bindings are not allowed here
let r: RepeatN<char> = MyIterator::<Item=char>::fill1('a', 5);
如何在这个调用中指定Item
的类型?还是特征之外的函数(如 itertools::repeat_n
)是这里最好的方法?
好吧,您还没有为任何类型实现特征,因此实际上不存在 fill1
函数。
如果您为实现 Iterator<Item = char>
的某种类型实现 MyIterator
,例如 std::iter::Empty<char>
,那么您将能够通过该类型调用 fill1
。
use std::iter::Empty;
impl MyIterator for Empty<char> {}
fn main() {
let r: RepeatN<char> = Empty::fill1('a', 5);
}
然而,这是毫无意义的。您会注意到 Empty
在实际的函数定义中没有任何作用——它可能是任何迭代器。此外,没有将此行为合理地推广到其他 Self
类型。这就是为什么 itertools::repeat_n
不是 Itertools
特征的成员:它作为特征函数是无意义的,因为它不是多个迭代器类型共享的行为的概括。
在 Rust 中,与其他一些语言不同,并不是所有的东西都必须是 class 的成员。如果你只是想把fill1
和相关的东西放在一个普通的namespace里,那么就用模块吧,模块是最基本的代码组织单位
mod my_iterator {
use itertools::{repeat_n, RepeatN};
fn fill1<T>(elem: T, n1: usize) -> RepeatN<T>
where
T: Clone,
{
repeat_n(elem, n1)
}
}
我有这个 rust 代码 playground:
use itertools::{repeat_n,RepeatN};
pub trait MyIterator: Iterator {
fn fill1(elem: Self::Item, n1: usize) -> RepeatN<Self::Item>
where
Self::Item: Clone,
{
repeat_n(elem, n1)
}
}
我的问题是我无法调用此方法,因为 rustc 无法推断类型。
// error[E0284]: type annotations needed
// let r: RepeatN<char> = MyIterator::fill1('a', 5);
// ^^^^^^^^^^^^^^^^^ cannot infer type
// note: cannot satisfy `<_ as Iterator>::Item == _`
let r: RepeatN<char> = MyIterator::fill1('a', 5);
我试过了,但没有编译:
// error[E0229]: associated type bindings are not allowed here
let r: RepeatN<char> = MyIterator::<Item=char>::fill1('a', 5);
如何在这个调用中指定Item
的类型?还是特征之外的函数(如 itertools::repeat_n
)是这里最好的方法?
好吧,您还没有为任何类型实现特征,因此实际上不存在 fill1
函数。
如果您为实现 Iterator<Item = char>
的某种类型实现 MyIterator
,例如 std::iter::Empty<char>
,那么您将能够通过该类型调用 fill1
。
use std::iter::Empty;
impl MyIterator for Empty<char> {}
fn main() {
let r: RepeatN<char> = Empty::fill1('a', 5);
}
然而,这是毫无意义的。您会注意到 Empty
在实际的函数定义中没有任何作用——它可能是任何迭代器。此外,没有将此行为合理地推广到其他 Self
类型。这就是为什么 itertools::repeat_n
不是 Itertools
特征的成员:它作为特征函数是无意义的,因为它不是多个迭代器类型共享的行为的概括。
在 Rust 中,与其他一些语言不同,并不是所有的东西都必须是 class 的成员。如果你只是想把fill1
和相关的东西放在一个普通的namespace里,那么就用模块吧,模块是最基本的代码组织单位
mod my_iterator {
use itertools::{repeat_n, RepeatN};
fn fill1<T>(elem: T, n1: usize) -> RepeatN<T>
where
T: Clone,
{
repeat_n(elem, n1)
}
}