Structs for n-dimensional point

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?

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

2 Likes

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]>.

1 Like

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

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.

I defined the tuple struct struct Point<T>(Vec<T>) for my type Point. But the following code Rust Playground 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 Rust Playground 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?

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

Thanks! It exactly solved my problem.

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