Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Rust, how check if a generic parameter is of a specific type and cast to it

Tags:

generics

rust

I have several types that implement a trait (Relation). I need to pass data between them, like INSERT INTO FROM SELECT from sql.

However, some times I will move data that is coming from the same type, meaning I could use a more direct way:

impl Relation for BTree {
    fn new_from<R: Relation>(names: Schema, of: R) -> Self {
       if of is Btree { //How do this
          //Fast path
          cast(of as Btree).clone()  //And this
       } else {
          //Generic path
       }
    }
}
like image 916
mamcx Avatar asked Dec 14 '18 23:12

mamcx


People also ask

How do you check variable type in Rust?

If your just wanting to know the type of your variable during interactive development, I would highly recommend using rls (rust language server) inside of your editor or ide. You can then simply permanently enable or toggle the hover ability and just put your cursor over the variable.

What is Rust generic?

In Rust, generics refer to the parameterization of data types and traits. Generics allows to write more concise and clean code by reducing code duplication and providing type-safety. The concept of Generics can be applied to methods, functions, structures, enumerations, collections and traits.

How do you use generic in Rust?

The syntax for using generics in struct definitions is similar to that used in function definitions. First, we declare the name of the type parameter inside angle brackets just after the name of the struct. Then we use the generic type in the struct definition where we would otherwise specify concrete data types.

Do Rust traits support generics?

Rust supports polymorphism with two related features: traits and generics.


1 Answers

What you are trying to do should be possible using std::any. I imagine it would look something like this:

use std::any::Any;

trait Trait {
    fn foo<T: Trait + Any>(of: T) -> Self;
}

#[derive(Clone)]
struct Special;

impl Trait for Special {
    fn foo<T: Trait + Any>(of: T) -> Self {
        let of_any = &of as &dyn Any;
        if let Some(special) = of_any.downcast_ref::<Special>() {
            // Fast path
            special.clone()
        } else {
            // Generic path, pretend this is expensive
            Special
        }
    }
}
like image 183
jmhain Avatar answered Nov 15 '22 11:11

jmhain