简体   繁体   中英

Traits with associated type in templates

I have been having problems compiling my Rust code, I managed to boil down the issue to this snippet:

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());
}

I am pretty sure I am just missing something, is there anything I need to do to make this trait work? I am using the latest nightly alpha build (at the time of writing):

rustc 1.0.0-nightly (458a6a2f6 2015-01-25 21:20:37 +0000)

Unfortunately, you need to write this:

fn get_int<'a, T: Foo<'a, Bar=I>, I: Iterator<Item=&'a usize>>(t: T) -> usize {
  t.make()
}

That is, you have to specify explicitly that the type of Bar is an iterator of the corresponding type. The trait bound inside the trait definition alone is insufficient.

This is very much like regular type parameters work. Even if you write something like

trait Parameterized<T: Clone> { ... }

You still need to write

fn do_something<P: Parameterized<T>, T: Clone>() { ... }

Or with structs:

struct S<T: Iterator<i32>> { ... }

impl<T: Iterator<i32>> for S<T> { ... }

This does look counterintuitive (and I've stumbled upon this several times as well) and probably deserves an issue in RFC repo.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM