不满足 Rust 特征边界。中间分配是必要的,或者删除 Trait 实现
Rust trait bounds not satisfied. Either intermediate assignment is necessary, or removal of a Trait implementation
我希望能够为不同的函数签名实现一个特征,但编译器给我奇怪的错误。我试图在以下最小示例中减少问题:
trait MyTrait<P> {
fn trait_method(&self, p: P);
}
impl MyTrait<fn(u32)> for MyStruct {
fn trait_method(&self, p: fn(u32)) {
todo!()
}
}
impl MyTrait<fn(u64)> for MyStruct {
fn trait_method(&self, p: fn(u64)) {
todo!()
}
}
struct MyStruct;
fn test() {
let my_struct = MyStruct;
// Gives error:
// the trait bound `MyStruct: MyTrait<fn(u32) {test_fun}>` is not satisfied
// the following implementations were found:
// <MyStruct as MyTrait<fn(u32)>>
// <MyStruct as MyTrait<fn(u64)>>
my_struct.trait_method(test_fun);
// Is ok
let fun: fn(u32) = test_fun;
my_struct.trait_method(fun);
// Gives error
// the trait bound `MyStruct: MyTrait<[closure@src/main.rs:176:28: 176:39]>` is not satisfied
// the following implementations were found:
// <MyStruct as MyTrait<fn(u32)>>
// <MyStruct as MyTrait<fn(u64)>>
my_struct.trait_method(|hi: u32|{});
// Is ok
let fun: fn(u32) = |hi: u32|{};
my_struct.trait_method(fun);
}
fn test_fun(hi: u32) {}
如果我删除 impl MyTrait<fn(u64)>
块,那么问题就会消失,我可以使用任何一种方式调用 Trait 函数。只有当我有多个相同特征的实现时,才会出现这些错误。
为什么这个 Rust 代码不正确,我可以用什么方法来解决这个问题?对我来说非常重要的是它可以在没有中间赋值的情况下调用,因为这个特征最终会出现在 public API.
提前致谢
编辑:
以下代码也适用:
my_struct.trait_method(test_fun as fn(u32));
让我们比较一下:
let fun: fn(u32) = test_fun;
还有这个:
let fun = test_fun;
第一个例子中 fun
的类型明确设置为 fn(u32)
,而在第二个版本中它实际上是 fn(u32) {test_fun}
。那是两种不同的类型。第一个是 函数指针 。第二个是功能项。当您显式指定 fun
的类型时,发生的事情称为 coercion.
好的,我设法解决了这个问题:
pub trait VarFunc<A, P, R, T> {}
impl<F, A: Actor, P, R> VarFunc<A, P, R, WithState> for F where
F: Fn(&mut A, &mut State<A>, P) -> Flow<A, R>
{
}
impl<F, A: Actor, P, R> VarFunc<A, P, R, WithoutState> for F where
F: Fn(&mut A, P) -> Flow<A, R>
{
}
pub struct WithState;
pub struct WithoutState;
基本上,我创建了一个新特征 VarFunc
,它可以同时实现 WithState
和 WithoutState
。然后,在指定 Trait impl 时,我们不使用 F: Fn(X) -> Y
,而是使用 F: VarFunc<StateX/StateY>
,这实际上可以被编译器视为不同的
我希望能够为不同的函数签名实现一个特征,但编译器给我奇怪的错误。我试图在以下最小示例中减少问题:
trait MyTrait<P> {
fn trait_method(&self, p: P);
}
impl MyTrait<fn(u32)> for MyStruct {
fn trait_method(&self, p: fn(u32)) {
todo!()
}
}
impl MyTrait<fn(u64)> for MyStruct {
fn trait_method(&self, p: fn(u64)) {
todo!()
}
}
struct MyStruct;
fn test() {
let my_struct = MyStruct;
// Gives error:
// the trait bound `MyStruct: MyTrait<fn(u32) {test_fun}>` is not satisfied
// the following implementations were found:
// <MyStruct as MyTrait<fn(u32)>>
// <MyStruct as MyTrait<fn(u64)>>
my_struct.trait_method(test_fun);
// Is ok
let fun: fn(u32) = test_fun;
my_struct.trait_method(fun);
// Gives error
// the trait bound `MyStruct: MyTrait<[closure@src/main.rs:176:28: 176:39]>` is not satisfied
// the following implementations were found:
// <MyStruct as MyTrait<fn(u32)>>
// <MyStruct as MyTrait<fn(u64)>>
my_struct.trait_method(|hi: u32|{});
// Is ok
let fun: fn(u32) = |hi: u32|{};
my_struct.trait_method(fun);
}
fn test_fun(hi: u32) {}
如果我删除 impl MyTrait<fn(u64)>
块,那么问题就会消失,我可以使用任何一种方式调用 Trait 函数。只有当我有多个相同特征的实现时,才会出现这些错误。
为什么这个 Rust 代码不正确,我可以用什么方法来解决这个问题?对我来说非常重要的是它可以在没有中间赋值的情况下调用,因为这个特征最终会出现在 public API.
提前致谢
编辑: 以下代码也适用:
my_struct.trait_method(test_fun as fn(u32));
让我们比较一下:
let fun: fn(u32) = test_fun;
还有这个:
let fun = test_fun;
第一个例子中 fun
的类型明确设置为 fn(u32)
,而在第二个版本中它实际上是 fn(u32) {test_fun}
。那是两种不同的类型。第一个是 函数指针 。第二个是功能项。当您显式指定 fun
的类型时,发生的事情称为 coercion.
好的,我设法解决了这个问题:
pub trait VarFunc<A, P, R, T> {}
impl<F, A: Actor, P, R> VarFunc<A, P, R, WithState> for F where
F: Fn(&mut A, &mut State<A>, P) -> Flow<A, R>
{
}
impl<F, A: Actor, P, R> VarFunc<A, P, R, WithoutState> for F where
F: Fn(&mut A, P) -> Flow<A, R>
{
}
pub struct WithState;
pub struct WithoutState;
基本上,我创建了一个新特征 VarFunc
,它可以同时实现 WithState
和 WithoutState
。然后,在指定 Trait impl 时,我们不使用 F: Fn(X) -> Y
,而是使用 F: VarFunc<StateX/StateY>
,这实际上可以被编译器视为不同的