Pertanyaan Apa yang dimaksud dengan typedef enum di Objective-C?


Saya tidak berpikir saya pada dasarnya memahami apa itu enum adalah, dan kapan menggunakannya.

Sebagai contoh:

typedef enum {
    kCircle,
    kRectangle,
    kOblateSpheroid
} ShapeType;

Apa yang sebenarnya dinyatakan di sini?


1042
2018-04-01 21:59


asal


Jawaban:


Ada tiga hal yang dinyatakan di sini: tipe anumerasi anonim dideklarasikan, ShapeType sedang dinyatakan sebagai typedef untuk enumerasi anonim, dan tiga nama kCircle, kRectangle, dan kOblateSpheroid sedang dinyatakan sebagai konstanta integral.

Mari kita hancurkan itu. Dalam kasus yang paling sederhana, enumerasi dapat dideklarasikan sebagai

enum tagname { ... };

Ini menyatakan enumerasi dengan tag tagname. Dalam C dan Objective-C (tapi tidak C ++), referensi apa pun untuk ini harus didahului dengan enum kata kunci. Sebagai contoh:

enum tagname x;  // declare x of type 'enum tagname'
tagname x;  // ERROR in C/Objective-C, OK in C++

Untuk menghindari keharusan menggunakan enum kata kunci di mana-mana, typedef dapat dibuat:

enum tagname { ... };
typedef enum tagname tagname;  // declare 'tagname' as a typedef for 'enum tagname'

Ini dapat disederhanakan menjadi satu baris:

typedef enum tagname { ... } tagname;  // declare both 'enum tagname' and 'tagname'

Dan akhirnya, jika kita tidak perlu dapat menggunakannya enum tagname dengan enum kata kunci, kita bisa membuat enum anonim dan hanya mendeklarasikannya dengan nama typedef:

typedef enum { ... } tagname;

Sekarang, dalam hal ini, kami menyatakan ShapeType menjadi nama yang diketik dari enumerasi anonim. ShapeType benar-benar hanya tipe integral, dan hanya boleh digunakan untuk mendeklarasikan variabel yang memegang salah satu nilai yang tercantum dalam deklarasi (yaitu salah satu dari kCircle, kRectangle, dan kOblateSpheroid). Anda dapat menetapkan ShapeType variabel nilai lain dengan casting, jadi Anda harus berhati-hati saat membaca nilai enum.

Akhirnya, kCircle, kRectangle, dan kOblateSpheroid dinyatakan sebagai konstanta integral dalam namespace global. Karena tidak ada nilai spesifik yang ditentukan, mereka ditetapkan ke bilangan bulat berturut-turut dimulai dengan 0, jadi kCircle adalah 0, kRectangle adalah 1, dan kOblateSpheroid adalah 2.


1532
2018-04-01 22:22



Apple merekomendasikan mendefinisikan enums seperti ini sejak Xcode 4.4:

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

Mereka juga menyediakan makro NS_ENUM yang praktis:

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

Definisi ini memberikan pemeriksaan tipe yang lebih kuat dan penyelesaian kode yang lebih baik. Saya tidak dapat menemukan dokumentasi resmi NS_ENUM, tetapi Anda dapat menonton video "Modern Objective-C" dari sesi WWDC 2012 sini.

PERBARUI: Tautan ke dokumentasi resmi sini.


240
2018-03-06 09:43



Sebuah enum menyatakan satu set nilai yang dipesan - typedef hanya menambahkan nama yang berguna untuk ini. Unsur pertama adalah 0 dll.

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

WORKDAYS today = Monday;

Di atas hanyalah sebuah enumerasi tag shapeType.


47
2018-03-15 16:31



Jenis yang ditentukan pengguna yang memiliki kemungkinan nilai kCircle, kRectangle, atau kOblateSpheroid. Nilai-nilai di dalam enum (kCircle, dll) terlihat di luar enum. Penting untuk mengingatnya (int i = kCircle; valid, misalnya).


34
2018-04-01 22:04



Pembaruan untuk Perubahan 64-bit: Menurut dokumen apel tentang perubahan 64-bit,

Enumerasi Juga Diketik: Dalam kompiler LLVM, jenis yang disebutkan dapat   tentukan ukuran enumerasi. Ini berarti bahwa beberapa disebutkan   jenis mungkin juga memiliki ukuran yang lebih besar dari yang Anda harapkan. Itu   solusi, seperti dalam semua kasus lain, adalah tidak membuat asumsi tentang a   ukuran tipe data. Sebagai gantinya, tetapkan nilai yang disebutkan ke suatu variabel   dengan tipe data yang tepat

Jadi kamu harus buat enum dengan tipe seperti di bawah ini sintaks jika Anda mendukung untuk 64-bit.

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

atau

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

Jika tidak, itu akan menyebabkan peringatan sebagai Implicit conversion loses integer precision: NSUInteger (aka 'unsigned long') to ShapeType

Pembaruan untuk pemrograman cepat:

Dengan cepat, ada perubahan sintaks.

enum ControlButtonID: NSUInteger {
        case kCircle , kRectangle, kOblateSpheroid
    }

28
2018-01-29 13:08



Enum adalah tipe data yang ditentukan pengguna. JENIS DATA DITENTUKAN Variabel tipe data yang di-enumerasi hanya dapat mengasumsikan nilai-nilai yang telah dinyatakan sebelumnya.

enum month { jan = 1, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec };
enum month this_month;

this_month = feb;

Dalam deklarasi di atas, bulan dideklarasikan sebagai tipe data yang disebutkan. Ini terdiri dari serangkaian nilai, jan untuk mendeklarasikan. Secara numerik, jan diberi nilai 1, feb nilai 2, dan seterusnya.

Variabel this_month dideklarasikan sebagai tipe yang sama dengan bulan, kemudian diberi nilai yang terkait dengan feb. This_month tidak dapat diberi nilai apa pun di luar yang ditentukan dalam daftar inisialisasi untuk deklarasi bulan.


25
2017-10-17 12:08



Enum (kependekan dari enumerasi) digunakan untuk menghitung satu set nilai (enumerator). Nilai adalah hal abstrak yang diwakili oleh simbol (kata). Misalnya enum dasar bisa

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

Enum ini disebut anonim karena Anda tidak memiliki simbol untuk menamainya. Tapi itu masih sangat benar. Gunakan saja seperti ini

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

Baik. Hidup ini indah dan semuanya berjalan dengan baik. Tetapi suatu hari Anda perlu menggunakan kembali enum ini untuk menentukan variabel baru untuk menyimpan myGrandFatherPantSize, kemudian Anda menulis:

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

Tapi kemudian Anda memiliki kesalahan kompiler "redefinisi enumerator". Sebenarnya masalahnya adalah bahwa compiler tidak yakin bahwa Anda enum pertama dan yang kedua menggambarkan hal yang sama.

Kemudian jika Anda ingin menggunakan kembali enumerator yang sama (di sini xs ... xxxxl) di beberapa tempat Anda harus menandainya dengan nama yang unik. Kali kedua Anda menggunakan set ini, Anda hanya perlu menggunakan tag. Tetapi jangan lupa bahwa tag ini tidak menggantikan kata enum tetapi hanya kumpulan enumerator. Kemudian berhati-hatilah menggunakan enum seperti biasa. Seperti ini:

// 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;

Anda dapat menggunakannya dalam definisi parameter juga:

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

Anda dapat mengatakan bahwa menulis ulang enum di mana saja tidak nyaman dan membuat kode terlihat agak aneh. Kamu benar. Tipe sebenarnya akan lebih baik.

Ini adalah langkah terakhir dari kemajuan besar kami ke puncak. Dengan hanya menambahkan typedef, mari kita ubah enum kita menjadi tipe nyata. Oh hal terakhir, typedef tidak diperbolehkan dalam kelas Anda. Kemudian tentukan tipe Anda di atas. Lakukan seperti ini:

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

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

Ingat bahwa tag itu opsional. Maka sejak di sini dalam kasus itu, kita tidak memberi tag pada enumerator tetapi hanya untuk mendefinisikan tipe baru. Maka kita tidak benar-benar membutuhkannya lagi.

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

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

Jika Anda mengembangkan di ObjectiveC dengan XCode saya membiarkan Anda menemukan beberapa macro bagus diawali dengan NS_ENUM. Itu akan membantu Anda mendefinisikan enum yang baik dengan mudah dan terlebih lagi akan membantu penganalisa statis untuk melakukan beberapa pemeriksaan menarik bagi Anda sebelum dikompilasi.

Enum yang baik!


23
2018-03-10 18:23