如何使用具有闭包成员的结构制作新的关联函数?

and*_*man 5 rust

我几乎对为什么该代码不起作用有一个直观的认识,但是我不能完全依靠它。我认为这与新函数每次都有不同的返回类型有关。

为什么会有问题呢?为什么直接创建有效?

struct Struct<T>
where
    T: Fn(&[u8]),
{
    func: T,
}

impl<T> Struct<T>
where
    T: Fn(&[u8]),
{
    fn new() -> Struct<T> {
        // this doesn't work
        Struct { func: |msg| {} }
    }
}

fn main() {
    // this works
    let s = Struct { func: |msg| {} };
}
Run Code Online (Sandbox Code Playgroud)

错误是

struct Struct<T>
where
    T: Fn(&[u8]),
{
    func: T,
}

impl<T> Struct<T>
where
    T: Fn(&[u8]),
{
    fn new() -> Struct<T> {
        // this doesn't work
        Struct { func: |msg| {} }
    }
}

fn main() {
    // this works
    let s = Struct { func: |msg| {} };
}
Run Code Online (Sandbox Code Playgroud)

phi*_*mue 5

tl;博士; 您可以执行以下操作:

fn new() -> Struct<impl Fn(&[u8])> {
    Struct { func: |msg| {} }
}
Run Code Online (Sandbox Code Playgroud)

更详细:

让我们剖析你的impl块:

impl<T> Struct<T>
where
    T: Fn(&[u8]),
{
    fn new() -> Struct<T> {
        // this doesn't work
        Struct { func: |msg| {} }
    }
}
Run Code Online (Sandbox Code Playgroud)

我们从:

impl<T> Struct<T>
where
    T: Fn(&[u8]),
Run Code Online (Sandbox Code Playgroud)

这告诉编译器整个impl块对于任何 T令人满意的Fn(&[u8]).

现在:

fn new() -> Struct<T> {
    // this doesn't work
    Struct { func: |msg| {} }
}
Run Code Online (Sandbox Code Playgroud)

你说它new返回 a Struct<T>,我们在块中声明它里面的一切都适用于任何 T令人满意的Fn(&[u8])。然而,返回一个特定实例Struct,即一个由参数化|msg| {}-这样,返回值不能是Struct<T>任何 T满足Fn(&[u8])

但是,您可以对其进行修改以执行以下操作:

fn new() -> Struct<impl Fn(&[u8])> {
    Struct { func: |msg| {} }
}
Run Code Online (Sandbox Code Playgroud)

这告诉编译器new返回 a Struct,其参数已知满足Fn(&[u8]),因此编译器应该推断它。特别是它没有假设T并返回一种特定类型

然而,在直接初始化中,我们告诉编译器:

let s = Struct { func: |msg| {} };
Run Code Online (Sandbox Code Playgroud)

编译器看到您想要创建 aStruct并且知道 - 为了创建它 - 它必须推断Tres的类型。func. 它看到您传递了|msg| {}for func,推断了闭包的类型,现在知道要放入T.