Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Enums 图书馆作者最喜欢的子类型选择是什么?为什么?_Enums_Rust_Polymorphism_Traits_Subtype - Fatal编程技术网

Enums 图书馆作者最喜欢的子类型选择是什么?为什么?

Enums 图书馆作者最喜欢的子类型选择是什么?为什么?,enums,rust,polymorphism,traits,subtype,Enums,Rust,Polymorphism,Traits,Subtype,我有两种类型,A和B,它们共享一个公共接口T。我想通过接口T编写既能使用A又能使用B的函数 < C++ >中,我将 T 为代码< A/和代码> B/COD>的抽象超类,并编写函数接受类型 t > 在锈病方面,我似乎有两个很好的解决方案 枚举类型 在T的方法中,我可以匹配变量以专门化类型,然后在访问变量成员时编写我想要的任何内容。 然后,我可以编写直接接受T类型参数的函数: fn f(t: T) { // I can use t.method here } 特点 对于traits,类型

我有两种类型,
A
B
,它们共享一个公共接口
T
。我想通过接口
T
编写既能使用
A
又能使用
B
的函数

< C++ >中,我将<代码> T <代码>为代码< A/<代码>和代码> B/COD>的抽象超类,并编写函数接受类型<代码> t<代码> >

在锈病方面,我似乎有两个很好的解决方案

枚举类型 在
T
的方法中,我可以匹配变量以专门化类型,然后在访问变量成员时编写我想要的任何内容。 然后,我可以编写直接接受
T
类型参数的函数:

fn f(t: T) {
    // I can use t.method here
}
特点 对于traits,类型已经在方法定义中专门化了。但是,要使用
T.method
,我需要编写一个通用函数:

fn f<X: T>(t: X) {
    // I can use t.method here
}
fn f(t:X){
//我可以在这里使用t方法
}
这里让我感到困扰的是,虽然这两种解决方案都能完美地工作,但实现是公开的:
f
的签名在这两个示例中是不同的。如果我编写了一个带有枚举的库,但最终决定我真正想要的是traits,那么每个用户级别的类型签名都需要更改

鉴于这一事实,图书馆作者选择了什么样的选择,为什么

<>请注意,我不特别关心继承,我不想把C++习语导入锈,我想知道更好的选择是什么。 图书馆作者喜欢使用枚举还是特征

建筑工人喜欢用钉子或螺丝钉吗

医生喜欢使用胶水、缝线或订书钉吗

这是一种荒谬的二分法。这两种能力都存在,并且都在使用。人们为手头的特定工作使用正确的工具

首先回顾并重读这一章

简言之,特征允许无限多态性,而枚举是严格有界的。真的,这就是主要的区别。回顾你的问题领域需要什么,并使用正确的东西

实现是公开的:
f
的签名在两个示例中都不同

是的,设计软件有时需要一些前期的思考、关注和设计

如果向用户公开枚举,然后添加、删除或修改变量,则需要更新该枚举的每次使用

如果您向用户公开一个特性,然后添加、删除或修改一个方法,那么该特性的每个用法都需要更新

在导致此问题的枚举或特征之间进行选择并没有什么特别的。您还可以重命名方法、添加、删除或重新排列参数。有很多方法会给用户带来麻烦

如果更改API,您的用户将受到影响

我需要写一个泛型函数

您不需要这样做,但出于性能原因,您可能应该默认使用它。如果
引起惊愕,可以使用特征对象,如
fn f(t:&t)
fn f(t:Box)

用enum编写一个库,但最终确定我真正想要的是traits

既然您知道不必总是选择其中一个,也要意识到您可以将它们一起使用:

enum Pet {
    Cat,
    Dog,
    Other(Box<Animal>),
}

trait Animal {}


就个人观点而言,如果我仍然在原型化我的代码,并且不清楚哪种选择更好,我可能会默认使用特性。无界多态性更符合我对依赖注入和测试风格的偏好。

从你回答的防御语气来看,你似乎将我的问题解释为生锈,而事实并非如此;我知道C++比锈少,所以也许比较不是最好的。多亏了指向无界/有界多态性的指针,我将对此进行研究。作为一个具体的例子,我正在构建一个光线跟踪器,它支持可以在空间中定位和渲染的形状。我将有一个用于定位属性的“Transform”数据类型和一个用于渲染属性的“Material”数据类型。然后,我可以将形状实现为包含这些数据类型的结构和类型enum(Sphere、Cube、Mesh等)。或者,我可以有一个“形状”特征(或者可能是“交叉的”),并让不同的形状类型实现这个特征。在这种情况下,两种选择的取舍是什么?@yawn我本不打算防御性的,但我的意思是(以轻松的方式)传达少量的烦恼/挫折。当一个问题预设了世界的某个状态时,这是令人恼火的,因为这样一来,答案就必须花时间撕毁这个信念,回到基础上来,然后再从那里建立起来。在本例中,我看到了两个选项:“枚举和特征在功能上是可交换的”和“枚举和特征之间的选择会影响我的用户”。然而,最好了解这个最初的世界观,这样才不会意外地妨碍理解。
fn f<X: T>(t: X) {
    // I can use t.method here
}
enum Pet {
    Cat,
    Dog,
    Other(Box<Animal>),
}

trait Animal {}
trait TimeSource {
    fn now() -> u64;
}

enum Builtin {
    Ntp,
    Sundial,
}

impl TimeSource for Builtin {
    // ...
}