【发布时间】:2010-12-12 08:57:55
【问题描述】:
是否可以在 Objective-C 中遍历枚举值?
【问题讨论】:
-
重新标记:这是(AFAIK)一个纯 C 问题。使用更通用的标记,您将获得更多响应。
-
它还回答了人们在 Obj-C 中搜索它的问题。添加了那个标签。
标签: c objective-c enums
是否可以在 Objective-C 中遍历枚举值?
【问题讨论】:
标签: c objective-c enums
如果上述方法不适合您,因为您使用的是 C++,the following should:
enum Foo { One, Two, Three, Last }; for ( int fooInt = One; fooInt != Last; fooInt++ ) { Foo foo = static_cast<Foo>(fooInt); // ... }
【讨论】:
我讨厌用“最后一个”条目弄脏我的枚举(以及附带的注意事项,即不应该使用它,并且必须始终保留它,嗯,最后),并且只找到了一种解决方法(除了使用最后一个枚举条目作为秘密“最后一个”,这再次让我感到恶心)。
如果您使用X Macros 定义您的枚举,您可以非常简单地计算您的枚举中的项目数。请参阅链接 FMI,了解何时可以使用此方法 - 为简明扼要,如下所示:
#define COLOR_TABLE \
X(red, "red") \
X(green, "green") \
X(blue, "blue")
#define X(a, b) a,
enum COLOR {
COLOR_TABLE
};
#undef X
#define X(a, b) b,
char *color_name[] = {
COLOR_TABLE
};
#undef X
#define X(a, b) +1
int color_count = 0 COLOR_TABLE;
#undef X
【讨论】:
给定
enum Foo {Bar=0,Baz,...,Last};
你可以像这样迭代元素:
for(int i=Bar; i<=Last; i++) {
...
}
请注意,这暴露了 C 枚举的真正只是一个整数的性质。特别是,您可以看到 C 枚举并没有真正提供类型安全,因为您可以使用 int 代替枚举值,反之亦然。此外,这取决于枚举值的声明顺序:至少可以说是脆弱的。另外,请看Chuck的评论;如果枚举项是不连续的(例如,因为您为某些项指定了显式的、非顺序的值),这根本不起作用。哎呀。
【讨论】:
vice versa。
for (int i=1; i<=Last; i=i*2)
可以通过获取枚举中的名称数组并利用数组的长度来确定任何枚举的长度(项目数)。使用 Enum 的 GetNames 方法。 Enum.GetNames(enumType).Length.
{
enum Pig { Snort, Sty, Oink, Curly };
const int Pig_Count = Enum.GetNames(typeof(Pig)).Length;
}
【讨论】:
对于非连续枚举,您可以通过以下方式迭代有效值:
enum {
value_one = 0,
value_two = 1,
value_three = 3,
value_max
}
for ( i = value_one; i < value_max; i++ )
{
switch(i)
{
case value_one:
case value_two:
case value_three:
case value_four:
{
/* ... Do something with valid enum value ... */
}
break;
default:
/* Found an invalid enum entry; ignore it */
break;
}
}
【讨论】:
为了寻找这个,我只是炮制了以下满足我自己要求的解决方案。我想我会把它贴在这里,供搜索类似内容的人使用。
假设我有一个枚举。
typedef NS_ENUM (NSInteger, ISDirection) {
ISDirectionUp,
ISDirectionDown,
ISDirectionLeft,
ISDirectionRight
};
为了能够循环它,我定义了以下预处理器宏。
#define ISDirectionAllAsDir ISDirection dir = ISDirectionUp; dir <= ISDirectionRight; dir++
然后我在循环中使用它,如下所示:
for(ISDirectionAllAsDir) {
NSLog(@"Direction %d", dir);
}
这将迭代的逻辑放在一个地方(宏),从而提高了代码的可维护性。
【讨论】:
我喜欢我从这里得到的东西 Iteration over enum in Objective C?
typedef enum { ENUM1=0, ENUM2, ENUM3, ENUM4 , TOTAL } ;
for ( int i=ENUM1 ; i<TOTAL; i++)
{}
这样你以后可以继续添加枚举而不影响你的循环吗?
【讨论】:
这有点杂乱无章(整个概念也是如此......嗯......)但如果您要多次执行此操作,并且您希望能够处理非连续枚举,您可以创建一个(全局常量)数组,并具有(使用 ennukiller 的示例)方向方向[4] = {东、西、北、南}; 然后在你的循环中你可以谈论方向[i]而不是直接迭代方向本身......
正如我所说,它很丑,但我认为它不那么脆弱......
【讨论】:
#define ENUM(type, ...) enum _##type { __VA_ARGS__ }; enum _##type type##s[] = { __VA_ARGS__ },尽管这只适用于连续的。我不使用不连续的枚举,因为这对我来说意味着糟糕的设计。此外,我的 C 代码中到处都有使用此宏的 typedef struct _list List;、typedef enum _direction Direction,这就是为什么我在类型前面加上 _ 的原因。 ENUM(direction, NORTH, EAST, SOUTH, WEST); 给了enum _direction { NORTH, EAST, SOUTH, WEST }; enum _direction directions = { NORTH, EAST, SOUTH, WEST }; 我喜欢。
如果你的枚举定义如下:
enum Direction { East, West, North, South};
你可以这样循环:
for ( int direction = East; direction <= South; ++direction)
{
/* Do something with Direction
}
【讨论】: