我不认为我从根本上理解枚举是什么,以及什么时候使用它。

例如:

typedef enum {
    kCircle,
    kRectangle,
    kOblateSpheroid
} ShapeType;

这里真正声明的是什么?


当前回答

枚举可以减少许多类型的“错误”,并使代码更易于管理

#define STATE_GOOD 0
#define STATE_BAD 1
#define STATE_OTHER 2
int STATE = STATE_OTHER

这个定义没有约束。这只是一个简单的代换。 它不能限制国家的所有条件。当STATE被赋值为5时,程序将出错,因为没有匹配的状态。但是编译器不会警告STATE = 5

所以这样用比较好

typedef enum SampleState {
    SampleStateGood  = 0,
    SampleStateBad,
    SampleStateOther
} SampleState;

SampleState state = SampleStateGood;

其他回答

从Xcode 4.4开始,苹果就建议这样定义枚举:

typedef enum ShapeType : NSUInteger {
    kCircle,
    kRectangle,
    kOblateSpheroid
} ShapeType;

它们还提供了一个方便的宏NS_ENUM:

typedef NS_ENUM(NSUInteger, ShapeType) {
    kCircle,
    kRectangle,
    kOblateSpheroid
};

这些定义提供了更强的类型检查和更好的代码补全。我找不到NS_ENUM的官方文档,但你可以在这里观看WWDC 2012会议的“Modern Objective-C”视频。


更新 官方文件的链接在这里。

枚举声明了一组有序值——typedef只是给它加了一个方便的名字。第一个元素是0等等。

typedef enum {
Monday=1,
...
} WORKDAYS;

WORKDAYS today = Monday;

上面只是shapeType标记的枚举。

Typedef对于重新定义现有变量类型的名称非常有用。它提供了调用数据类型的简短而有意义的方式。 例句:

typedef unsigned long int TWOWORDS;

这里,unsigned long int类型被重新定义为TWOWORDS类型。因此,我们现在可以声明unsigned long int类型的变量:

TWOWORDS var1, var2;

而不是

unsigned long int var1, var2;

您可以使用下面的格式,原始默认值从0开始,所以

kCircle是0, kRectangle是1, kOblateSpheroid是2。

您可以指定自己的特定起始值。

typedef enum : NSUInteger {
    kCircle, // for your value; kCircle = 5, ...
    kRectangle,
    kOblateSpheroid
} ShapeType;

ShapeType circleShape = kCircle;
NSLog(@"%lu", (unsigned long) circleShape); // prints: 0

enum (enumeration的缩写)用于枚举一组值(枚举器)。值是由符号(词)表示的抽象事物。 例如,基本枚举可以是

enum { xs,s,m,l,xl,xxl,xxxl,xxxxl };

此枚举被称为匿名,因为您没有符号来命名它。但它仍然是完全正确的。就像这样用

enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandMotherDressSize;

好的。生活是美丽的,一切都很顺利。但是有一天你需要重用这个枚举来定义一个新变量来存储myGrandFatherPantSize,然后你写:

enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandMotherDressSize;
enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandFatherPantSize;

但是你有一个编译器错误“重定义枚举器”。实际上,问题是编译器不确定你的第一个枚举和你的第二个枚举描述的是同一件事。

然后,如果您想在多个地方重用同一组枚举数(这里是xs…xxxxl),则必须使用唯一的名称标记它。第二次使用这个集合时,只需使用标签即可。但是不要忘记,这个标记并不替换枚举词,而只是一组枚举数。然后注意像往常一样使用enum。是这样的:

// Here the first use of my enum
enum sizes { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandMotherDressSize; 
// here the second use of my enum. It works now!
enum sizes myGrandFatherPantSize;

你也可以在参数定义中使用它:

// Observe that here, I still use the enum
- (void) buyANewDressToMyGrandMother:(enum sizes)theSize;

可以说,在所有地方重写枚举并不方便,而且会使代码看起来有点奇怪。你说得对。真正的类型会更好。

这是我们向顶峰伟大前进的最后一步。通过添加typedef,我们可以将枚举转换为实类型。最后一点,typedef在类中是不允许的。然后在上面定义你的类型。这样做:

// enum definition
enum sizes { xs,s,m,l,xl,xxl,xxxl,xxxxl };
typedef enum sizes size_type

@interface myClass {
   ...
   size_type myGrandMotherDressSize, myGrandFatherPantSize;
   ...
}

记住,标记是可选的。在这种情况下,我们不标记枚举数,而只是定义一个新类型。那我们就不再需要它了。

// enum definition
typedef enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } size_type;

@interface myClass : NSObject {
  ...
  size_type myGrandMotherDressSize, myGrandFatherPantSize;
  ...
}
@end

如果你在Objective-C中使用XCode开发,我会让你发现一些以NS_ENUM为前缀的宏。这将帮助您轻松地定义好的枚举,而且还将帮助静态分析器在编译之前为您做一些有趣的检查。

Enum好!