অবজেক্টিভ-সি-তে টাইপয়েড এনাম কী?


1087

আমি মনে করি না যে আমি মৌলিকভাবে একটি enumকী এবং কখন এটি ব্যবহার করব তা বুঝতে পারি।

উদাহরণ স্বরূপ:

typedef enum {
    kCircle,
    kRectangle,
    kOblateSpheroid
} ShapeType;

আসলে এখানে কী ঘোষণা করা হচ্ছে?


2
ব্যবহারকারীর সংজ্ঞায়িত প্রকারকে কি "এনাম" বলা হয়? এটি আমি ভেবেছিলাম, যতক্ষণ না আমি একাধিক টাইপেডে এনামের ঘোষণা দিয়েছি।
ক্রেগ 22

8
না, ব্যবহারকারী সংজ্ঞায়িত ধরণটি শেপটাইপ। মধ্যে typedef আপ পড়ুন: en.wikipedia.org/wiki/Typedef
rampion

6
অবজেক্টিভ-সি-তে একটি টাইপডেফ সি-তে টাইপডেফের সমান এবং অবজেক্টিভ-সি-তে একটি এনাম সি-তে একটি এনামের সমান, এটি কে.ক্রেলল = 0, কেআরেক্টাঙ্গেল = 1 এবং কেবলেটসফেরয়েড = সহ একটি এনাম ঘোষণা করে = 2, এবং এনাম টাইপের নাম শেপটাইপ দেয়। আপনি যদি জানেন না "টাইপিডেফ" এবং "এনাম" এর অর্থ কী, সি সম্পর্কে একটি বই
কিনুন

উত্তর:


1565

তিনটি জিনিস এখানে ঘোষণা করা হচ্ছে: একটি বেনামী গণিত টাইপ ঘোষিত হয়, ShapeTypeযে বেনামী শুমার জন্য একটি typedef ঘোষিত হচ্ছে, এবং তিন নাম kCircle, kRectangleএবং kOblateSpheroidঅবিচ্ছেদ্য ধ্রুবক হিসেবে ঘোষণা করা হচ্ছে।

আসুন এটি ভেঙে দিন। সবচেয়ে সহজ ক্ষেত্রে, একটি গণনা হিসাবে ঘোষণা করা যেতে পারে

enum tagname { ... };

এটি ট্যাগ সহ একটি গণনা ঘোষণা করে tagname। সি এবং উদ্দেশ্য সি (কিন্তু ইন না সি ++) এই কোনো রেফারেন্স নয় সঙ্গে পূর্বে করা enumশব্দ। উদাহরণ স্বরূপ:

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

যে enumকোনও জায়গায় কীওয়ার্ডটি ব্যবহার না করার জন্য , একটি টাইপডিফ তৈরি করা যেতে পারে:

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)। আপনি ShapeTypeingালাইয়ের মাধ্যমে ভেরিয়েবলের অন্য মান নির্ধারণ করতে পারেন , তবে এনাম মানগুলি পড়ার সময় আপনাকে সতর্কতা অবলম্বন করতে হবে।

অবশেষে, kCircle, kRectangle, এবং kOblateSpheroidবিশ্বব্যাপী নামস্থানে অবিচ্ছেদ্য ধ্রুবক হিসেবে ঘোষণা করা হয়। যেহেতু কোনও নির্দিষ্ট মান নির্দিষ্ট করা হয়নি, সেগুলি 0 দিয়ে শুরু করে একটানা পূর্ণসংখ্যার জন্য নির্ধারিত হয়, সুতরাং kCircle0 হয়, kRectangle1 হয় এবং kOblateSpheroid2 হয়।


6
সুন্দর ব্যাখ্যা - কেবল একটি জিনিস যুক্ত করতে, স্ট্রাক্টস সি তে অনুরূপ নামকরণের নিয়ম অনুসরণ করুন (উদ্দেশ্য-সি সম্পর্কে নিশ্চিত নয়)।
মাইকেল বুড়

109
অবজেক্টিভ-সি হ'ল সি-এর যথাযথ সুপারসেট সি-তে সমস্ত সি স্ট্রাক্ট নামকরণের নিয়মগুলি যেমন-সি-তে ঠিক তেমন বৈধ।
সিগজুইস

অসাধারণ. আমি কি কেবল সি ++ স্টাইল
এনাম

11
আপনি সি ++ স্টাইল এনাম ব্যবহার করতে পারেন যদি আপনি যে ফাইলটিতে সেগুলি ঘোষণা করেন সেটিকে .m এর পরিবর্তে একটি। মিমি ফাইল হয়। উদ্দেশ্য-সি ++ অদ্ভুতভাবে শক্তিশালী।
কেভিন হফম্যান

14
এবং একবার এই উত্তরের মাথাটি পেয়ে গেলে নতুন এনএস_ইএনএম এবং এনএস_অপশনগুলি দেখার পক্ষে উপযুক্ত। এখানে টিউটোরিয়াল: nshipster.com/ns_enum-ns_options এবং তাই এখানে: stackoverflow.com/questions/14080750/...
Snowcrash

254

অ্যাপল এক্সকোড ৪.৪ থেকে এ জাতীয় এনাম সংজ্ঞায়নের পরামর্শ দিচ্ছে :

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

তারা একটি সহজ ম্যাক্রো সরবরাহ করে NS_ENUM:

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

এই সংজ্ঞাগুলি শক্তিশালী ধরণের চেকিং এবং আরও ভাল কোড সমাপ্তি সরবরাহ করে। আমি এর অফিসিয়াল ডকুমেন্টেশন খুঁজে পাইনি NS_ENUM, তবে আপনি এখানে ডাব্লুডাব্লুডিসি 2012 সেশন থেকে "মডার্ন অবজেক্টিভ-সি" ভিডিওটি দেখতে পারেন ।



অফিসিয়াল ডকুমেন্টেশনের লিঙ্ক আপডেট করুন এখানে



5
অন্য উত্তরে যেমন মন্তব্য করা হয়েছে, NS_ENUMএনএসএইচএসটার দ্বারা অ্যাপলের ম্যাক্রোর ব্যাখ্যা দেখুন : এনএসএইচইএসটার.
বেসিল

1
এটি এনএস_এনইউএম সম্পর্কিত অফিসিয়াল ডকুমেন্টেশনের লিঙ্ক: ডেভেলপার.এপল.
জি

50

একটি এনাম অর্ডার করা মানগুলির একটি সেট ঘোষণা করে - টাইপিডেফ এটিতে একটি সহজ নাম যুক্ত করে। প্রথম উপাদানটি 0 ইত্যাদি is

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

WORKDAYS today = Monday;

উপরেরটি আকৃতি টাইপ ট্যাগগুলির একটি অঙ্ক মাত্র।


34

একজন ব্যবহারকারী সংজ্ঞায়িত ধরনের সম্ভাব্য মান আছে kCircle, kRectangleঅথবা kOblateSpheroid। এনামের ভিতরে থাকা মানগুলি (কেসি সার্কেল ইত্যাদি) যদিও এনামের বাইরে দৃশ্যমান। এটি মনে রাখা ( int i = kCircle;যেমন বৈধ, উদাহরণস্বরূপ) রাখা গুরুত্বপূর্ণ ।


30

-৪-বিট পরিবর্তনের জন্য আপডেট: apple৪- বিট পরিবর্তন সম্পর্কে আপেল ডক্স অনুসারে ,

গণনাগুলিও টাইপ করা হয়: এলএলভিএম সংকলনে, গণিত প্রকারগুলি গণনার আকার নির্ধারণ করতে পারে। এর অর্থ হ'ল কিছু গণিত প্রকারের আকারও আপনার প্রত্যাশার চেয়ে বড়। অন্যান্য সমস্ত মামলার মতো সমাধানও হ'ল ডেটা টাইপের আকার সম্পর্কে কোনও অনুমান করা। পরিবর্তে, সঠিক ডেটা টাইপ সহ কোনও ভেরিয়েবলের জন্য যে কোনও গণনা করা মানগুলি নির্ধারণ করুন

সুতরাং আপনি যদি 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
    }

যদি এগিয়ে ঘোষণা enum (NS_ENUM) প্রয়োজন: stackoverflow.com/a/42009056/342794
লাল

25

এনাম (গণনার সংক্ষিপ্তকরণ) মানগুলির একটি সেট গণনা করতে ব্যবহৃত হয় (গণক)। একটি মান একটি বিমূর্ত জিনিস যা একটি চিহ্ন (একটি শব্দ) দ্বারা প্রতিনিধিত্ব করা হয়। উদাহরণস্বরূপ, একটি বেসিক এনাম হতে পারে

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

এই এনামটিকে বেনামে বলা হয় কারণ এটির নামকরণের জন্য আপনার কাছে কোনও প্রতীক নেই। তবে এটি এখনও পুরোপুরি সঠিক। শুধু এটি ব্যবহার করুন

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

ঠিক আছে. জীবন সুন্দর এবং সবকিছু ঠিকঠাক হয়। তবে একদিন আপনার মাইগ্র্যান্ডফাদারপ্যান্টসাইজ সংরক্ষণ করার জন্য একটি নতুন ভেরিয়েবল সংজ্ঞায়িত করতে এই এনামটিকে পুনরায় ব্যবহার করতে হবে, তারপরে আপনি লিখবেন:

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;

আপনি বলতে পারেন যে সমস্ত জায়গায় এনরাইট রাইটিংটি সুবিধাজনক নয় এবং কোডটি কিছুটা অদ্ভুত দেখাচ্ছে। তুমি ঠিক. একটি বাস্তব টাইপ আরও ভাল হবে।

এটি শীর্ষ সম্মেলনে আমাদের দুর্দান্ত অগ্রগতির চূড়ান্ত পদক্ষেপ। কেবল একটি টাইপিডেফ যুক্ত করে আসুন আমাদের এনামকে একটি প্রকৃত ধরণের রূপান্তরিত করি। ওহ শেষ কথা, টাইপয়েফ আপনার ক্লাসের মধ্যে অনুমোদিত নয়। তারপরে ঠিক আপনার উপরে প্রকারটি নির্ধারণ করুন। এটা এভাবে করো:

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

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

মনে রাখবেন যে ট্যাগটি alচ্ছিক। তারপরে এখানে, সেই ক্ষেত্রে, আমরা গণককে ট্যাগ করি না তবে একটি নতুন ধরণের সংজ্ঞা দিতে পারি। তাহলে আমাদের আর এটির দরকার নেই।

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

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

আপনি যদি এক্সকোডের সাথে অবজেক্টিভ-সি-তে বিকাশ করছেন তবে আমি আপনাকে এনএস_ইএনএম-এর উপসর্গযুক্ত কিছু দুর্দান্ত ম্যাক্রো আবিষ্কার করতে দেব। এটি আপনাকে সহজেই ভাল এনামগুলিকে সংজ্ঞায়িত করতে সহায়তা করবে এবং তদ্ব্যতীত স্থির বিশ্লেষককে সংকলনের আগে আপনার জন্য কিছু আকর্ষণীয় চেক করতে সহায়তা করবে।

গুড এনুম!


আমি সর্বদা ভাবতাম "কেন এমন প্রশ্নের উত্তর আগেই দেওয়া এবং স্বীকৃত কেন কেউ দেবে"? ছেলে, আমি সব সময় ভুল ছিল! এটি সেরা উত্তর এবং আমার মতো নতুনদের সহায়তা করে!
রাক অ্যাপদেব

10

typedefবিদ্যমান ভেরিয়েবল টাইপের নাম পুনরায় সংজ্ঞায়িত করার জন্য দরকারী। এটি ডেটাটাইপ কল করার জন্য সংক্ষিপ্ত এবং অর্থপূর্ণ উপায় সরবরাহ করে। উদাহরণ:

typedef unsigned long int TWOWORDS;

এখানে, স্বাক্ষরবিহীন দীর্ঘ int টাইপটি TWWORDS টাইপের হতে নতুন সংজ্ঞা দেওয়া হয়েছে। সুতরাং, আমরা এখন লিখে স্বাক্ষরযুক্ত দীর্ঘ int টাইপের ভেরিয়েবল ঘোষণা করতে পারি,

TWOWORDS var1, var2;

পরিবর্তে

unsigned long int var1, var2;

7
typedef enum {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;

তাহলে আপনি এটি ব্যবহার করতে পারেন: -

 ShapeType shape;

এবং

 enum {
    kCircle,
    kRectangle,
    kOblateSpheroid
} 
ShapeType;

এখন আপনি এটি ব্যবহার করতে পারেন:

enum ShapeType shape;

3

এনামকে এনাম উপাদানগুলিকে মান নির্ধারণের জন্য ব্যবহৃত হয় যা স্ট্রাক্টে করা যায় না। সুতরাং প্রতিবার সম্পূর্ণ ভেরিয়েবল অ্যাক্সেস না করে আমরা এনামে ভেরিয়েবলগুলিকে নির্ধারিত মান দ্বারা এটি করতে পারি। ডিফল্টরূপে এটি 0 অ্যাসাইনমেন্ট দিয়ে শুরু হয় তবে আমরা এটিকে কোনও মান নির্ধারণ করতে পারি এবং এনামের পরবর্তী চলকটি পূর্ববর্তী মান +1 হিসাবে একটি মান নির্ধারিত হবে।


3

আপনি নীচের বিন্যাসে ব্যবহার করতে পারেন, কাঁচা ডিফল্ট মান 0 থেকে শুরু করে, তাই

  • কে সার্কেল 0,
  • kR আয়তক্ষেত্র 1,
  • কেবলেটসফেরয়েড 2।

আপনি নিজের নির্দিষ্ট সূচনা মান নির্ধারণ করতে পারেন।

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

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

2

একটি টাইপিডেফ প্রোগ্রামারকে একটি উদ্দেশ্য-সি প্রকারকে অন্য হিসাবে সংজ্ঞায়িত করতে দেয়। উদাহরণ স্বরূপ,

typedef int কাউন্টার; কাউন্টারকে টাইপটি ইন্ট টাইপের সমতুল্য হিসাবে সংজ্ঞায়িত করে। এটি কোড পঠনযোগ্যতা তীব্রভাবে উন্নত করে।


2

টাইপিডেফ সি এবং সি ++ এর একটি কীওয়ার্ড। এটি বেসিক ডেটা ধরণের (চর, ইনট, ফ্লোট, ডাবল, স্ট্রাক্ট এবং এনাম) নতুন নাম তৈরি করতে ব্যবহৃত হয় ।

typedef enum {
    kCircle,
    kRectangle,
    kOblateSpheroid
} ShapeType;

এখানে এটি অঙ্কিত ডেটা টাইপ শেপ টাইপ তৈরি করে এবং আমরা নীচের মত এনাম টাইপ শেপ টাইপের জন্য নতুন নাম লিখতে পারি

ShapeType shape1; 
ShapeType shape2; 
ShapeType shape3;

1

এনাম বহু ধরণের "ত্রুটি" হ্রাস করতে পারে এবং কোডটিকে আরও পরিচালিত করে তুলবে

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

সংজ্ঞাটির কোনও বাধা নেই। এটি কেবলমাত্র একটি বিকল্প। এটি রাজ্যের সমস্ত শর্ত সীমাবদ্ধ করতে সক্ষম নয়। যখন স্টেটটি 5 তে নির্ধারিত হয়, তখন প্রোগ্রামটি ভুল হবে, কারণ কোনও মিলের অবস্থা নেই। সংকলক স্টেট = 5 সতর্ক করতে যাচ্ছে না

সুতরাং এটির মতো ব্যবহার করা ভাল

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

SampleState state = SampleStateGood;
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.