user2110184
user2110184

Reputation: 55

How to call an associated function of a struct with a generic type?

I tried to create a Link trait and a struct SinglLink with a generic type which implements Link, but when I call the associated function of the struct, I get an error. Should I use a macro like vec!?

mod Link {
    use std::cell::RefCell;
    use std::collections::VecDeque;
    use std::fmt::Debug;
    use std::rc::Rc;

    trait Link {
        type Node;
        type Value;
        fn new(data: &mut VecDeque<Self::Value>) -> Self;
    }

    #[derive(Debug)]
    pub struct Node<T> {
        pub value: T,
        pub next: RefCell<Option<Rc<Node<T>>>>,
    }

    #[derive(Debug)]
    pub struct SinglLink<T> {
        pub header: RefCell<Option<Rc<Node<T>>>>,
        pub len: i32,
    }

    impl<T: Copy> Link for SinglLink<T> {
        type Node = Node<T>;
        type Value = T;
        fn new(data: &mut VecDeque<Self::Value>) -> Self {
            SinglLink {
                header: RefCell::new(None),
                len: 0,
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use super::Link::SinglLink;
    use super::*;
    use std::cell::RefCell;
    use std::collections::VecDeque;

    #[test]
    fn it_works() {
        let mut data: VecDeque<i32> = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10].into_iter().collect();
        let single: SinglLink<i32> = SinglLink::new(&mut data);
    }
}

The error message:

error[E0599]: no function or associated item named `new` found for type `Link::SinglLink<_>` in the current scope
  --> src/lib.rs:47:49
   |
20 |     pub struct SinglLink<T> {
   |     ----------------------- function or associated item `new` not found for this
...
47 |         let single: SinglLink<i32> = SinglLink::new(&mut data);
   |                                                 ^^^ function or associated item not found in `Link::SinglLink<_>`
   |
   = help: items from traits can only be used if the trait is implemented and in scope
   = note: the following trait defines an item `new`, perhaps you need to implement it:
           candidate #1: `Link::Link`

Upvotes: 1

Views: 1839

Answers (1)

loganfsmyth
loganfsmyth

Reputation: 161447

Two small mistakes are compounding here to make the error message not very helpful.

  1. You've forgotten the pub on trait Link, so it is entirely inaccessible outside of the Link module. e.g. pub trait Link { /* ... */ }

  2. You need to use the Link trait in the tests module for its methods to be available there. (Once you add the pub, the compiler error will tell you this nicely). e.g. use super::Link::Link;

Here's a working version of your code:

mod Link {
    use std::cell::RefCell;
    use std::collections::VecDeque;
    use std::fmt::Debug;
    use std::rc::Rc;
    pub trait Link {
        type Node;
        type Value;
        fn new(data: &mut VecDeque<Self::Value>) -> Self;
    }

    #[derive(Debug)]
    pub struct Node<T> {
        pub value: T,
        pub next: RefCell<Option<Rc<Node<T>>>>,
    }

    #[derive(Debug)]
    pub struct SinglLink<T> {
        pub header: RefCell<Option<Rc<Node<T>>>>,
        pub len: i32,
    }

    impl<T: Copy> Link for SinglLink<T> {
        type Node = Node<T>;
        type Value = T;
        fn new(data: &mut VecDeque<Self::Value>) -> Self {
            SinglLink {
                header: RefCell::new(None),
                len: 0,
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use super::Link::SinglLink;
    use super::Link::Link;
    use super::*;
    use std::cell::RefCell;
    use std::collections::VecDeque;

    #[test]
    fn it_works() {
        let mut data: VecDeque<i32> = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10].into_iter().collect();
        let single: SinglLink<i32> = SinglLink::new(&mut data);
    }
}

(Rust Playground)

Upvotes: 2

Related Questions