- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有两种类型,A
和 B
, 它们共享一个公共(public)接口(interface) T
.我想编写同时适用于 A
的函数和 B
通过界面T
.
在 C++ 中,我会有 T
是两者的抽象父类(super class) A
和 B
, 并编写接受 T
类型参数的函数.
在 Rust 中,我似乎有两个很好的解决方案。
enum T {
A { /* ... */ },
B { /* ... */ },
}
impl T {
fn method(&self) {
match *self {
// ...
}
}
}
在T
的方法中,我可以匹配变体以专门化类型,然后在访问变体成员时编写我想要的任何内容。然后我可以编写接受类型参数的函数 T
直接:
fn f(t: T) {
// I can use t.method here
}
trait T {
// ...
}
struct A { /* ... */ }
struct B { /* ... */ }
impl T for A {
fn method(&self) {
// ...
}
}
impl T for B {
fn method(&self) {
// ...
}
}
有了 traits,类型已经专门化在方法定义中。但是,要使用 T.method
,我需要编写一个通用函数:
fn f<X: T>(t: X) {
// I can use t.method here
}
让我感到困扰的是,虽然这两种解决方案都可以完美运行,但实现却暴露了:f
的签名在这两个例子中是不同的。如果我写了一个带有枚举的库,但最终决定我真正想要的是特征,那么每个用户级类型签名都需要更改!
鉴于这一事实,图书馆作者会做出怎样的选择,为什么?
请注意,我并不特别关心继承,我不打算将 C++ 习语导入 Rust,我试图了解更好的选择是什么。
最佳答案
Do library writers favor using enums or traits?
Do builders favor using nails or screws?
Do doctors favor using glue, stitches, or staples?
这是一个荒谬的二分法。这两种能力都存在并且都被使用。人们使用正确的工具来完成手头的特定工作。
首先返回并重新阅读 The Rust Programming Language章Is Rust an Object-Oriented Programming Language? .
简而言之,特征允许无限制的多态性,而枚举则有严格的限制。真的,这是主要的区别。查看您的问题域需要什么并使用正确的东西。
the implementation is exposed: the signature of
f
is different in both examples
是的,设计软件有时需要一定的前期思考、细心和设计。
如果您向用户公开一个枚举,然后添加、删除或修改一个变体,则该枚举的每次使用都需要更新。
如果您向用户公开一个特征,然后添加、删除或修改一个方法,则该特征的每次使用都需要更新。
在导致此问题的枚举或特征之间进行选择并没有什么特别之处。您还可以重命名该方法,添加、删除或重新排序您的参数。有很多方法会给您的用户带来麻烦。
如果您更改 API,您的用户将受到影响。
I need to write a generic function
您不需要,但出于性能原因,您可能应该默认使用它。您可以使用像 fn f(t: &T)
这样的特征对象或 fn f(t: Box<T>)
如果<T>
引起 panic 。
write a library with enums, but eventually decide what I really wanted was traits
现在您知道您不必总是选择一个或另一个,也意识到您可以一起使用它们:
enum Pet {
Cat,
Dog,
Other(Box<Animal>),
}
trait Animal {}
trait TimeSource {
fn now() -> u64;
}
enum Builtin {
Ntp,
Sundial,
}
impl TimeSource for Builtin {
// ...
}
个人观点,如果我仍在制作我的代码原型(prototype)并且不清楚哪个选择更好,我可能会默认使用特征。无限多态更符合我对依赖注入(inject)和测试风格的偏好。
关于enums - 库编写者选择的替代子类型的首选方法是什么,为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50710339/
我不明白为什么这甚至可以编译。我尝试过不同的格式,它们似乎都有效。 为什么有一个 enum of enum of enum of.. 是合法的? interface I { enum E im
我有大型数据库(数百万行),我正在尝试为 2 个字段的数据类型做出最佳选择。我制作的大部分内容都是 varchar 或 INT。但是,我想知道 Enum 是否是最好的方法的 2 个字段。 字段 1第一
我是 C++ 新手,我想知道是否有人可以帮助我理解原因 enum difficulty { NOVICE, EASY, NORMAL, HARD, UNBEATABLE }; difficulty m
从 native 代码强制转换(在 C++/CLI 中)的正确方法是什么 enum到托管代码enum其中包含相同的 enum值(value)观?与使用 C# 的强制转换方式有什么区别,例如 (int)
我有以下枚举 [Flags] public enum WeekDays { Monday = 1, Tuesday = 2, Wednesday = 4, Thursd
我刚刚学习 Java 中的枚举。当我运行下面的代码时,我收到一个错误,我也在下面重现该错误。基本上,我的问题是:当我在枚举中定义一个方法,并且在该方法中我想检查枚举的值以便我可以根据该值执行某些操作时
我想要一些语法糖来打开 Enum .当然,一个if else块按预期工作: @enum Fruit apple=1 orange=2 kiwi=3 function talk1(fruit::Frui
我试图在 Enum.each 的函数内为变量设置一个值,但在循环结束时,变量为空,我不知道为什么会出现这种行为。 代码: base = "master" candidates = ["stream",
This question already has answers here: Is there a way to use existing structs as enum variants? (2个
我想让 Java 中的枚举器具有其他枚举作为属性。 public enum Direction { Up(Down), Down(Up), Left(Right), R
我有一个包含两种不同可能“类型”的枚举和一个可以返回其中任何一种的函数,封装在 Option 中: enum Possibilities { First(i32), Second(St
我刚刚注意到 pyhton 中 Enum+defaultdict 的一个非常奇怪的行为。我定义了一个这样的枚举,它收集了一些默认词典: from enum import Enum from colle
我想在运行时从配置文件生成一些类型。为简单起见,假设我已经将数据加载为 Python 字典: color_values = dict(RED = 1, YELLOW = 2, GREEN = 3) 我
我想创建一个方法,在传入参数的任何枚举类上实现 valueOf(并包装一些专门的错误/缺失名称代码)。所以基本上,我有几个枚举,例如: enum Enum1{ A, B, C } enum Enum2
我有一个user数据库表: CREATE TABLE IF NOT EXISTS `user` ( `user_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
这是我的 JPA @Repository,在这里我们可以得到 list与 findByFullNameContaining(String query) - 通过在查询中提供 fullName 的子字符
(也在这里打开了一个问题:https://github.com/square/moshi/issues/768 但被要求打开一个stackoverflow问题)我正在编写一个通用适配器来转换带有枚举值
请帮助找到以下情况的最佳方法: 有一个表,大约有 20 列。 每列都有自己的短名称、全名称和类型(数字或字符串)。 每个列类型都可以有自己的运算符 - 例如,字符串 - 包含、等于;数字 - 更多、更
如果我在 python 中按功能创建了 enum.Enum(本例中为 3.7),如何从中检索类的名称? import enum def print_the_enum_class_name(some_e
我正在编写一个与第 3 方程序交互的程序。这个第 3 方程序允许用户制作可以运行在第 3 方程序中进行的步骤记录的按钮。 但! 这些按钮还可以运行用户定义的批处理文件。因此,我使用此功能通过创建文件并
我是一名优秀的程序员,十分优秀!