BigEpsilon
BigEpsilon

Reputation: 679

Parametric mutability

I have tow questions concerning generics in rust:

I'm trying to port some C++ boost like concepts to Rust (here an example with a 2D point):

#![feature(associated_types)]

pub trait Point2D {
    type value_type;
    fn x(&self) -> &<Self as Point2D>::value_type;
    fn y(&self) -> &<Self as Point2D>::value_type;
}

#[deriving(Show)]
pub struct Point2<T> {
    x : T,
    y : T,
}

impl<T> Point2D for Point2<T> {
    type value_type = T;

#[inline]
    fn x(&self) -> &T {
        &self.x
    }

#[inline]
    fn y(&self) -> &T {
        &self.y
    }
}

fn main(){
    let mut  p = Point2{x: 0i32, y : 0i32};

    println!("p = {}", p);

    //*p.x() = 1i32; //error: cannot assign to immutable dereference of `&`-pointer
}

Here what I want is that x() and y() return a reference to mutable T when T is mutable, and an immutable reference otherwise, is it possible? I saw some internals talks about parametric mutability but I didn't find any established RFC.

Is there any plans to add parametrization over numeric values (like template<size_t n>) to Rust?

I guess for now the only solution is something like that :

#![feature(associated_types)]

pub trait Point2D {
    type value_type;
    fn x_as_mut(&mut self) -> &mut <Self as Point2D>::value_type;
    fn y_as_mut(&mut self) -> &mut <Self as Point2D>::value_type;
    fn x_as_ref(&self) -> &<Self as Point2D>::value_type;
    fn y_as_ref(&self) -> &<Self as Point2D>::value_type;
}

#[deriving(Show)]
pub struct Point2<T> {
    x : T,
    y : T,
}

impl<T> Point2D for Point2<T> {
    type value_type = T;

#[inline]
    fn x_as_mut(&mut self) -> &mut T {
        &mut self.x
    }

#[inline]
    fn y_as_mut(&mut self) -> &mut T {
        &mut self.y
    }
#[inline]
    fn x_as_ref(&self) -> &T {
        &self.x
    }

#[inline]
    fn y_as_ref(&self) -> &T {
        &self.y
    }
}

trait Channel {

}

fn main(){
    let mut p1 = Point2{x: 0i32, y : 0i32};

    println!("p1 = {}", p1);

    *p1.x_as_mut() = 1i32;
    
    println!("p1 = {}", p1);

    let p2 = Point2{x:0u8, y:10u8};

    println!("p2 = {}", p2.y_as_ref());

}

Any cleaner way ?

Upvotes: 0

Views: 240

Answers (1)

DK.
DK.

Reputation: 59095

There is no parametric mutability. I know that several people have expressed a strong desire for something along those lines, but I'm not aware of any actual plans as yet.

There is also no generic value parameters. I believe the core team definitely wants it, but it's not a priority right now.

Upvotes: 2

Related Questions