3

I know that you can't mutate the type of a variable. So coming from other programming languages where following would work:

struct Point<T> {
    x: T,
    y: T,
}

fn main() {
    let mut p = Point { x: 1, y: 1 }; // p is type of Point<u8> now
    p = Point { x: 1.0, y: 1.0 }; // p should be type of Point<float> now
}

My use case for this would, that you assign a default value to variable and i specific case you change the value. But both are e.g. of the generic type Point<T> and the rest of the code just works with this generic type and not a specific one.

What is the best practice in Rust to achieve this kind of workflow?

EDIT:

A better example to understand what i want to accomplish is maybe following: DateTime<Tz> is given by the crate chrono.


fn main() {
   let is_utc = ....;

   let mut datetime = Local::now(); // datetime is now of type DateType<Local>

   if is_utc {
       datetime = Utc::now(); // datetime is now of type DateType<Utc>
   }

   format(datetime);
}


fn format<Tz: TimeZone>(datetime: DateTime<Tz>) where Tz::Offset : fmt::Display {
    // here is someother code to justify this extra function :)
    datetime.format("%a %b %e %k:%M:%S %Z %Y");
}

So the function format does not are what Tz is except it should be of type TimeZone.

4
  • As you said: You can't change the type. Also I don't see why you would need that from your comment. You need beforehand to know which type you expect (you can't change the type of values inside a Vec at runtime as well, can you?). I see two possibilities. Use Default::default and add the requirement T: Default and then you can write: let mut p: Point<f32> = Point::Default Commented Oct 10, 2019 at 7:52
  • You could do this in a weakly typed language, but in strongly typed languages which support generics, you cannot change the generic parameter. E.g. if you write Point<int> p = new Point<int>(1, 2); in C#, you cannot write p = new Point<float>(1f, 2f); afterwards. If the class was mutable, you couldn't even write p.X = 2.1f; because p is a struct containing integers. Think of generic classes as templates for concrete classes that are set in stone when you specify a parameter. Commented Oct 10, 2019 at 8:06
  • @hellow this not exactly what i want to do. See my edited question. Commented Oct 10, 2019 at 8:07
  • @Groo yes i understand that. I just want to know a best practice code how to approach my problem. Commented Oct 10, 2019 at 8:08

1 Answer 1

1

You can set your multi variable type in enum,

enum Num {
    int(i32),
    float(f64)
}

fn main() {
    let mut p = Point { x: Num::int(1), y: Num::int(1) };
    p = Point { x: Num::float(1.0), y: Num::float(1.0) };
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.