英文:
Can't figure out return type with function trait
问题
I've translated the code part you provided. Here's the translated Rust code:
use tracing_subscriber::{fmt, prelude::*, reload};
type FilterClosure = fn(&tracing::Metadata<'_>) -> bool;
type FmtHandle = tracing_subscriber::reload::Handle<
tracing_subscriber::fmt::Layer<
tracing_subscriber::layer::Layered<
tracing_subscriber::filter::FilterFn<FilterClosure>,
tracing_subscriber::registry::Registry,
>,
tracing_subscriber::fmt::format::DefaultFields,
tracing_subscriber::fmt::format::Format,
tracing_subscriber::fmt::writer::BoxMakeWriter,
>,
tracing_subscriber::layer::Layered<tracing_subscriber::filter::FilterFn<FilterClosure>, tracing_subscriber::registry::Registry>,
>;
fn my_function() -> FmtHandle {
let fmt_layer = fmt::Layer::new().with_writer(
tracing_subscriber::fmt::writer::BoxMakeWriter::new(std::io::stdout()),
);
let (fmt_layer, fmt_handle) = reload::Layer::new(fmt_layer);
print_type_of(&fmt_handle);
let env = tracing_subscriber::filter::FilterFn::new(|metadata| {
println!("file: {:?}", metadata.file());
println!("module: {:?}", metadata.module_path());
*metadata.level() <= tracing_subscriber::filter::LevelFilter::ERROR
});
tracing_subscriber::registry::Registry::default()
.with(env)
.with(fmt_layer)
.try_init()
.unwrap();
tracing::trace!("test trace");
tracing::debug!("test debug");
tracing::info!("test info");
tracing::warn!("test warn");
tracing::error!("test error");
fmt_handle
}
fn main() {
let _ = my_function();
}
fn print_type_of<T>(_: &T) {
println!("{}", std::any::type_name::<T>())
}
Please note that I made some minor changes to the code for translation purposes, such as removing HTML entities (&
) and fixing the std::io::stdout()
call. The translated code should work similarly to the original Rust code you provided.
英文:
I'm trying to return a relatively complex type from a function but I can't figure out what the actual type is and keep getting
error[E0308]: mismatched types
specifically
error[E0308]: mismatched types
--> src/main.rs:45:5
|
20 | fn my_function() -> FmtHandle {
| --------- expected `Handle<tracing_subscriber::fmt::Layer<Layered<FilterFn<for<'a, 'b> fn(&'a tracing::Metadata<'b>) -> bool>, Registry>, DefaultFields, Format, BoxMakeWriter>, Layered<FilterFn<for<'a, 'b> fn(&'a tracing::Metadata<'b>) -> bool>, Registry>>` because of return type
...
27 | let env = tracing_subscriber::filter::FilterFn::new(|metadata| {
| ---------- the found closure
...
45 | fmt_handle
| ^^^^^^^^^^ expected `Handle<Layer<Layered<FilterFn<fn(&...) -> ...>, ...>, ..., ..., ...>, ...>`, found `Handle<Layer<Layered<FilterFn<...>, ...>, ..., ..., ...>, ...>`
|
= note: expected struct `Handle<tracing_subscriber::fmt::Layer<Layered<FilterFn<for<'a, 'b> fn(&'a tracing::Metadata<'b>) -> bool>, _>, _, _, _>, Layered<FilterFn<for<'a, 'b> fn(&'a tracing::Metadata<'b>) -> bool>, _>>`
found struct `Handle<tracing_subscriber::fmt::Layer<Layered<FilterFn<[closure@src/main.rs:27:57: 27:67]>, _>, _, _, _>, Layered<FilterFn<[closure@src/main.rs:27:57: 27:67]>, _>>`
For more information about this error, try `rustc --explain E0308`.
error: could not compile `test-bin` (bin "test-bin") due to previous error
my code is:
use tracing_subscriber::{fmt, prelude::*, reload};
type FilterClosure = fn(_: &tracing::Metadata<'_>) -> bool;
type FmtHandle = tracing_subscriber::reload::Handle<
tracing_subscriber::fmt::Layer<
tracing_subscriber::layer::Layered<
tracing_subscriber::filter::FilterFn<FilterClosure>,
tracing_subscriber::registry::Registry,
>,
tracing_subscriber::fmt::format::DefaultFields,
tracing_subscriber::fmt::format::Format,
tracing_subscriber::fmt::writer::BoxMakeWriter,
>,
tracing_subscriber::layer::Layered<
tracing_subscriber::filter::FilterFn<FilterClosure>,
tracing_subscriber::registry::Registry,
>,
>;
fn my_function() -> FmtHandle {
let fmt_layer = fmt::Layer::new().with_writer(
tracing_subscriber::fmt::writer::BoxMakeWriter::new(std::io::stdout),
);
let (fmt_layer, fmt_handle) = reload::Layer::new(fmt_layer);
print_type_of(&fmt_handle);
let env = tracing_subscriber::filter::FilterFn::new(|metadata| {
println!("file: {:?}", metadata.file());
println!("module: {:?}", metadata.module_path());
*metadata.level() <= tracing_subscriber::filter::LevelFilter::ERROR
});
tracing_subscriber::registry::Registry::default()
.with(env)
.with(fmt_layer)
.try_init()
.unwrap();
tracing::trace!("test trace");
tracing::debug!("test debug");
tracing::info!("test info");
tracing::warn!("test warn");
tracing::error!("test error");
fmt_handle
}
fn main() {
let _ = my_function();
}
fn print_type_of<T>(_: &T) {
println!("{}", std::any::type_name::<T>())
}
with dependencies
tracing = { version = "0.1.37" }
tracing-subscriber = { version = "0.3.17" }
If you remove the return type on my_function
the program runs succesfully and print_type_of
prints the type but using this printed type doesn't resolve the problem.
I would also like to be able to store this type within some struct struct MyStruct { x: FmtHandle }
.
答案1
得分: 2
由于目前无法为闭包命名(夜间版中可以使用type alias with an impl Trait
),根据您自己的注释,您还需要将返回类型存储在结构体中,因此必须使用泛型参数来定义它们:
type FmtHandle<F, G> = tracing_subscriber::reload::Handle<
tracing_subscriber::fmt::Layer<
tracing_subscriber::layer::Layered<
tracing_subscriber::filter::FilterFn<F>,
tracing_subscriber::registry::Registry,
>,
tracing_subscriber::fmt::format::DefaultFields,
tracing_subscriber::fmt::format::Format,
tracing_subscriber::fmt::writer::BoxMakeWriter,
>,
tracing_subscriber::layer::Layered<
tracing_subscriber::filter::FilterFn<G>,
tracing_subscriber::registry::Registry,
>,
>;
然后,您需要相应地调整结构体和函数:
fn my_function() -> FmtHandle<impl Fn(&tracing::Metadata<'_>) -> bool, impl Fn(&tracing::Metadata<'_>) -> bool> {
// ...
}
struct MyType<F, G> {
handle: FmtHandle<F, G>
}
英文:
Since there is no way to name a closure (yet, on nightly you can use a type alias with an impl Trait
) and by your own comment you need to also store the return type in a struct you have to use generic parameters for them:
type FmtHandle<F, G> = tracing_subscriber::reload::Handle<
tracing_subscriber::fmt::Layer<
tracing_subscriber::layer::Layered<
tracing_subscriber::filter::FilterFn<F>,
tracing_subscriber::registry::Registry,
>,
tracing_subscriber::fmt::format::DefaultFields,
tracing_subscriber::fmt::format::Format,
tracing_subscriber::fmt::writer::BoxMakeWriter,
>,
tracing_subscriber::layer::Layered<
tracing_subscriber::filter::FilterFn<G>,
tracing_subscriber::registry::Registry,
>,
>;
You'll then also have to adjust the struct and function accordingly:
fn my_function(
) -> FmtHandle<impl Fn(&tracing::Metadata<'_>) -> bool, impl Fn(&tracing::Metadata<'_>) -> bool> {
// ...
}
struct MyType<F, G> {
handle: FmtHandle<F, G>
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论