2

I tried to implement a builder pattern in Rust as an exercise. Then, I wanted to implement struct Director with generics which handle concrete Builders and calculates the distance between two points.

Please turn a blind eye to the unsafe code:

struct VecLengthDirector<T> {
    builder: T,
}

impl<T> VecLengthDirector<T> {
    fn construct(&self) -> f64 {
        let s = self.builder.start.unwrap();
        let e = self.builder.end.unwrap();

        let mut sum: i32 = 0;
        for i in 0..s.len() {
            sum += (s[i] - e[i]).pow(2);
        }

        (sum as f64).sqrt()
    }
}

trait AbstractVecLengthBuider<T> {
    fn addStartPoint(&mut self, point: T);
    fn addEndPoint(&mut self, point: T);
}

struct TwoDimVecLengthBuilder {
    start: Option<[i32; 2]>,
    end: Option<[i32; 2]>,
}

impl AbstractVecLengthBuider<[i32; 2]> for TwoDimVecLengthBuilder {
    fn addStartPoint(&mut self, point: [i32; 2]) {
        self.start = Some(point);
    }
    fn addEndPoint(&mut self, point: [i32; 2]) {
        self.end = Some(point);
    }
}

pub fn test() {
    let mut veclen1 = VecLengthDirector {
        builder: TwoDimVecLengthBuilder {
            start: None,
            end: None,
        },
    };
    veclen1.builder.addStartPoint([0, 0]);
    veclen1.builder.addEndPoint([1, 1]);
    println!(
        "Distance between [0, 0] and [1, 1] is: {}",
        veclen1.construct()
    );
}

After running this code, the following error is reported:

error[E0609]: no field `start` on type `T`
 --> src/main.rs:7:30
  |
7 |         let s = self.builder.start.unwrap();
  |                              ^^^^^

error[E0609]: no field `end` on type `T`
 --> src/main.rs:8:30
  |
8 |         let e = self.builder.end.unwrap();
  |                              ^^^

I researched the error code and read Rust's documentation, but I couldn't understand what is happening and what's wrong.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
yutaaa
  • 97
  • 8
  • 2
    Rust generics do not use SFINAE like in C++ but are semantic. Read more about them. – Boiethios May 15 '18 at 15:48
  • Welcome to Stack Overflow! I believe your question is answered by the answers of [Is it possible to access struct fields from within a trait?](https://stackoverflow.com/q/28219730/155423). TL;DR: no, you cannot do what you are trying to do. If you disagree, please [edit] your question to explain the differences. Otherwise, we can mark this question as already answered. – Shepmaster May 15 '18 at 15:57
  • 1
    Please do not change your question to include suggestions from answers. Your question was answered, but it's acceptable to ask new ones for new topics (after searching for existing posts and creating a [mcve], of course). – Shepmaster May 15 '18 at 16:52
  • 1
    For example, your update would be a duplicate of questions like [“no method found for type T in the current scope” when wrapping a type](https://stackoverflow.com/q/38812874/155423). Make sure to search for your error message first. – Shepmaster May 15 '18 at 16:54

0 Answers0