How can I approximate method overloading?

前端 未结 2 1336

I am modeling an API where method overloading would be a good fit. My naïve attempt failed:

// fn attempt_1(_x: i32) {}
// fn attempt_1(_x: f32) {}
// Error:         


        
相关标签:
2条回答
  • 2020-12-03 22:15

    Here's another way that drops the enum. It's an iteration on Vladimir's answer.

    trait Tr {
      fn go(&self) -> ();
    }
    
    impl Tr for i32 {
      fn go(&self) {
        println!("i32")
      }
    }
    
    impl Tr for f32 {
      fn go(&self) {
        println!("f32")
      }
    }
    
    fn attempt_1<T: Tr>(t: T) {
      t.go()
    }
    
    fn main() {
      attempt_1(1 as i32);
      attempt_1(1 as f32);
    }
    
    0 讨论(0)
  • 2020-12-03 22:16

    Yes, there is, and you almost got it already. Traits are the way to go, but you don't need trait objects, use generics:

    #[derive(Debug)]
    enum IntOrFloat {
        Int(i32),
        Float(f32),
    }
    
    trait IntOrFloatTrait {
        fn to_int_or_float(&self) -> IntOrFloat;
    }
    
    impl IntOrFloatTrait for i32 {
        fn to_int_or_float(&self) -> IntOrFloat {
            IntOrFloat::Int(*self)
        }
    }
    
    impl IntOrFloatTrait for f32 {
        fn to_int_or_float(&self) -> IntOrFloat {
            IntOrFloat::Float(*self)
        }
    }
    
    fn attempt_4<T: IntOrFloatTrait>(x: T) {
        let v = x.to_int_or_float();
        println!("{:?}", v);
    }
    
    fn main() {
        let i: i32 = 1;
        let f: f32 = 3.0;
    
        attempt_4(i);
        attempt_4(f);
    }
    

    See it working here.

    0 讨论(0)
提交回复
热议问题