为什么 dyn Any 类型找不到 downcast_ref 方法?

5

我正在尝试创建自己的模拟框架,但遇到了问题。 当我尝试将我的Any类型向下转换时,它找不到downcast_ref方法:

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

struct X;
struct Y;

fn main() {
    let mut map: HashMap<&'static str, Box<Any + Sync>> = HashMap::new();
    map.insert("x", Box::new(X));
    map.insert("y", Box::new(Y));

    get_x(map);
}

fn get_x(map: HashMap<&'static str, Box<Any + Sync>>) {
    let ref any = map["x"];
    let res = Any::downcast_ref::<X>(any); // Works
    let res = any.downcast_ref::<X>();     // Fails
}

Playground

error[E0599]: no method named `downcast_ref` found for type `&std::boxed::Box<(dyn std::any::Any + std::marker::Sync + 'static)>` in the current scope
  --> src/main.rs:18:19
   |
18 |     let res = any.downcast_ref::<X>();
   |                   ^^^^^^^^^^^^

如果我使用关联函数语法调用它,它能找到函数并正常工作。
为什么编译器无法从类型为 dyn Any 的变量 any 中找到 downcast_ref() 方法?
1个回答

2
这是因为 Any::downcast_ref() 没有为 dyn Any + 'static + Sync 实现,只为以下类型实现:
  • dyn Any + 'static
  • dyn Any + 'static + Send
  • dyn Any + 'static + Send + Sync
"最初的回答"

1
嗯...看起来,dyn Any + 'static + Sync 可以自动转换为 dyn Any + 'static,因为函数式调用是有效的。 - Matthieu M.
1
但为什么这个排列没有实现呢? - Peter Hall
我猜这只是被遗忘了,还没有拉取请求。 - Tim Diekmann
2
@PeterHall:我在这个问题的讨论中发现了一个有趣的话题(https://github.com/rust-lang/rust/issues/18737),Niko介绍了`Any + Send的impl。似乎存在一个“子类型”关系的限制,阻止从Any + Sync中剥离Sync以考虑只在Any`上实现。这似乎更多是一种实现限制而不是基本类型系统限制。 - Matthieu M.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接