tl;dr; You can do the following:
fn new() -> Struct<impl Fn(&[u8])> { Struct { func: |msg| {} } }
More detailed:
Let's dissect your impl block:
impl<T> Struct<T> where T: Fn(&[u8]), { fn new() -> Struct<T> { // this doesn't work Struct { func: |msg| {} } } }
We start with:
impl<T> Struct<T> where T: Fn(&[u8]),
This tells the compiler that the whole impl block is "valid" for any T satisfying Fn(&[u8]).
Now:
fn new() -> Struct<T> { // this doesn't work Struct { func: |msg| {} } }
You say that new returns a Struct<T>, and we are within the block stating that everything inside it works for any T satisfying Fn(&[u8]). However, you return one particular instance of Struct, namely the one parametrized by |msg| {} - thus, the return value can not be a Struct<T> for any T satisfying Fn(&[u8]).
However, you can modify it to do the following:
fn new() -> Struct<impl Fn(&[u8])> { Struct { func: |msg| {} } }
This tells the compiler that new returns a Struct, whose parameter is known to satisfy Fn(&[u8]), so that the compiler should infer it. In particular it has no assumptions about T and returns one particular type.
In the direct initialization, however, we tell the compiler:
let s = Struct { func: |msg| {} };
The compiler sees that you want to create a Struct and knows that - in order to create it - it must infer the type for T res. func. It sees that you passed |msg| {} for func, infers the type for the closure and now knows a concrete type to put into the T.
Tis?" You want the implementation ofnewto decide what closure to return, but generics let the caller decide what typeTis. I'm pretty sure there's another question that addresses this... I'll look for it.impl Trait. What is the correct way to return an Iterator (or any other trait)? is the other question I was looking for. Just changefn new() -> Struct<T>tofn new() -> Struct<impl Fn(&[u8])>and it will work.for<'r> <_ as std::ops::FnOnce<(&'r [u8],)>>::Output == ()"