Skip to content

Instantly share code, notes, and snippets.

@mendes5
Created February 7, 2023 13:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mendes5/5ea0155f7dbd3fb8612f37cba166cc9e to your computer and use it in GitHub Desktop.
Save mendes5/5ea0155f7dbd3fb8612f37cba166cc9e to your computer and use it in GitHub Desktop.
Traits, sub-traits and dyn Trait
use std::{rc::Rc, vec};
trait Unsafe {
// where Self: Sized allows us to hold
// values implementing this in arrays
// and pass it as function arguments as &dyn Unsafe
// or Box<dyn Unsafe> without not object-safe errors.
fn create() -> Self where Self: Sized;
}
trait Safe {
fn safe(&self);
}
trait WithGeneric<T> {
fn identity(&self, t: T) -> T;
}
trait All<T>: Unsafe + Safe + WithGeneric<T> {}
struct Test;
impl Unsafe for Test {
fn create() -> Self where Self: Sized {
Test{}
}
}
impl Safe for Test {
fn safe(&self) {
println!("Calling safe method");
}
}
impl <T> WithGeneric<T> for Test {
fn identity(&self, t: T) -> T {
t
}
}
impl <T> All<T> for Test {}
fn call_x<T>(a: &dyn All<T>) {
}
fn factory<T: All<X>, X>() -> Rc<T> {
Rc::new(T::create())
}
fn main() {
// Test implements All, which implements Unsafe
// So we can pass the type itself to factory
// to create an instance
let value = factory::<Test, i32>();
// An list holding objects implementing All<i32>
let all: Vec<Rc<dyn All<i32>>> = vec![value.clone()];
// The same Rc<Test> can be casted to another list of a different
// trait, since All implements Safe this works
let safe: Vec<Rc<dyn Safe>> = vec![value.clone()];
// Same thing here
let generic: Vec<Rc<dyn WithGeneric<i32>>> = vec![value.clone()];
for item in safe {
item.safe();
}
for item in generic {
println!("Calinng {}", item.identity(100));
}
println!("Hello, world!");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment