我想访问我的
log::Log
impl 实例以访问特定字段,但是一旦我收到引用,我就无法将其向下转换为我的结构。
我尝试将记录器引用转换为
core::any::Any
,然后将其向下转换为我的原始结构,但我总是获得None
。
use core::any::Any;
pub trait AToAny: 'static {
fn as_any(&self) -> &dyn Any;
}
impl<T: 'static> AToAny for T {
fn as_any(&self) -> &dyn Any {
self
}
}
struct MyLogger {}
impl log::Log for MyLogger {
fn enabled(&self, _: &log::Metadata<'_>) -> bool { todo!() }
fn log(&self, _: &log::Record<'_>) { todo!() }
fn flush(&self) { todo!() }
}
pub fn main() {
let logger_impl = MyLogger {};
log::set_boxed_logger(Box::new(logger_impl)).unwrap();
let logger = log::logger();
let logger_any = logger.as_any();
let logger_impl = logger_any.downcast_ref::<MyLogger>()
.expect("downcast failed");
}
我也尝试过不通过日志初始化函数传递,但我得到了相同的结果:
use core::any::Any; // 0.10.1
pub trait AToAny: 'static {
fn as_any(&self) -> &dyn Any;
}
impl<T: 'static> AToAny for T {
fn as_any(&self) -> &dyn Any {
self
}
}
struct MyLogger {}
impl log::Log for MyLogger {
fn enabled(&self, _: &log::Metadata<'_>) -> bool { todo!() }
fn log(&self, _: &log::Record<'_>) { todo!() }
fn flush(&self) { todo!() }
}
pub fn main() {
let logger_impl = MyLogger {};
let logger_boxed: Box<MyLogger> = Box::new(logger_impl);
let logger: &'static mut dyn log::Log = Box::leak(logger_boxed);
let logger_any = logger.as_any();
let logger_impl = logger_any.downcast_ref::<MyLogger>()
.expect("downcast failed");
}
这是操场上的代码。
我看到
type_id
变量的 logger
与 type_id
的 logger_impl
不同,所以我相信这就是阻止我进行沮丧的原因,但我无法理解我应该如何做解决这个问题。
您正在调用
<&dyn Log>::as_any
,但您只能将其向下转换为 &dyn Log
。 A &dyn Log
不会暴露向下转换为 MyLogger
所需的信息。
幸运的是,您在这里根本不需要
Any
或向下转型,因为您可以仅使用共享引用来设置全局记录器:
struct MyLogger {}
impl MyLogger {
fn foo(&self) {
println!("foo")
}
}
pub fn main() {
let logger: &MyLogger = Box::leak(Box::new(MyLogger {}));
log::set_logger(logger as &dyn log::Log).unwrap();
logger.foo(); // can still call inherent MyLogger::foo
}