Structs for n-dimensional point


#1

I use the following struct to represent a n-dimensional point:

struct Point<T> {
    coords: Vec<T>,
    dim: usize,
}

It seems that the dim field is redundant, since we can obtain it from vec.len(). If we use only a Vec to represent the point, we need guarantee that its length is constant, which contradict with the definition of Vec as a growable list type. An array [T; N] is also considered, but its size should be known at runtime. Is there any better ways to represent a n-dimensional point?


#2

You could not expose any interface that increases Vec length after construction, that way the len will always be constant.


#3

You could use Box<[T]>, depending on what you need to do with the values; I don’t know if there’s any way to move out of a Box<[T]>.


#4

If I use pub type Point<T> = Vec<T>, I cannot define inherent impl for Point, since Vec is defined outside of my crate.


#5

I need to get the dim and get or set the coordinate component of the n-dimensional point. I also would like to define inherent impl for my type Point.


#6

I defined the tuple struct struct Point<T>(Vec<T>) for my type Point. But the following code http://is.gd/HXXiaC runs into an error cannot invoke tuple struct constructor with private fields:

mod point {
    pub struct Point<T>(Vec<T>);
}

fn main() {
    use point::Point;
    let point = Point(vec![0f64; 5]);
    let Point(coords) = point;
    println!("{:?}", coords);
}

However, this http://is.gd/1bMIDU just works as expected:

struct Point<T>(Vec<T>);

fn main() {
    let point = Point(vec![0f64; 5]);
    let Point(coords) = point;
    println!("{:?}", coords);
}

What is the problem?


#7

All slices, and anything that derefs to a slice, has a len method. Just use that.

As for inherent impls, just use a newtype (like you have in your follow-up post).

Exactly what the compiler told you: the Vec<T> field of the Point struct is private. You can only ignore privacy within a module. If you want it to be public, you have to say so:

struct Point<T>(pub Vec<T>);

#8

Thanks! It exactly solved my problem.


#9

You may also consider creating constructor method to encapsulate Point creation, so you can hide the way data really stored (you will need accessor methods as well in this case):

impl<T> Point<T> {
  pub fn new(vec: Vec<T>) -> Point<T> {
    Point(vec)
  }
}