gpt4 book ai didi

generics - 为什么在具有泛型类型参数的结构定义中使用特征边界?

转载 作者:行者123 更新时间:2023-12-05 03:16:49 24 4
gpt4 key购买 nike

我可以定义一个结构类型,它使用具有特征绑定(bind)的泛型类型参数:

struct MyStruct<T: Clone> {
field: T,
}

这使我无法使用不符合特征界限的泛型实例化 MyStruct:

// Note: does not implement Clone
struct UnitStruct;

fn main() {
// ERROR: Unsatisfied trait bound: UnitStruct: Clone
let s = MyStruct { field: UnitStruct };
}

但是为什么我要这样定义我的结构呢?对 MyStruct 的实例化施加此类限制的用例是什么?

我注意到即使在 MyStruct 定义中绑定(bind)了 trait,如果我定义一个使用 MyStruct 的接口(interface),我仍然必须重复特征界限:

// This works
fn func<T: Clone>(s: MyStruct<T>) -> T { s.field.clone() }

// This does not. Compiler demands a trait bound for `T`
fn func<T>(s: MyStruct<T>) -> T { s.field.clone() }

最佳答案

通常,您希望尽可能避免向结构添加特征边界。当您以这种方式添加特征边界时,您将不得不在每个 impl<T: A + B + C + Etc> for Foo<T> 上再次写出特征边界。 .这对你来说是更多的工作,如果不是所有这些特性对于 impl 都是必需的,甚至会降低可读性。阻止你正在写。类似 Clone 的特征没有关联类型或静态函数的类型可能不应包含在类型范围中,除非您有特定的理由这样做。

您可以通过这种方式添加特征边界的原因是它可以大大提高可读性,并且在某些情况下它在很大程度上是不可避免的,例如关联类型或字段必须是 Sized。 .

use std::sync::mspc::Receiver;

trait FooProcessor {
type Input: Sized + Send;
type Output: Sized;

fn do_foo(&mut self, input: Self::Input) -> Self::Output;
}


struct FooHandler<P: FooProcessor> {
processor: P,
input_channel: Receiver<P::Input>,
outputs: Vec<P::Output>,
}

我们可以通过扩展以添加更多类型参数来避免这种情况,但这很快就会变得困惑。这会大大降低代码的可读性,如果您有多个嵌套的通用结构,情况会变得更糟。

struct FooHandler<P, I, O> {
processor: P,
input_channel: Receiver<I>,
outputs: Vec<O>,
}

还有一个很重要的原因就是避免出错。如果类型在泛型字段中没有意义,那么您可以通过在结构参数上强制执行它来让编译器及早捕获它。围绕使用 Foo<Bar> 的想法编写代码并不是一种好感觉。才发现Bar实际上从来都不是一个有效的选项。

关于generics - 为什么在具有泛型类型参数的结构定义中使用特征边界?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74454620/

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