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| {} };
}
错误是
error[E0308]: mismatched types
--> src/main.rs:14:24
|
14 | Struct { func: |msg| {} }
| ^^^^^^^^ expected type parameter, found closure
|
= note: expected type `T`
found type `[closure@src/main.rs:14:24: 14:32]`
解决方案
tl;博士; 您可以执行以下操作:
fn new() -> Struct<impl Fn(&[u8])> {
Struct { func: |msg| {} }
}
更详细:
让我们剖析你的impl
块:
impl<T> Struct<T>
where
T: Fn(&[u8]),
{
fn new() -> Struct<T> {
// this doesn't work
Struct { func: |msg| {} }
}
}
我们从:
impl<T> Struct<T>
where
T: Fn(&[u8]),
这告诉编译器整个impl
块对于任何 T
令人满意的Fn(&[u8])
.
现在:
fn new() -> Struct<T> {
// this doesn't work
Struct { func: |msg| {} }
}
你说new
返回 a Struct<T>
,而我们在块内声明它里面的所有东西都适用于任何 T
令人满意的Fn(&[u8])
。但是,您返回的一个特定实例,Struct
即参数化的实例|msg| {}
- 因此,返回值不能是Struct<T>
任何令人满意 T
的Fn(&[u8])
。
但是,您可以对其进行修改以执行以下操作:
fn new() -> Struct<impl Fn(&[u8])> {
Struct { func: |msg| {} }
}
这告诉编译器new
返回 a Struct
,其参数已知满足Fn(&[u8])
,因此编译器应该推断它。特别是它没有关于T
并返回一种特定类型的假设。
然而,在直接初始化中,我们告诉编译器:
let s = Struct { func: |msg| {} };
编译器看到您想要创建 aStruct
并且知道 - 为了创建它 - 它必须推断T
res 的类型。func
. 它看到你传递|msg| {}
了 for func
,推断闭包的类型,现在知道要放入的具体类型T
。
推荐阅读
- html - 使用 webpack 构建 i18n 多页站点的正确方法是什么?
- javascript - 数组数组的 JavaScript reduce() 方法行为
- mysql - mysqldump 丢失了外键约束的引用动作子句
- javascript - React img onError 事件未触发
- javascript - 如何刷新模式弹出窗口中的数据或转发到模式弹出窗口
- laravel - Laravel 5 多租户应用程序,带有用于 octoberCMS 的单个数据库
- php - 如何为 FROM 设置别名?在 php laravel 中
- python - 使用 Visual Studio 在 C++ 中嵌入 Python 代码,无需安装 Python
- symfony - Symfony 资产函数在 http url 前面添加 /
- html - 如何将所有元素放在弹性列的底部