无法确定函数特征的返回类型

huangapple go评论110阅读模式
英文:

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 (&amp;) 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
  --&gt; src/main.rs:45:5
   |
20 | fn my_function() -&gt; FmtHandle {
   |                     --------- expected `Handle&lt;tracing_subscriber::fmt::Layer&lt;Layered&lt;FilterFn&lt;for&lt;&#39;a, &#39;b&gt; fn(&amp;&#39;a tracing::Metadata&lt;&#39;b&gt;) -&gt; bool&gt;, Registry&gt;, DefaultFields, Format, BoxMakeWriter&gt;, Layered&lt;FilterFn&lt;for&lt;&#39;a, &#39;b&gt; fn(&amp;&#39;a tracing::Metadata&lt;&#39;b&gt;) -&gt; bool&gt;, Registry&gt;&gt;` because of return type
...
27 |     let env = tracing_subscriber::filter::FilterFn::new(|metadata| {
   |                                                         ---------- the found closure
...
45 |     fmt_handle
   |     ^^^^^^^^^^ expected `Handle&lt;Layer&lt;Layered&lt;FilterFn&lt;fn(&amp;...) -&gt; ...&gt;, ...&gt;, ..., ..., ...&gt;, ...&gt;`, found `Handle&lt;Layer&lt;Layered&lt;FilterFn&lt;...&gt;, ...&gt;, ..., ..., ...&gt;, ...&gt;`
   |
   = note: expected struct `Handle&lt;tracing_subscriber::fmt::Layer&lt;Layered&lt;FilterFn&lt;for&lt;&#39;a, &#39;b&gt; fn(&amp;&#39;a tracing::Metadata&lt;&#39;b&gt;) -&gt; bool&gt;, _&gt;, _, _, _&gt;, Layered&lt;FilterFn&lt;for&lt;&#39;a, &#39;b&gt; fn(&amp;&#39;a tracing::Metadata&lt;&#39;b&gt;) -&gt; bool&gt;, _&gt;&gt;`
              found struct `Handle&lt;tracing_subscriber::fmt::Layer&lt;Layered&lt;FilterFn&lt;[closure@src/main.rs:27:57: 27:67]&gt;, _&gt;, _, _, _&gt;, Layered&lt;FilterFn&lt;[closure@src/main.rs:27:57: 27:67]&gt;, _&gt;&gt;`

For more information about this error, try `rustc --explain E0308`.
error: could not compile `test-bin` (bin &quot;test-bin&quot;) due to previous error

my code is:

use tracing_subscriber::{fmt, prelude::*, reload};

type FilterClosure = fn(_: &amp;tracing::Metadata&lt;&#39;_&gt;) -&gt; bool;
type FmtHandle = tracing_subscriber::reload::Handle&lt;
    tracing_subscriber::fmt::Layer&lt;
        tracing_subscriber::layer::Layered&lt;
            tracing_subscriber::filter::FilterFn&lt;FilterClosure&gt;,
            tracing_subscriber::registry::Registry,
        &gt;,
        tracing_subscriber::fmt::format::DefaultFields,
        tracing_subscriber::fmt::format::Format,
        tracing_subscriber::fmt::writer::BoxMakeWriter,
    &gt;,
    tracing_subscriber::layer::Layered&lt;
        tracing_subscriber::filter::FilterFn&lt;FilterClosure&gt;,
        tracing_subscriber::registry::Registry,
    &gt;,
&gt;;

fn my_function() -&gt; 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(&amp;fmt_handle);

    let env = tracing_subscriber::filter::FilterFn::new(|metadata| {
        println!(&quot;file: {:?}&quot;, metadata.file());
        println!(&quot;module: {:?}&quot;, metadata.module_path());
        *metadata.level() &lt;= tracing_subscriber::filter::LevelFilter::ERROR
    });

    tracing_subscriber::registry::Registry::default()
        .with(env)
        .with(fmt_layer)
        .try_init()
        .unwrap();

    tracing::trace!(&quot;test trace&quot;);
    tracing::debug!(&quot;test debug&quot;);
    tracing::info!(&quot;test info&quot;);
    tracing::warn!(&quot;test warn&quot;);
    tracing::error!(&quot;test error&quot;);

    fmt_handle
}

fn main() {
    let _ = my_function();
}
fn print_type_of&lt;T&gt;(_: &amp;T) {
    println!(&quot;{}&quot;, std::any::type_name::&lt;T&gt;())
}

with dependencies

tracing = { version = &quot;0.1.37&quot; }
tracing-subscriber = { version = &quot;0.3.17&quot; }

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&lt;F, G&gt; = tracing_subscriber::reload::Handle&lt;
    tracing_subscriber::fmt::Layer&lt;
        tracing_subscriber::layer::Layered&lt;
            tracing_subscriber::filter::FilterFn&lt;F&gt;,
            tracing_subscriber::registry::Registry,
        &gt;,
        tracing_subscriber::fmt::format::DefaultFields,
        tracing_subscriber::fmt::format::Format,
        tracing_subscriber::fmt::writer::BoxMakeWriter,
    &gt;,
    tracing_subscriber::layer::Layered&lt;
        tracing_subscriber::filter::FilterFn&lt;G&gt;,
        tracing_subscriber::registry::Registry,
    &gt;,
&gt;;

You'll then also have to adjust the struct and function accordingly:

fn my_function(
) -&gt; FmtHandle&lt;impl Fn(&amp;tracing::Metadata&lt;&#39;_&gt;) -&gt; bool, impl Fn(&amp;tracing::Metadata&lt;&#39;_&gt;) -&gt; bool&gt; {
    // ...
}

struct MyType&lt;F, G&gt; {
    handle: FmtHandle&lt;F, G&gt;
}

huangapple
  • 本文由 发表于 2023年8月10日 20:32:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/76875773.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定