使用枚举比直接使用整数类型有什么好处?
1) 我知道以下好处:
它们提高了抽象级别,因为您可以立即看到基础积分值代表什么。
您可以使用它们代替幻数,从而使代码更易于理解
它们还限制值
enum
变量可以具有,这样做可以使应用程序更安全,因为程序员知道哪些值对变量有效,所以我猜它们有点提供类型安全
与直接使用相比,它们还有其他好处吗积分值?
2)为什么他们使用积分作为基础类型而不是字符串?
谢谢
1) I’m aware of the following benefits:
they increase the level of abstraction since you immediately see what underlying integral values represent.
You can use them instead of magic numbers and by doing that making the code more understandable
They also restrict the values an
enum
variable can have and in doing so make the application safer, since programmers know which values are valid for variable, so I guess they sort of provide a type safety
Are there any other benefits they provide over directly using integral values?
2) Why do they use integrals as an underlying type and not string?
thank you
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您已经列出了枚举优于整数类型的许多核心原因。
命名常量比幻数更安全、更易读
枚举向程序员描述了它们的用途。整数值则不然。
自然地限制可以传入的值的集合。(您已经看到了类型安全冰山一角......但看得更深入......)
您还可以添加:
大大提高了类型安全性。如果你接受一个“int”,那么任何int都可以传入。如果你接受一个VehicleType,那么只能传入一个VehicleType。我并不是说有人在最大允许数字为5时传入6。我的意思是,如果您将 FuelType.Unleaded 传递给一个认为它意味着 VehicleType.Aeroplane 的函数会怎样?使用枚举,编译器会告诉你你是个白痴。整数类型表示“是的,5 对我来说没问题”,并且您的程序表现出非常奇怪的行为,可能很难追踪。
更容易重构。就像任何魔法常量一样,如果您在程序中的一百个地方传递值 5,那么如果您决定将 5 更改为具有不同的含义,那么您就会遇到麻烦。使用枚举(只要您没有二进制向后兼容性问题),您可以更改基础值。如果您愿意,您还可以更改枚举的基础类型(byte -> int -> long),而无需重新编译客户端代码。
当位和掩码可以命名时,位域的使用就容易多了。如果添加新位,您通常可以进行安排,以便仅更新相关掩码就可以让大多数现有代码完美地处理新位字段,而无需从头开始重写它们。
整个计划的一致性。如果您小心混淆和类型安全,枚举可以让您用代码中的相同名称来表示用户选择的命名值列表,但不会产生使用字符串的效率成本。< /p>
每个人都明白为什么常量在代码中非常有用。枚举只是为您提供了一种将一组相关常量组合在一起的方法。您可以使用常量命名空间以更混乱的方式实现同样的事情。
使用枚举而不是布尔值作为参数不仅使代码具有自记录性、可读性,而且不易出错。当您意识到两个选项还不够时,它还可以更轻松地添加第三个选项。
与所有工具一样,枚举可能会被滥用。只要在有意义的地方使用它们即可。
2)为什么使用字节或整数而不是字符串?简单来说,它们体积小,效率高。
You've listed a lot of the core reasons where enums are preferable to integral types.
Named constants are safer and more readable than magic numbers
Enums describe to programmers what they are for. Integral values don't.
Naturally limiting the set of values that can be passed in. (You've got the tip of the type-safety iceberg... but look deeper...)
You can also add:
Vastly increased Type Safety. If you accept an 'int', then any int can be passed in. If you accept a VehicleType, then only a VehicleType can be passed in. I'm not just talking about someone passing in 6 when the largest allowed number is 5. I mean what if you pass in FuelType.Unleaded to a function that thinks it means VehicleType.Aeroplane? With enums the compiler will tell you you're an idiot. An integral type says "yeah, 5 is fine with me" and your program exhibits really odd behaviour that may be extremely difficult to trace.
Easier refactoring. Just as with any magic constants, If you pass in the value 5 in a hundred places in your program, you're in trouble if you decide to change 5 to have a different meaning. With an enum (as long as you don't have binary backwards compatibility concerns) you can change the underlying values. You can also change the underlying type of an enum if you wish (byte -> int -> long) without having to do anything more than recompile the client code.
Bitfields are so much easier to work with when the bits and masks can be named. And if you add new bits, you can often arrange things so that merely updating the related masks will allow most of your existing code to handle the new bitfields perfectly without having to rewrite them from scratch.
Consistency throughout the program. If you are careful with obfuscation and type safety, enums allow you to represent a list of named values that a user chooses from with the same names in the code, but without the efficiency cost of using strings.
Everybody understands why constants are great in code. Enums simply give you a way of holding together a related group of constants. You could achieve the same thing in a messier manner using a namespace of consts.
Using an enum for a parameter rather than a bool not only makes the code self-documenting, readable, and less prone to mistakes. It also makes it much easier to add a third option when you realize that two options isn't enough.
As with all tools, enums can be misused. Just use them where they make sense.
2) Why use bytes or ints instead of strings? Simply they're small and efficient.
我猜想它们需要底层整数类型来确保比较的简单性并更容易支持位标志。如果没有这个限制,我们、编译器或运行时,可能不得不诉诸一些模糊性来完成诸如组合之类的事情 - 或者我们会陷入这样的情况 - 正如你所说 - 我们不应该 关心底层类型(抽象点),但是当我们尝试说
A | B
我们收到运行时错误,因为我们使用了无法执行该类型操作的基础类型。I would conjecture that they require underlying integral types to ensure simplicity of comparison and more easily support bit flags. Without that limitation, we, or the compiler, or the runtime, would likely have to resort to some fuzziness to do things like combinations - or we would get into a situation where - as you say - we shouldn't care about the underlying type (the point of the abstraction) and yet when we try to say
A | B
we get a runtime error because we used an underlying type that isn't capable of that type of operation.一个好处是当您想使用枚举作为标志时。
因此,如果您像这样定义一个枚举:
那么如果您有一个接受 TestEnum 实例作为变量的方法,您可以组合枚举中的值,这样您就可以发送例如
A |乙| C
作为方法的参数。然后,在方法内部,您可以像这样检查参数:另外,我认为您提到的原因本身就足以使用枚举。
另外,关于您可以使用类似
(TestEnum)500;
的代码强制将错误值放入枚举的注释,如果您不想破坏代码,则很难做到这一点。枚举的值 0 应该是默认值,或者在标志的情况下“不存在所有其他标志”这一点非常重要,因为
TestEnum myenum
行会将 myenum 实例化为 0无论您是否为 0 定义了任何枚举值。One benefit is when you want to use enum as a flag.
So if you define an enum like this:
Then if you have a method that accept an instance of TestEnum as a variable, you can combine the values from the enum, so you can send for example
A | B | C
as the parameter for the method. Then, inside the method, you can check the parameter like this:Also, I think the reasons you mention are good enough by themselves to use enums.
Also regarding the comment that you can force an wrong value into an enum with code like this
(TestEnum)500;
it's hard to do if you do not want to break your code.The point that the value 0 for an enum should be the default value, or in the case of flags "the absence of all other flags" is very important, since the line
TestEnum myenum
will instanciate myenum as 0 regardless if you have defined any enum value for 0 or not.您还可以从字符串表示中解析枚举。您可以从数据源或用户条目获取该字符串。
我认为你以“神奇数字”的价格向我推销了枚举。
You can also parse an Enum from the string representation. You may get that string from a data source or user-entry.
I think you sold me on Enums at "magic numbers".
枚举的主要好处是可以以一致、富有表现力和类型安全的方式引用常量。
可读性当然是使用枚举的最大优点。
另一个优点是枚举常量是由编译器自动生成的。
例如,如果您的程序中可能出现错误代码,则有一个枚举常量类型,则您的枚举定义可能如下所示:
枚举错误代码
{
内存不足,
文件未找到
};
编译器自动为 OUT_OF_MEMORY 分配值 0(零)
因为它首先出现在定义中。FILE_NOT_FOUND 等于 1,依此类推。
如果您要使用符号常量或幻数来处理相同的示例,则需要编写更多代码来执行相同的操作。
The main benefit of enum is that constants can be referred to in a consistent, expressive and type safe way.
Readability is of-course the topmost advantage of using the enumeration.
Another advantage is that enumerated constants are generated automatically by the compiler.
For instance, if you had an enumerated constant type for error codes that could occur in your program, your enum definition could look something like this:
enum Error_Code
{
OUT_OF_MEMORY,
FILE_NOT_FOUND
};
OUT_OF_MEMORY is automatically assigned the value of 0 (zero) by the compiler
because it appears first in the definition.FILE_NOT_FOUND equal to 1, so on.
If you were to approach the same example by using symbolic constants or Magic numbers, you write much more code to do the same.