gpt4 book ai didi

rust - 如何解决分配中的 "expected struct, found type parameter"?

转载 作者:行者123 更新时间:2023-12-03 11:33:55 26 4
gpt4 key购买 nike

几天前刚开始使用 Rust。我现在正在移植一些 C++ 代码,这个问题似乎与常见的“预期结构,得到类型”排序相反。这段代码涉及两个类,一个容器类 A 和一个客户端类 B。

use std::vec::Vec;

struct A<T:FooTrait> {
children: Vec<*mut T>
}

impl <T:FooTrait> A<T> {
fn insert(&mut self, val: &mut T) -> Handle<T> {
self.children.push(val);
return Handle{owner: self};
}
}
struct B {
handle: Handle<B>
}

trait FooTrait {
fn set_handle<T:FooTrait>(&mut self, h: Handle<T>);
}

impl FooTrait for B {
fn set_handle<B:FooTrait>(&mut self, h: Handle<B>) {
self.handle = h; // <-- Here is the problem
}
}

struct Handle<T:FooTrait> {
owner: *mut A<T>
}

impl <T:FooTrait> Default for Handle<T> {
fn default()->Handle<T> {
Handle {
owner: std::ptr::null_mut()
}
}
}
fn main() {
let mut foo = A::<B> { children: Default::default() };
let mut b = B{handle: Default::default()};
b.handle = foo.insert(&mut b);
}
得到错误:
error[E0308]: mismatched types
--> src/main.rs:23:23
|
22 | fn set_handle<B:FooTrait>(&mut self, h: Handle<B>) {
| - this type parameter
23 | self.handle = h;
| ^ expected struct `B`, found type parameter `B`
|
= note: expected struct `Handle<B>` (struct `B`)
found struct `Handle<B>` (type parameter `B`)

最佳答案

简化版(playground) :

use std::marker::PhantomData;

struct B {
handle: PhantomData<B>,
}

trait FooTrait {
fn set_handle<T: FooTrait>(&mut self, h: PhantomData<T>);
}

impl FooTrait for B {
fn set_handle<BType: FooTrait>(&mut self, h: PhantomData<BType>) {
self.handle = h;
}
}
请注意,我在 set_handle 中更改了类型参数的名称。 .现在错误更清楚了:
error[E0308]: mismatched types
--> src/lib.rs:13:23
|
12 | fn set_handle<BType: FooTrait>(&mut self, h: PhantomData<BType>) {
| ----- this type parameter
13 | self.handle = h;
| ^ expected struct `B`, found type parameter `BType`
|
= note: expected struct `std::marker::PhantomData<B>`
found struct `std::marker::PhantomData<BType>`
在您的情况下,错误基本上是相同的,因为泛型参数是一种新类型,它掩盖了全局 struct B .
现在,该怎么办?这取决于你想得到什么。
  • 如果 struct B定义正确,set_handle只需处理B s,只需从 set_handle 中删除通用参数( playground ):
  • trait FooTrait {
    fn set_handle(&mut self, h: PhantomData<B>);
    }

    impl FooTrait for B {
    fn set_handle(&mut self, h: PhantomData<B>) {
    self.handle = h;
    }
    }
  • 如果 struct B定义是正确的,但是 set_handle必须能够根据 Self 使用不同的处理程序类型,使用关联类型(playground):
  • trait FooTrait {
    type T: FooTrait;
    fn set_handle(&mut self, h: PhantomData<Self::T>);
    }

    impl FooTrait for B {
    type T = B;
    fn set_handle(&mut self, h: PhantomData<B>) {
    self.handle = h;
    }
    }
    现在实现 block 将选择它将获得什么样的参数(处理程序,在你的情况下)。
  • 如果 set_handle定义正确,即调用者可以选择处理程序的类型,那么struct B也必须是通用的。但是,在这种情况下,您基本上不能使用基于特征的方法,因为特征也必须是通用的,并且您将无法在不提供参数的情况下简单地在任何通用绑定(bind)中使用它(也必须绑定(bind),无限)。
  • 关于rust - 如何解决分配中的 "expected struct, found type parameter"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63877098/

    26 4 0