fn 在特征中采用 FnMut 闭包 -> "patterns aren't allowed in functions without bodies" 或 "please add mut"
fn taking FnMut closure in trait -> either "patterns aren't allowed in functions without bodies" or "please add mut"
pub struct A {}
pub trait FooTakesFnMut {
fn foo<VF>(&self, mut fnmuti32: VF)
where
VF: FnMut(i32);
}
impl FooTakesFnMut for A {
fn foo<VF>(&self, mut fnmuti32: VF)
where
VF: FnMut(i32),
{
for x in 1..5 {
fnmuti32(x);
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_00() {
let a = A;
let mut v = Vec::new();
let bar = |x| { v.push(x); };
a.foo(bar);
assert_eq!(v, vec![1,2,3,4]);
}
}
link to play rust playground copy
编译器抱怨:
error: patterns aren't allowed in functions without bodies
--> src/lib.rs:9:23
|
9 | fn foo<VF>(&self, mut fnmuti32: VF)
| ^^^^^^^^^^^^ help: remove `mut` from the parameter: `fnmuti32`
<--cut-->
但是在从 foo
函数签名中删除 mut
之后,它建议添加它们:
Compiling playground v0.0.1 (/playground)
error[E0596]: cannot borrow `fnmuti32` as mutable, as it is not declared as mutable
--> src/lib.rs:20:13
|
15 | fn foo<VF>(&self, fnmuti32: VF)
| -------- help: consider changing this to be mutable: `mut fnmuti32`
...
20 | fnmuti32(x);
| ^^^^^^^^ cannot borrow as mutable
<--cut-->
问题是您在特征定义中指定了 mut
。 mut
使变量绑定可变,这种信息属于特征实现,而不是声明。
如果您删除特征定义中的 mut
,您的代码将编译。
您的代码中存在一些错误,这应该有效:
pub struct A;
pub trait FooTakesFnMut {
fn foo<VF>(&self, fnmuti32: VF)
where
VF: FnMut(i32);
}
impl FooTakesFnMut for A {
fn foo<VF>(&self, mut fnmuti32: VF)
where
VF: FnMut(i32),
{
for x in 1..=5 {
fnmuti32(x);
}
}
}
#[cfg(test)]
#[allow(unused_imports)]
mod tests {
use super::*;
#[test]
fn test_00() {
let a = A;
let mut v = Vec::new();
let bar = |x| { v.push(x); };
a.foo(bar);
assert_eq!(v, vec![1,2,3,4,5]);
}
}
struct A {}
替换为 struct A;
以便 A
可以用作 ZST A
的唯一实例值而不是 A {}
.
参数附加的mut
关键字只是实现的问题,因为只要所有权转移到函数中,实现是否会发生变异参数不再由调用者决定。
1..5
更改为 1..=5
以便结果与提供的测试用例匹配。
pub struct A {}
pub trait FooTakesFnMut {
fn foo<VF>(&self, mut fnmuti32: VF)
where
VF: FnMut(i32);
}
impl FooTakesFnMut for A {
fn foo<VF>(&self, mut fnmuti32: VF)
where
VF: FnMut(i32),
{
for x in 1..5 {
fnmuti32(x);
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_00() {
let a = A;
let mut v = Vec::new();
let bar = |x| { v.push(x); };
a.foo(bar);
assert_eq!(v, vec![1,2,3,4]);
}
}
link to play rust playground copy
编译器抱怨:
error: patterns aren't allowed in functions without bodies
--> src/lib.rs:9:23
|
9 | fn foo<VF>(&self, mut fnmuti32: VF)
| ^^^^^^^^^^^^ help: remove `mut` from the parameter: `fnmuti32`
<--cut-->
但是在从 foo
函数签名中删除 mut
之后,它建议添加它们:
Compiling playground v0.0.1 (/playground)
error[E0596]: cannot borrow `fnmuti32` as mutable, as it is not declared as mutable
--> src/lib.rs:20:13
|
15 | fn foo<VF>(&self, fnmuti32: VF)
| -------- help: consider changing this to be mutable: `mut fnmuti32`
...
20 | fnmuti32(x);
| ^^^^^^^^ cannot borrow as mutable
<--cut-->
问题是您在特征定义中指定了 mut
。 mut
使变量绑定可变,这种信息属于特征实现,而不是声明。
如果您删除特征定义中的 mut
,您的代码将编译。
您的代码中存在一些错误,这应该有效:
pub struct A;
pub trait FooTakesFnMut {
fn foo<VF>(&self, fnmuti32: VF)
where
VF: FnMut(i32);
}
impl FooTakesFnMut for A {
fn foo<VF>(&self, mut fnmuti32: VF)
where
VF: FnMut(i32),
{
for x in 1..=5 {
fnmuti32(x);
}
}
}
#[cfg(test)]
#[allow(unused_imports)]
mod tests {
use super::*;
#[test]
fn test_00() {
let a = A;
let mut v = Vec::new();
let bar = |x| { v.push(x); };
a.foo(bar);
assert_eq!(v, vec![1,2,3,4,5]);
}
}
struct A {}
替换为struct A;
以便A
可以用作 ZSTA
的唯一实例值而不是A {}
.参数附加的
mut
关键字只是实现的问题,因为只要所有权转移到函数中,实现是否会发生变异参数不再由调用者决定。1..5
更改为1..=5
以便结果与提供的测试用例匹配。