< 返回版块

5000_years_ago 发表于 2023-05-16 16:47

Tags:Any,downcast,is

我有这样一个变量

HashMap::<String, Box<dyn Any>>::new();

map.insert(String::from("test-key"), Box::new(String::from("hello world")));

这个kv取出来后调用is::<String>()返回的是true,但是我自己创建了一个trait模仿了Any的is和downcast_ref,将上述代码中的泛型改为我模仿的那个trait,之后取出kv调用is::<String>()返回的是false,求教一下这是为什么,谢谢看到这里的朋友!!!

评论区

写评论
作者 5000_years_ago 2023-05-18 11:13

没抄错,就抄了两个方法,downcast_ref,is

--
👇
viruscamp: 1. 贴完整代码或者有效 play 链接 2. 抄 Any 的话,就这么几行,自己看看哪里抄错了

    use std::any::Any;
    use std::collections::HashMap;

    #[test]
    fn test_any() {
        let k = String::from("test-key");
        let mut map = HashMap::<String, Box<dyn Any>>::new();
        map.insert(k.clone(), Box::new(String::from("hello world")));

        dbg!(map.get(&k).unwrap().is::<String>());
        assert!(map.get(&k).unwrap().is::<String>());
    }

    use std::any::TypeId;
    pub trait Any1: 'static {
        fn type_id(&self) -> TypeId;
    }
    impl<T: 'static + ?Sized> Any1 for T {
        fn type_id(&self) -> TypeId {
            TypeId::of::<T>()
        }
    }
    impl dyn Any1 {
        pub fn is<T: Any1>(&self) -> bool {
            // Get `TypeId` of the type this function is instantiated with.
            let t = TypeId::of::<T>();
    
            // Get `TypeId` of the type in the trait object (`self`).
            let concrete = self.type_id();
    
            // Compare both `TypeId`s on equality.
            t == concrete
        }
    }

    #[test]
    fn test_any1() {
        let k = String::from("test-key");
        let mut map = HashMap::<String, Box<dyn Any1>>::new();
        map.insert(k.clone(), Box::new(String::from("hello world")));

        dbg!(map.get(&k).unwrap().is::<String>());
        assert!(map.get(&k).unwrap().is::<String>());
    }
viruscamp 2023-05-17 11:37
  1. 贴完整代码或者有效 play 链接
  2. 抄 Any 的话,就这么几行,自己看看哪里抄错了
    use std::any::Any;
    use std::collections::HashMap;

    #[test]
    fn test_any() {
        let k = String::from("test-key");
        let mut map = HashMap::<String, Box<dyn Any>>::new();
        map.insert(k.clone(), Box::new(String::from("hello world")));

        dbg!(map.get(&k).unwrap().is::<String>());
        assert!(map.get(&k).unwrap().is::<String>());
    }

    use std::any::TypeId;
    pub trait Any1: 'static {
        fn type_id(&self) -> TypeId;
    }
    impl<T: 'static + ?Sized> Any1 for T {
        fn type_id(&self) -> TypeId {
            TypeId::of::<T>()
        }
    }
    impl dyn Any1 {
        pub fn is<T: Any1>(&self) -> bool {
            // Get `TypeId` of the type this function is instantiated with.
            let t = TypeId::of::<T>();
    
            // Get `TypeId` of the type in the trait object (`self`).
            let concrete = self.type_id();
    
            // Compare both `TypeId`s on equality.
            t == concrete
        }
    }

    #[test]
    fn test_any1() {
        let k = String::from("test-key");
        let mut map = HashMap::<String, Box<dyn Any1>>::new();
        map.insert(k.clone(), Box::new(String::from("hello world")));

        dbg!(map.get(&k).unwrap().is::<String>());
        assert!(map.get(&k).unwrap().is::<String>());
    }
作者 5000_years_ago 2023-05-16 19:58

我是复制的Any中的实现啊,和Any一样的

--
👇
Aya0wind: 至少给一下你那个trait怎么写的吧。
any是通过比较type_id实现的,你是怎么实现的?

作者 5000_years_ago 2023-05-16 19:58

就是抄下来的,一个字符都不差

--
👇
teshin: 把any的代码抄下来就不会出错了

Aya0wind 2023-05-16 19:58

至少给一下你那个trait怎么写的吧。
any是通过比较type_id实现的,你是怎么实现的?

teshin 2023-05-16 19:40

把any的代码抄下来就不会出错了

1 共 6 条评论, 1 页