ฉันไม่คิดว่าฉันเข้าใจในสิ่งที่เป็นenum
อยู่และควรใช้เมื่อใด
ตัวอย่างเช่น:
typedef enum {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;
มีการประกาศอะไรที่นี่จริง ๆ ?
ฉันไม่คิดว่าฉันเข้าใจในสิ่งที่เป็นenum
อยู่และควรใช้เมื่อใด
ตัวอย่างเช่น:
typedef enum {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;
มีการประกาศอะไรที่นี่จริง ๆ ?
คำตอบ:
สามสิ่งที่จะได้รับการประกาศที่นี่: ไม่ระบุชื่อระบุชนิดมีการประกาศShapeType
จะถูกประกาศ typedef ที่แจงนับไม่ระบุชื่อและชื่อที่สามkCircle
, kRectangle
และkOblateSpheroid
จะได้รับการประกาศให้เป็นค่าคงที่หนึ่ง
มาทำลายมันกันเถอะ ในกรณีที่ง่ายที่สุดการแจงนับสามารถประกาศเป็น
enum tagname { ... };
tagname
ประกาศนี้นับมีแท็ก ใน C และ Objective-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
กับenum
คำหลักเราสามารถทำให้enum
ไม่ระบุชื่อและประกาศด้วยชื่อ typedef เท่านั้น:
typedef enum { ... } tagname;
ตอนนี้ในกรณีนี้เรากำลังประกาศShapeType
ให้เป็นชื่อที่พิมพ์โดยไม่มีการระบุชื่อ ShapeType
เป็นจริงเพียงชนิดหนึ่งและควรจะใช้เฉพาะกับตัวแปรประกาศซึ่งถือเป็นหนึ่งในค่าที่ระบุไว้ในประกาศ (นั่นคือหนึ่งkCircle
, kRectangle
และkOblateSpheroid
) คุณสามารถกำหนดShapeType
ตัวแปรอีกค่าได้โดยการร่ายดังนั้นคุณต้องระวังเมื่ออ่านค่า enum
สุดท้ายkCircle
, kRectangle
และkOblateSpheroid
ได้รับการประกาศให้เป็นค่าคงที่สำคัญใน namespace โลก เนื่องจากไม่มีการระบุค่าเฉพาะพวกเขาจะได้รับมอบหมายให้เป็นจำนวนเต็มต่อเนื่องโดยเริ่มต้นด้วย 0 ดังนั้นkCircle
0 kRectangle
คือ 1 และkOblateSpheroid
2
Apple แนะนำให้นิยาม enums เช่นนี้ตั้งแต่Xcode 4.4 :
typedef enum ShapeType : NSUInteger {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;
พวกเขายังให้มาโครที่ใช้งานง่ายNS_ENUM
:
typedef NS_ENUM(NSUInteger, ShapeType) {
kCircle,
kRectangle,
kOblateSpheroid
};
คำจำกัดความเหล่านี้ให้การตรวจสอบประเภทที่เข้มงวดยิ่งขึ้นและการกรอกโค้ดที่ดีขึ้น ฉันไม่สามารถหาเอกสารอย่างเป็นทางการของNS_ENUM
แต่คุณสามารถชม "โมเดิร์น Objective-C" วิดีโอจากงาน WWDC 2012 เซสชั่นที่นี่
NS_ENUM
มาโครของ Apple โดย NSHipster: NSHipster.com/ns_enum-ns_options
Enum ประกาศชุดของค่าที่สั่ง - typedef เพิ่งเพิ่มชื่อที่มีประโยชน์ให้กับสิ่งนี้ องค์ประกอบที่ 1 คือ 0 เป็นต้น
typedef enum {
Monday=1,
...
} WORKDAYS;
WORKDAYS today = Monday;
ด้านบนเป็นเพียงการนับแท็ก shapeType
ผู้ใช้กำหนดชนิดที่มีค่าที่เป็นไปได้ของkCircle
, หรือkRectangle
kOblateSpheroid
แม้ว่าค่าภายใน enum (kCircle ฯลฯ ) จะมองเห็นได้นอก enum สิ่งสำคัญคือต้องคำนึงถึงสิ่งนั้น ( int i = kCircle;
เช่นถูกต้อง)
อัพเดตสำหรับการเปลี่ยนแปลง 64 บิต: ตามเอกสารของ Appleเกี่ยวกับการเปลี่ยนแปลง 64 บิต
การแจกแจงจะถูกพิมพ์ด้วยเช่นกัน: ในคอมไพเลอร์ LLVM ประเภทการแจกแจงสามารถกำหนดขนาดของการแจงนับได้ ซึ่งหมายความว่าบางประเภทระบุอาจมีขนาดที่ใหญ่กว่าที่คุณคาดไว้ วิธีการแก้ปัญหาดังเช่นในกรณีอื่น ๆ ทั้งหมดคือการไม่มีข้อสมมติฐานเกี่ยวกับขนาดของชนิดข้อมูล ให้กำหนดค่าที่แจกแจงให้กับตัวแปรด้วยชนิดข้อมูลที่เหมาะสมแทน
ดังนั้นคุณต้องสร้าง enum พร้อมกับประเภทดังนี้ไวยากรณ์ถ้าคุณรองรับ 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
อัพเดตสำหรับการตั้งโปรแกรมแบบ swift:
รวดเร็วมีการเปลี่ยนแปลงทางไวยากรณ์
enum ControlButtonID: NSUInteger {
case kCircle , kRectangle, kOblateSpheroid
}
enum (ตัวย่อของการแจงนับ) ใช้เพื่อแจกแจงชุดของค่า (enumerators) ค่าคือสิ่งที่เป็นนามธรรมแสดงด้วยสัญลักษณ์ (คำ) ตัวอย่างเช่น enum พื้นฐานอาจเป็น
enum { xs,s,m,l,xl,xxl,xxxl,xxxxl };
enum นี้เรียกว่าไม่ระบุชื่อเนื่องจากคุณไม่มีสัญลักษณ์ชื่อ แต่มันก็ยังถูกต้องสมบูรณ์ แค่ใช้มันแบบนี้
enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandMotherDressSize;
ตกลง. ชีวิตมีความสวยงามและทุกอย่างเป็นไปด้วยดี แต่วันหนึ่งคุณต้องใช้ enum นี้ซ้ำเพื่อกำหนดตัวแปรใหม่เพื่อเก็บ myGrandFatherPantSize จากนั้นคุณเขียน:
enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandMotherDressSize;
enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandFatherPantSize;
แต่คุณมีข้อผิดพลาดคอมไพเลอร์ "นิยามใหม่ของตัวแจงนับ" ที่จริงแล้วปัญหาคือคอมไพเลอร์ไม่แน่ใจว่าคุณ enum แรกและคุณเป็นคนที่สองอธิบายสิ่งเดียวกัน
ถ้าคุณต้องการใช้ชุดตัวแจงนับซ้ำ (ที่นี่ xs ... xxxxl) ในหลาย ๆ ที่คุณต้องติดแท็กด้วยชื่อที่ไม่ซ้ำกัน ครั้งที่สองที่คุณใช้ชุดนี้คุณเพียงแค่ต้องใช้แท็ก แต่อย่าลืมว่าแท็กนี้ไม่ได้แทนที่คำ enum แต่เป็นเพียงชุดของตัวแจงนับ จากนั้นดูแลให้ใช้ 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;
คุณสามารถพูดได้ว่าการเขียนซ้ำ enum ไม่สะดวกและทำให้โค้ดดูแปลกไป คุณพูดถูก ประเภทที่แท้จริงจะดีกว่า
นี่เป็นขั้นตอนสุดท้ายของการก้าวไปสู่การประชุมสุดยอดครั้งใหญ่ของเรา เพียงแค่เพิ่ม typedef ลองเปลี่ยน enum ของเราแบบจริง โอ้สิ่งสุดท้ายไม่อนุญาตให้พิมพ์ typef ในชั้นเรียนของคุณ จากนั้นกำหนดประเภทของคุณด้านบน ทำเช่นนี้:
// 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 ที่จะช่วยให้คุณกำหนด enums ที่ดีได้ง่ายและยิ่งกว่านั้นจะช่วยให้ตัววิเคราะห์แบบคงที่ทำการตรวจสอบที่น่าสนใจสำหรับคุณก่อนที่จะรวบรวม
ดี Enum!
typedef
มีประโยชน์สำหรับการกำหนดชื่อตัวแปรชนิดที่มีอยู่ใหม่ มันมีวิธีสั้น ๆ และมีความหมายในการเรียกประเภทข้อมูล เช่น:
typedef unsigned long int TWOWORDS;
นี่ int ชนิดยาวที่ไม่ได้ลงนามจะถูกกำหนดให้เป็นประเภท TWOWORDS ดังนั้นตอนนี้เราสามารถประกาศตัวแปรประเภท int ไม่ได้ลงนามยาวโดยการเขียน
TWOWORDS var1, var2;
แทน
unsigned long int var1, var2;
typedef enum {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;
จากนั้นคุณสามารถใช้มันเช่น: -
ShapeType shape;
และ
enum {
kCircle,
kRectangle,
kOblateSpheroid
}
ShapeType;
ตอนนี้คุณสามารถใช้มันเหมือน: -
enum ShapeType shape;
enum ใช้เพื่อกำหนดค่าให้กับองค์ประกอบ enum ซึ่งไม่สามารถทำได้ใน struct ดังนั้นทุกครั้งแทนที่จะเข้าถึงตัวแปรทั้งหมดเราสามารถทำได้โดยค่าที่เรากำหนดให้กับตัวแปรใน enum โดยค่าเริ่มต้นมันเริ่มต้นด้วยการกำหนดค่า 0 แต่เราสามารถกำหนดค่าใดก็ได้และตัวแปรถัดไปใน enum จะถูกกำหนดค่าให้กับค่าก่อนหน้า +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 สิ่งนี้ช่วยปรับปรุงความสามารถในการอ่านโค้ดอย่างมาก
Typedef เป็นคำสำคัญใน C และ C ++ มันถูกใช้เพื่อสร้างชื่อใหม่สำหรับชนิดข้อมูลพื้นฐาน(ถ่าน, int ลอยคู่ struct & enum)
typedef enum {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;
ที่นี่สร้างประเภทข้อมูลที่แจกแจงShapeType & เราสามารถเขียนชื่อใหม่สำหรับประเภท Enum ShapeTypeตามที่ระบุด้านล่าง
ShapeType shape1;
ShapeType shape2;
ShapeType shape3;
enum สามารถลด "ข้อผิดพลาด" ได้หลายประเภทและทำให้รหัสสามารถจัดการได้ง่ายขึ้น
#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;