From: Ian Jackson Date: Mon, 5 Jun 2023 15:58:02 +0000 (+0100) Subject: W X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ian/git?a=commitdiff_plain;h=5efd503cc9b26bfd421fd7acf95dda1e01c1af87;p=rust-experiments.git W --- diff --git a/src/main.rs b/src/main.rs index 59582c8..b860f63 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,20 +2,20 @@ use std::any::{Any,TypeId}; use std::sync::Arc; -pub trait CastToAnyTrait { - fn cast_to_instance(&self, tp: TypeId) -> Option>; +pub trait HasPseudoMethods: Any + Send + Sync + 'static { + fn cast_to_instance(&self, arc: Arc, tp: TypeId) -> Option>; } - -pub trait CastToAnyTraitExt { +/* +pub trait HasPseudoMethodsExt { fn cast_to(&self) -> Option>; } -impl CastToAnyTraitExt for T { +impl HasPseudoMethodsExt for T { fn cast_to(&self) -> Option> { let instance = self.cast_to_instance(TypeId::of::())?; instance.downcast().ok() } -} +}*/ trait HasFeet { fn how_many_feet(&self) -> usize; @@ -32,22 +32,24 @@ impl EatsFood for Frog { "flies" } } - +/* impl HasFeet for Frog { fn how_many_feet(&self) -> usize { 4 } -} +}*/ -impl CastToAnyTrait for Arc { +impl HasPseudoMethods for Frog { // Note: if you wanted to be able to add more traits to Frog elsewhere, you would // need a registry of cast-to-trait objects, similar to the existing dispatch // table. I'm not sure if that's needed. - fn cast_to_instance(&self, tp: TypeId) -> Option> { + fn cast_to_instance(&self, arc: Arc, tp: TypeId) -> Option> { if tp == TypeId::of::>() { - let arc: Arc = self.clone(); + let arc: Arc = Arc::downcast::(arc); + let arc: Arc = arc.clone(); return Some(Box::new(arc)); - } else if tp == TypeId::of::>() { +/* } else if tp == TypeId::of::>() { let arc: Arc = self.clone(); return Some(Box::new(arc)); +*/ } None } @@ -55,7 +57,7 @@ impl CastToAnyTrait for Arc { fn main() { let frog = Arc::new(Frog); - let erased_frog: &dyn CastToAnyTrait = &frog; + let erased_frog: Arc = frog as _; let with_feet: Arc = *erased_frog.cast_to::>().unwrap(); let eats_food: Arc = *erased_frog.cast_to::>().unwrap();