gpt4 book ai didi

generics - 预期的泛型类型,但找到了具体类型(实现特征绑定(bind))

转载 作者:行者123 更新时间:2023-11-29 08:18:40 26 4
gpt4 key购买 nike

我有两个方法做的事情非常相似,我确实想使用泛型和特征边界进行重构。

下面是我的例子的两种工作方式。

fn some_method_a(some_arg: u8) -> (Mode, Vec<A>)
{
let mode = match some_arg {
0 => Mode::ZERO,
_ => Mode::NOTZERO,
};

let some_as = vec![A::new(0), A::new(1)];
(mode, some_as)
}

fn some_method_b(some_arg: u8) -> (Mode, Vec<B>)
{
let mode = match some_arg {
0 => Mode::ZERO,
_ => Mode::NOTZERO,
};

let some_bs = vec![B::new("Testing".to_string())];
(mode, some_bs)
}

这是应该替换两者的方法。

fn some_method<T>(some_arg: u8) -> (Mode, Vec<T>)
where
T: Filterable,
{
let mode = match some_arg {
0 => Mode::ZERO,
_ => Mode::NOTZERO,
};

match &mode {
&Mode::ZERO => (mode, vec![A::new(0), A::new(1)]),
_ => (mode, vec![B::new("Testing".to_string())]),
}
}

但是,我现在收到此错误,即使 A(和 B)实现了 Filterable 特性,我已将其指定为方法的特性绑定(bind)。

error[E0308]: mismatched types
--> src/main.rs:11:36
|
11 | &Mode::ZERO => (mode, vec![A::new(0), A::new(1)]),
| ^^^^^^^^^ expected type parameter, found struct `A`
|
= note: expected type `T`
found type `A`

Permalink to playground这是程序的其余部分:

#[derive(Debug)]
enum Mode {
ZERO,
NOTZERO,
}

trait Filterable {
fn get_some_data(&self) -> u8 {
0
}
}

struct A {
some_data: u8,
}

struct B {
some_other_data: String,
}

impl A {
fn new(some_data: u8) -> A {
A { some_data }
}
}

impl B {
fn new(some_other_data: String) -> B {
B { some_other_data }
}
}

impl Filterable for A {
fn get_some_data(&self) -> u8 {
self.some_data
}
}

impl Filterable for B {}

some_method 需要做什么才能返回模式元组和 A 或 B 结构的向量?

最佳答案

我对 Rust 泛型的理解是,它们比您可能习惯的更像 C++ 模板,因为它们在编译时被单态化和扩展。

本质上是做什么的:

fn some_method<T>(some_arg: u8) -> (Mode, Vec<T>)
where T: Filterable,

...是(如果编译成功)创建此方法的两个版本。一个期望返回的 (Mode, Vec<A>)和一个希望返回的(Mode, Vec<B>) .当您以这种方式考虑时,这根本没有任何意义。

您想要的是返回一个实现特征 Filterable 的向量.因此,由于特征未确定大小,因此您需要将它们包装在已知大小的东西中。 Box 'ing 他们在这里做的伎俩:

fn some_method(some_arg: u8) -> (Mode, Vec<Box<Filterable>>)

这完全删除了泛型,只返回一个装箱的向量 Filterable -实现实例。

当然,现在的方法体也必须变成这样:

match &mode {
&Mode::ZERO => (mode, vec![Box::new(A::new(0)), Box::new(A::new(1))]),
_ => (mode, vec![Box::new(B::new("Testing".to_string()))]),
}

导致代码编译。

Here it is running on the Playground

关于generics - 预期的泛型类型,但找到了具体类型(实现特征绑定(bind)),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46106993/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com