Error: Expected Type Parameter, Found Closure

Error: Expected Type Parameter, Found Closure

我有以下 code:

struct Helper<F1: Fn()> {
    f: F1,
}

struct User<F2: Fn()> {
    h: Helper<F2>,
}

fn new_user<F3: Fn()>() -> User<F3> {
    User {
        // error: expected type parameter, found closure
        h: Helper { f: || {} },
    }
}

fn main(){}

所以 User 需要一个 Helper<F1>,F1 的类型由 User 指定,在本例中由 new_user 中的闭包指定。

此代码编译失败,在 new_user 中出现错误 expected type parameter, found closure。据我所知(例如参见 [​​=31=]),这是因为 new_user 上的类型参数 F3 的边界是由调用者指定的(或者签名可能?),所以尽管闭包实现了 Fn() 特征,但它无法限制类型参数 F3 以匹配闭包的类型。相反,预计 new_user 应该与任何给定的 F3 一起工作,但显然不会。

所以我的问题是:我该如何解决这个问题?有没有什么方法可以表达我想要 new_user 到 return 一个 User 并且 F2 设置为闭包的类型?

我尝试使用类型推断占位符:

// error: the type placeholder `_` is not allowed within types on item signatures
fn new_user() -> User<_> {
    User {
        h: Helper { f: || {} },
    }
}

我可以使用 Box,但这需要修改 Helper,这在我的实际情况下并不理想:

struct Helper {
    f: Box<dyn Fn()>,
}

struct User {
    h: Helper,
}

fn new_user() -> User {
    User {
        h: Helper { f: Box::new(|| {}) },
    }
}

fn main(){}

我也在尝试用自定义特征替换 Fn(),我可以专门为 User 实现,但到目前为止它很笨拙。

有什么建议吗?

tl;dr; 你可能想要这个:

fn new_user() -> User<impl Fn()> {
    User {
        h: Helper { f: || {} },
    }
}

更多详情:让我们看看这个:

fn new_user<F3: Fn()>() -> User<F3> {
    User {
        // error: expected type parameter, found closure
        h: Helper { f: || {} },
    }
}

这表明new_user "accepts" 任何满足Fn(),但调用者必须在调用new_user时指定它。但是,要成功进行类型检查,提供的类型必须与 new_user 正文中使用的类型相同(即 || {} 的类型)。但是,闭包具有匿名类型,因此 new_user 的调用者无法知道此类型,因为它无法查看 new_user 的实现,也无法找出为 F3.[=30 提供的内容=]

如前所述,您想要的是 new_user returns a User<SomeConcreteType> 其中 SomeConcreteType 满足 F3。调用者不需要 - 事实上它甚至不应该 - 指定 SomeConcreteType,因为它是在 new_user 内推断的。您可以按如下方式执行此操作:

fn new_user() -> User<impl Fn()> {
    User {
        h: Helper { f: || {} },
    }
}

这样,您指定 new_user 可以在没有任何参数的情况下被调用,它 returns 一个 User 具有满足 Fn().[=30= 的具体类型]