나는 그것이 무엇인지 enum
, 언제 사용 해야하는지 근본적으로 이해하지 못한다고 생각 합니다.
예를 들면 다음과 같습니다.
typedef enum {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;
여기서 실제로 무엇을 선언합니까?
나는 그것이 무엇인지 enum
, 언제 사용 해야하는지 근본적으로 이해하지 못한다고 생각 합니다.
예를 들면 다음과 같습니다.
typedef enum {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;
여기서 실제로 무엇을 선언합니까?
답변:
익명 열거 형식이 선언 : 세 가지가 여기에 선언되고있는 ShapeType
익명 열거에 대한 형식 정의를 선언되고 있으며, 세 개의 이름은 kCircle
, kRectangle
및 kOblateSpheroid
통합 상수로 선언되고있다.
그것을 분해하자. 가장 간단한 경우 열거 형을 다음과 같이 선언 할 수 있습니다.
enum tagname { ... };
이것은 태그를 사용하여 열거를 선언합니다 tagname
. C와 오브젝티브 C (그러나에서 하지 C ++),이에 대한 참조가 있어야합니다 앞에는 enum
키워드. 예를 들면 다음과 같습니다.
enum tagname x; // declare x of type 'enum tagname'
tagname x; // ERROR in C/Objective-C, OK in C++
enum
어디에서나 키워드 를 사용하지 않으려면 typedef를 작성할 수 있습니다.
enum tagname { ... };
typedef enum tagname tagname; // declare 'tagname' as a typedef for 'enum tagname'
한 줄로 단순화 할 수 있습니다.
typedef enum tagname { ... } tagname; // declare both 'enum tagname' and 'tagname'
마지막으로 키워드 enum tagname
와 함께 사용할 필요가 없으면 익명을 만들고 typedef 이름으로 만 선언 할 수 있습니다.enum
enum
typedef enum { ... } tagname;
이제이 경우 ShapeType
익명 열거 형의 typedef 이름으로 선언 됩니다. ShapeType
정말 일체형이며, 단 (이며, 하나의 선언에 열거 된 값 중 하나를 보유 변수 선언 표기 kCircle
, kRectangle
등을 kOblateSpheroid
). ShapeType
그러나 캐스팅을 통해 변수에 다른 값을 할당 할 수 있으므로 열거 형 값을 읽을 때주의해야합니다.
마지막으로 kCircle
, kRectangle
및 kOblateSpheroid
글로벌 네임 스페이스에 필수적인 상수로 선언된다. 특정 값이 지정되지 않았으므로 0으로 시작하는 연속 정수에 할당되므로 kCircle
0, kRectangle
1, kOblateSpheroid
2입니다.
Apple은 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"비디오를 여기에서 볼 수 있습니다 .
업데이트 여기
공식 문서 링크 .
NS_ENUM
NSHipster 의 Apple 매크로 설명 : NSHipster.com/ns_enum-ns_options
64 비트 변경에 대한 업데이트 : 64 비트 변경 에 대한 Apple 문서 에 따르면 ,
열거 형도 타입 : LLVM 컴파일러에서 열거 형은 열거의 크기를 정의 할 수 있습니다. 즉, 열거 된 일부 유형의 크기가 예상보다 클 수도 있습니다. 다른 모든 경우와 마찬가지로 해결책은 데이터 유형의 크기에 대한 가정을하지 않는 것입니다. 대신 열거 된 값을 적절한 데이터 유형의 변수에 지정하십시오.
따라서 64 비트를 지원하는 경우 아래 구문 과 같은 유형 으로 열거 형 을 만들어야 합니다.
typedef NS_ENUM(NSUInteger, ShapeType) {
kCircle,
kRectangle,
kOblateSpheroid
};
또는
typedef enum ShapeType : NSUInteger {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;
그렇지 않으면 다음과 같이 경고로 이어집니다. Implicit conversion loses integer precision: NSUInteger (aka 'unsigned long') to ShapeType
신속한 프로그래밍을위한 업데이트 :
신속하게 구문이 변경되었습니다.
enum ControlButtonID: NSUInteger {
case kCircle , kRectangle, kOblateSpheroid
}
열거 형 (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)을 재사용하려면 고유 한 이름으로 태그를 지정해야합니다. 이 세트를 두 번째로 사용할 때는 태그 만 사용하면됩니다. 그러나이 태그는 열거 형 단어를 대체하는 것이 아니라 열거 자 세트 만 대체한다는 것을 잊지 마십시오. 그런 다음 평소처럼 열거 형을 사용하도록주의하십시오. 이처럼 :
// 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
XCode를 사용하여 Objective-C에서 개발하는 경우 NS_ENUM 접두사가있는 멋진 매크로를 발견 할 수 있습니다. 그렇게하면 좋은 열거 형을 쉽게 정의 할 수 있으며 정적 분석기가 컴파일하기 전에 흥미로운 검사를 수행하는 데 도움이됩니다.
좋은 열거 형!
enum은 구조체에서 수행 할 수없는 enum 요소에 값을 할당하는 데 사용됩니다. 따라서 완전한 변수에 액세스하는 대신 열거 형의 변수에 할당 한 값으로 수행 할 수 있습니다. 기본적으로 0 할당으로 시작하지만 값을 할당 할 수 있으며 열거 형의 다음 변수에는 이전 값 +1의 값이 할당됩니다.
아래 형식으로 사용할 수 있습니다. 기본 값은 0부터 시작하므로
고유 한 시작 값을 지정할 수 있습니다.
typedef enum : NSUInteger {
kCircle, // for your value; kCircle = 5, ...
kRectangle,
kOblateSpheroid
} ShapeType;
ShapeType circleShape = kCircle;
NSLog(@"%lu", (unsigned long) circleShape); // prints: 0
프로그래머는 typedef를 사용하여 하나의 Objective-C 유형을 다른 것으로 정의 할 수 있습니다. 예를 들어
typedef int 카운터; int 유형과 동등한 Counter 유형을 정의합니다. 이것은 코드 가독성을 크게 향상시킵니다.
Typedef는 C 및 C ++의 키워드입니다. 기본 데이터 유형 (char, int, float, double, struct & enum)의 새 이름을 작성하는 데 사용됩니다 .
typedef enum {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;
여기에 열거 된 데이터 유형 ShapeType 을 작성 하고 아래에 주어진 것처럼 열거 유형 ShapeType의 새 이름을 작성할 수 있습니다.
ShapeType shape1;
ShapeType shape2;
ShapeType shape3;
열거 형은 많은 유형의 "오류"를 줄이고 코드를보다 관리하기 쉽게 만듭니다.
#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;