模板中关联类型的特征
Traits with associated type in templates
我在编译我的 Rust 代码时遇到问题,我设法将问题归结为这个片段:
use std::slice::Iter;
pub trait Foo<'a> {
type Bar: Iterator<Item=&'a usize>;
fn make(&self) -> usize;
}
pub struct Juice;
impl <'a> Foo<'a> for Juice {
type Bar = Iter<'a, usize>;
fn make(&self) -> usize { 0us }
}
// Uncomment this line to break things
// fn get_int<'a, T: Foo<'a>>(t: T) -> usize {
// t.make()
// }
fn main() {
println!("Hello, {:?} world!" , Juice.make());
}
我很确定我只是遗漏了一些东西,我需要做些什么才能让这个特性发挥作用吗?我正在使用最新的夜间 alpha 版本(在撰写本文时):
rustc 1.0.0-nightly (458a6a2f6 2015-01-25 21:20:37 +0000)
很遗憾,你需要这样写:
fn get_int<'a, T: Foo<'a, Bar=I>, I: Iterator<Item=&'a usize>>(t: T) -> usize {
t.make()
}
也就是你要明确指定Bar
的类型是对应类型的迭代器。仅在特征定义内的特征绑定是不够的。
这与常规类型参数的工作方式非常相似。即使你写了类似
的东西
trait Parameterized<T: Clone> { ... }
你还需要写
fn do_something<P: Parameterized<T>, T: Clone>() { ... }
或结构:
struct S<T: Iterator<i32>> { ... }
impl<T: Iterator<i32>> for S<T> { ... }
这看起来确实违反直觉(而且我也多次偶然发现)并且可能值得在 RFC 回购中提出问题。
我在编译我的 Rust 代码时遇到问题,我设法将问题归结为这个片段:
use std::slice::Iter;
pub trait Foo<'a> {
type Bar: Iterator<Item=&'a usize>;
fn make(&self) -> usize;
}
pub struct Juice;
impl <'a> Foo<'a> for Juice {
type Bar = Iter<'a, usize>;
fn make(&self) -> usize { 0us }
}
// Uncomment this line to break things
// fn get_int<'a, T: Foo<'a>>(t: T) -> usize {
// t.make()
// }
fn main() {
println!("Hello, {:?} world!" , Juice.make());
}
我很确定我只是遗漏了一些东西,我需要做些什么才能让这个特性发挥作用吗?我正在使用最新的夜间 alpha 版本(在撰写本文时):
rustc 1.0.0-nightly (458a6a2f6 2015-01-25 21:20:37 +0000)
很遗憾,你需要这样写:
fn get_int<'a, T: Foo<'a, Bar=I>, I: Iterator<Item=&'a usize>>(t: T) -> usize {
t.make()
}
也就是你要明确指定Bar
的类型是对应类型的迭代器。仅在特征定义内的特征绑定是不够的。
这与常规类型参数的工作方式非常相似。即使你写了类似
的东西trait Parameterized<T: Clone> { ... }
你还需要写
fn do_something<P: Parameterized<T>, T: Clone>() { ... }
或结构:
struct S<T: Iterator<i32>> { ... }
impl<T: Iterator<i32>> for S<T> { ... }
这看起来确实违反直觉(而且我也多次偶然发现)并且可能值得在 RFC 回购中提出问题。