Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Select constant based on the generic type in rust function

Tags:

generics

rust

Is there any way to select the value of a constant depending on the generic type?

For example, something like (not valid Rust code):

fn foo<T>() {
    let b = match T {
        u32 => 0x01234567u32,
        u64 => 0x0123456789abcdefu64,
        _ => panic!()
    }
}

fn main() {
    foo::<u32>();
    foo::<u64>();
}

This function would be only designed to operate with u16, u32 and u64 types.

like image 813
gagiuntoli Avatar asked Dec 03 '25 17:12

gagiuntoli


2 Answers

You could use an associated constant of a trait:

trait MyTrait {
    const SOME_CONST: Self;
}

impl MyTrait for u32 {
    const SOME_CONST: Self = 0x01234567u32;
}

impl MyTrait for u64 {
    const SOME_CONST: Self = 0x0123456789abcdefu64;
}

fn foo<T>() where T: MyTrait {
    let _b: T = T::SOME_CONST;
}

fn main() {
    foo::<u32>();
    foo::<u64>();
}

Try it on the rust playground.

like image 60
Brian Avatar answered Dec 06 '25 16:12

Brian


If you need to do more than just return a value, you could also match on the TypeId of your generic, but you'd have to wrap your return value in an enum because you can't return multiple types from a single match statement:

use std::any::TypeId;

#[derive(Debug)]
enum Value {
    u32(u32),
    u64(u64),
}

fn foo<T: 'static>() -> Value {
    match TypeId::of::<T>() {
        t if t == TypeId::of::<u32>() => {
            // other stuff
            Value::u32(0x01234567u32)
        },
        t if t == TypeId::of::<u64>() => {
            // other stuff
            Value::u64(0x0123456789abcdefu64)
        },
        _ => panic!(),
    }
}

fn main() {
    println!("{:?}", foo::<u32>());
    println!("{:?}", foo::<u64>());
}

The associated constants already mentioned are better if getting a constant value is the only functionality you need though.

like image 42
Jeremy Meadows Avatar answered Dec 06 '25 15:12

Jeremy Meadows



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!