نوع مُعدّد
في برمجة الحاسوب ، يُعرف النوع المُعدّد (ويُسمى أيضًا التعداد أو العامل في لغة البرمجة R ، واسم الشرط في لغة البرمجة COBOL ، ومتغير الحالة في لغة البرمجة JOVIAL ، والترتيبي في لغة البرمجة PL /I ، والمتغير الفئوي في الإحصاء) بأنه نوع بيانات يتكون من مجموعة من القيم المسماة بالعناصر أو الأعضاء أو التعداد أو المُعدِّدات . عادةً ما تكون أسماء المُعدِّدات مُعرِّفات تعمل كثوابت في اللغة. يُمكن اعتبار النوع المُعدّد اتحادًا مُنحطًا مُوسومًا لنوع الوحدة . يُمكن إسناد أي قيمة من المُعدِّدات إلى متغير مُعرَّف على أنه من النوع المُعدّد. بعبارة أخرى، يحتوي النوع المُعدّد على قيم مختلفة عن بعضها البعض، يُمكن مقارنتها وإسنادها، ولكن لا يُحددها المبرمج عادةً على أنها ذات تمثيل ملموس مُحدد في ذاكرة الحاسوب . يمكن للمترجمات والمفسرات تمثيلها بشكل تعسفي.
وصف
على سبيل المثال، قد تكون الأوراق الأربعة في مجموعة أوراق اللعب أربعة عناصر تعدادية تُسمى CLUBS، ، DIAMONDS، HEARTS، و SPADES، تنتمي إلى نوع تعدادي يُسمى . إذا تم تعريف CardSuitمتغير بنوع بيانات ، فيمكن إسناد أي من هذه القيم الأربع إليه.vCardSuit
على الرغم من أن المُعدِّدات عادةً ما تكون متميزة، إلا أن بعض اللغات قد تسمح بإدراج المُعدِّد نفسه مرتين في تعريف النوع. ولا يشترط أن تكون أسماء المُعدِّدات متطابقة دلاليًا أو متوافقة بأي شكل من الأشكال. على سبيل المثال، يمكن تعريف نوع مُعدَّد باسم `a` Colorليتكون من المُعدِّدات RED`a` GREENو` ZEBRAa` و`a` و` MISSINGa` و` a`. في بعض اللغات، يُحدد تعريف النوع المُعدَّد ترتيبًا لأعضائه عمدًا (` a` و ...BACONHIGHMEDIUMLOWENGLISHFRENCHGERMANSPANISH
قد تتضمن اللغة بعض أنواع التعداد. على سبيل المثال، غالبًا ما يكون النوع المنطقي عبارة عن تعداد مُعرَّف مسبقًا للقيمتين falseو true. كما يمكن تعريف نوع وحدة يتكون من قيمة واحدة لتمثيل null. وتتيح العديد من اللغات للمستخدمين تعريف أنواع تعداد جديدة.
عادةً ما تُنفَّذ قيم ومتغيرات النوع المُعدَّد باستخدام نوع عدد صحيح كتمثيل أساسي. تسمح بعض لغات البرمجة، وخاصة لغات برمجة الأنظمة ، للمستخدم بتحديد تركيبة البتات المستخدمة لكل مُعدِّد، مما يُفيد في تمثيل مجموعات المُعدِّدات بكفاءة كسلاسل بتات ثابتة الطول. في نظرية الأنواع ، تُعتبر الأنواع المُعدَّدة غالبًا اتحادات مُوسَّمة لأنواع الوحدة . ولأن هذه الأنواع تأخذ الشكلويمكن كتابتها أيضاً كأعداد طبيعية.
الأساس المنطقي
لم تكن بعض لغات البرمجة المبكرة تدعم أنواع البيانات المُعدّدة. فإذا أراد المبرمج، على سبيل المثال myColor، أن تكون قيمة متغير ما هي REDصفر، فإنه يُعلن عن هذا الثابت REDويُسند إليه قيمة عشوائية، عادةً ما تكون عددًا صحيحًا ثابتًا. REDثم يُسند هذا الثابت إلى المتغير myColor. وهناك تقنيات أخرى تُسند قيمًا عشوائية إلى سلاسل نصية تحتوي على أسماء المُعدِّدات.
كانت هذه القيم العشوائية تُعرف أحيانًا بالأرقام السحرية ، نظرًا لعدم وجود تفسير لكيفية الحصول عليها أو ما إذا كانت قيمها الفعلية ذات دلالة. وقد تُصعّب هذه الأرقام السحرية فهم وصيانة شفرة المصدر على الآخرين.
من ناحية أخرى، تجعل الأنواع المُعدّدة الكود أكثر وضوحًا وتوثيقًا ذاتيًا. فبحسب لغة البرمجة، قد يُعيّن المُصرّف تلقائيًا قيمًا افتراضية للمُعدّدات، ما يُخفي التفاصيل غير الضرورية عن المُبرمج. بل قد لا تكون هذه القيم مرئية للمُبرمج أصلًا (انظر إخفاء المعلومات ). كما تمنع الأنواع المُعدّدة المُبرمج من كتابة كود غير منطقي، مثل إجراء عمليات حسابية على قيم المُعدّدات. فإذا طُبعت قيمة مُتغير مُعيّن له مُعدّد، فقد تطبع بعض لغات البرمجة اسم المُعدّد بدلًا من قيمته العددية. ومن المزايا الأخرى للأنواع المُعدّدة أنها تُمكّن المُصرّفات من فرض صحة دلالية. فعلى سبيل المثال: myColor = TRIANGLE يُمكن منع استخدام `true`، بينما myColor = RED يُمكن استخدام `false`، حتى لو كان كل من `true` TRIANGLEو` REDfalse` مُمثلين داخليًا بالقيمة `true` 1.
من الناحية المفاهيمية، يُشبه النوع المُعدّد قائمة الأسماء (الرموز العددية)، حيث يُخصص لكل قيمة ممكنة من النوع عدد طبيعي مميز. وبالتالي، يُعد أي نوع مُعدّد تطبيقًا عمليًا لهذا المفهوم. وعندما يكون الترتيب ذا معنى أو يُستخدم للمقارنة، يتحول النوع المُعدّد إلى نوع ترتيبي .
الاتفاقيات
تميل لغات البرمجة إلى امتلاك أساليب برمجة خاصة بها، وغالبًا ما تكون متعددة، بالإضافة إلى اصطلاحات تسمية خاصة بها . عادةً ما يكون المتغير المُسند إلى تعداد اسمًا بصيغة المفرد، وغالبًا ما يتبع إما اصطلاح PascalCase أو الأحرف الكبيرة ، بينما تُستخدم الأحرف الصغيرة وغيرها بشكل أقل شيوعًا.
بناء الجملة في العديد من لغات البرمجة
لغات مبنية على ALGOL 60
على الرغم من أن لغة ALGOL 60 نفسها لا تحتوي على نوع تعداد، إلا أن العديد من اللغات المشتقة منها تحتوي عليه. وعلى وجه الخصوص، كان لباسكال تأثير قوي على تصميم لغة Ada.
باسكال
في لغة باسكال ، يمكن تعريف نوع مُعدّد ضمنيًا عن طريق سرد القيم في قائمة بين قوسين:
var suit : ( club , diamonds , hearts , spades ) ;غالباً ما يظهر هذا التصريح في تصريح مرادف نوع، بحيث يمكن استخدامه لمتغيرات متعددة:
نوع رمز الورقة = ( النوادي ، الماس ، القلوب ، البستوني ) ؛ الورقة = سجل الرمز : رمز الورقة ؛ القيمة : 1 .. 13 ؛ نهاية ؛ متغير اليد : مصفوفة [ 1 .. 13 ] من الورقة ؛ الورقة الرابحة : رمز الورقة ؛يُعدّ ترتيب قيم التعداد مهمًا. فالنوع المُعدّد هو نوع ترتيبي، وتُعطي الدالتان ` predand` succالقيمة السابقة أو التالية للتعداد، كما ordتُحوّلان قيم التعداد إلى تمثيلها العددي الصحيح. مع ذلك، لا تُوفّر لغة باسكال القياسية تحويلًا من الأنواع الحسابية إلى التعدادات. بينما تُوفّر لغة باسكال المُوسّعة هذه الوظيفة عبر succدالة مُوسّعة. وتُتيح بعض لهجات باسكال الأخرى هذه الوظيفة عبر تحويل الأنواع. كما تُوفّر بعض اللغات الحديثة المُشتقّة من باسكال، مثل Modula-3 ، صيغة تحويل خاصة باستخدام دالة تُسمى VAL`or`. وتُعامل Modula-3 أيضًا BOOLEAN`and` CHARكأنواع مُعدّدة خاصة مُعرّفة مُسبقًا، وتستخدم ORD`and` VALلفك تشفير وتشفير ASCII القياسي.
تسمح لغات البرمجة من نمط باسكال أيضًا باستخدام التعداد كمؤشر للمصفوفة:
var suitcount : array [ cardsuit ] of integer ;آدا
في لغة Ada ، يكون تعريف الأنواع المعدودة مشابهًا لتعريفها في لغة Pascal، حيث يتم استبدال استخدام "=" بـ "is":
نوع Cardsuit هو ( نوادي ، ماس ، قلوب ، بستوني )؛بالإضافة إلى ذلك Pred، تدعم لغة Ada أيضًا Succتحويلات السلاسل البسيطة عبر و .ValPosImageValue
على غرار لغات البرمجة من نمط C، تسمح لغة Ada بتحديد التمثيل الداخلي للتعداد:
للاستخدام مع أوراق اللعب ( النوادي => 1 ، الماس => 2 ، القلوب => 4 ، البستوني => 8 )؛تتيح لغة آدا أيضًا تحديد عدد بتات التعداد بطريقة مباشرة، على عكس لغات البرمجة المشابهة للغة سي التي تتميز بدعم غير متسق غالبًا ما يؤدي إلى أخطاء ترجمة دقيقة . [ 1 ] على سبيل المثال:
بالنسبة لحجم أوراق اللعب ، استخدم 4 ؛ -- 4 بتاتبالإضافة إلى ذلك، يمكن استخدام التعدادات كمؤشرات للمصفوفات، كما هو الحال في لغة باسكال، ولكن هناك سمات محددة للتعدادات.
Shuffle : constant array ( Cardsuit ) of Cardsuit := ( Clubs => Cardsuit ' Succ ( Clubs ), -- انظر سمات التعدادات 'First, 'Last, 'Succ, 'Pred Diamonds => Hearts , -- قيمة صريحة Hearts => Cardsuit ' Last , -- أول قيمة تعداد من نوع Cardsuit، على سبيل المثال، clubs Spades => Cardsuit ' First -- آخر قيمة تعداد من نوع Cardsuit، على سبيل المثال، spades );على غرار لغة Modula-3، تتعامل لغة Ada Booleanمع الأحرف كأنواع تعداد Characterخاصة مُعرَّفة مسبقًا (في الحزمة " Standard"). على عكس Modula-3، يُمكن أيضًا تعريف أنواع أحرف خاصة.
نوع البطاقات هو (' 7 ', ' 8 ', ' 9 ', ' X ', ' J ', ' Q ', ' K ', ' A ');PL/I
لا يحتوي كل من PL/I الأصلي و ANSI X3.53–1976 على تعدادات، ولكن IBM Enterprise PL/I [ 2 ] يحتوي على أنواع ترتيبية.
لا يمكن استخدام المتغير الترتيبي مباشرةً كدليل سفلي أو كشرط من شروط الأمر DO TO . ومع ذلك،
- تسمح وظائف النوع first و last ، والوظائف المضمنة binaryvalue و ordinalpred و ordinalsucc بذلك بشكل غير مباشر.
- يدعم الترتيب DO UPTHRU و DO DOWNTO
عرّف متغيرًا ترتيبيًا foo ( أخضر ، مع ، حسد ) ؛ أعلن عن متغير ترتيبي ix ، متغيرًا ترتيبيًا foo، متغيرًا ترتيبيًا bar ( الأول ( : foo :) : الأخير ( : foo :) ثابت ثنائي ؛ كرر من i = الأول ( : foo :) إلى الأخير ( : foo :) ؛ bar ( i ) = 13 ؛ انتهى ؛ كرر من ix = الأول ( : foo :) إلى الأخير ( : foo :) ؛ i = القيمة الثنائية ( ix ) ؛ bar ( i ) = bar ( i ) + 1 ؛ انتهى ؛ كرر من ix = الأول ( : foo :) كرر ordinalsucc ( ix ) حتى ( ix = الأول ( : foo :) /* توقف عند الالتفاف. */ ؛ i = القيمة الثنائية ( ix ) ؛ اعرض ( bar ( i ) || ' في ' || ix ) ؛ انتهى ؛لغة C واللغات المشابهة لها نحوياً
ج
لم تكن لهجة K&R الأصلية للغة البرمجة C تحتوي على أنواع مُعدّدة. [ 3 ] في لغة C، يتم إنشاء التعدادات من خلال تعريفات صريحة ( enumالكلمة المفتاحية بحد ذاتها لا تتسبب في تخصيص مساحة تخزين) والتي تستخدم الكلمة المفتاحيةenum وتُذكّر بتعريفات البنية والاتحاد :
typedef enum { CLUBS , DIAMONDS , HEARTS , SPADES , } CardSuit ;typedef struct { CardSuit suit ; short int value ; } Card ;يد البطاقات [ 13 ]؛ ورقة رابحة من نوع البطاقة ؛تُتيح لغة C للمبرمج تمثيل قيم التعداد كأعداد صحيحة مباشرةً. يُمكن مزج الأعداد الصحيحة وقيم التعداد بحرية، كما يُسمح بإجراء جميع العمليات الحسابية على قيم التعداد. بل يُمكن لمتغير التعداد أن يحتوي على عدد صحيح لا يُمثل أيًا من قيم التعداد. في الواقع، وفقًا لتعريف اللغة، سيُعرّف الكود أعلاه القيم Clubsو Diamondsو Heartsو Spadesكثوابت من النوع int، والتي سيتم تحويلها (تلقائيًا) إلى فقط enum CardSuitإذا تم تخزينها في متغير من هذا النوع.
تسمح لغة C أيضًا للمبرمج باختيار قيم ثوابت التعداد بشكل صريح، حتى بدون تحديد النوع. على سبيل المثال،
enum CardSuit { CLUBS = 1 , DIAMONDS = 2 , HEARTS = 4 , SPADES = 8 , };يمكن استخدامها لتعريف نوع يسمح بتمثيل المجموعات الرياضية من البدلات عن enum CardSuitطريق عمليات المنطق الثنائي.
منذ إصدار C23 ، أصبح بإمكان المبرمج تحديد النوع الأساسي للتعداد، بنفس صيغة C++. [ 4 ] وهذا يسمح للمبرمجين بإنشاء تعدادات مُحسَّنة عن طريق اختيار نوع أساسي أقل تكلفة.
enum CardSuit : char { CLUBS = 1 , DIAMONDS = 2 , HEARTS = 4 , SPADES = 8 , };لا تُحدد نطاقات أو مؤهلات أنواع البيانات المُعدّدة في لغة C، لأن لغة C تفتقر إلى ميزات تحديد مساحات الأسماء . قبل إدخال الكلمة constexprالمفتاحية في C23، كانت أنواع البيانات المُعدّدة تُستخدم غالبًا لتعريف الثوابت في وقت الترجمة دون استخدام مُعالج C المُسبق .
سي شارب
تحافظ الأنواع المُعدّدة في لغة البرمجة C# على معظم دلالات "الأعداد الصحيحة الصغيرة" الخاصة بأنواع enum في لغة C. في C#، جميع أنواع enum هي فئات ترث من System.Enum. [ 5 ] بعض العمليات الحسابية غير مُعرّفة لأنواع enum، ولكن يمكن تحويل قيمة enum صراحةً إلى عدد صحيح والعكس، ويمكن أن يحتوي متغير enum على قيم لم يتم التصريح عنها في تعريف enum. على سبيل المثال، بالنظر إلى
enum CardSuit { Clubs , Diamonds , Spades , Hearts , }يُسمح بالتعبيرات CardSuit.Diamonds + 1و CardSuit.Hearts - CardSuit.Clubsبشكل مباشر (لأنه قد يكون من المنطقي المرور عبر تسلسل القيم أو السؤال عن عدد الخطوات بين قيمتين)، ولكن CardSuit.Hearts * CardSuit.Spadesيُعتبر أقل منطقية ولا يُسمح به إلا إذا تم تحويل القيم أولاً إلى أعداد صحيحة.
توفر لغة C# ميزة مشابهة للغة C، وهي إمكانية تحديد قيم عددية صحيحة محددة للتعدادات. وبذلك، يُمكن إجراء عمليات ثنائية على التعدادات، وبالتالي التعامل مع قيم التعداد كمجموعات من العلامات. ويمكن اختبار هذه العلامات باستخدام العمليات الثنائية أو باستخدام HasFlag()الدالة المدمجة لنوع التعداد. [ 6 ]
يُعرّف تعريف التعداد أسماءً للقيم العددية المُختارة، وهو اختصارٌ برمجي ، إذ يُمكن إسناد قيم عددية أخرى إلى متغير التعداد، حتى لو لم تكن هذه القيم ضمن نطاق تعريف التعداد. [ 7 ] [ 8 ] [ 9 ]
لغة سي++
تحتوي لغة C++ على أنواع تعداد موروثة مباشرةً من لغة C، وتعمل بشكل مشابه لها إلى حد كبير، باستثناء أن التعداد في C++ يُعد نوعًا حقيقيًا، مما يُضيف فحصًا إضافيًا أثناء الترجمة. أيضًا (كما هو الحال مع الهياكل)، enumيتم دمج الكلمة المفتاحية C++ مع تعريف نوع (typedef )، بحيث يُمكن الإشارة إلى النوع ببساطة كـ ` <typedef>` بدلًا من `<typedef>`. يُمكن محاكاة ذلك في لغة C باستخدام تعريف نوع (typedef).enumMyEnumMyEnumtypedefenum{VALUE_1,VALUE_2}MyEnum;
توفر لغة C++11 نوعًا ثانيًا من التعداد، يُسمى التعداد النطاقي . يتميز هذا النوع بأمانه من حيث النوع: فلا يتم تحويل عناصر التعداد ضمنيًا إلى نوع عدد صحيح. من بين مزاياه، يسمح هذا بتعريف تدفق الإدخال/الإخراج لنوع التعداد. من سمات التعداد النطاقي أيضًا ضرورة تحديد عناصر التعداد باسم التعداد، لذا يتطلب الاستخدام إضافة اسم التعداد كبادئة (مثلًا، Color::REDبالنسبة لعنصر التعداد الأول في المثال أدناه)، إلا إذا تم استخدام تعريف (تم تقديمه في C++20 ) لإدخال عناصر التعداد في النطاق الحالي. يتم تحديد التعداد النطاقي باستخدام العبارة (أو ). على سبيل المثال:usingenumenumclassenumstruct
// تعداد غير محدد النطاق على نمط لغة C: تعداد CardSuit { CLUBS , DIAMONDS , SPADES , HEARTS , };// فئة تعداد ذات نطاق محدد على نمط C++11: اللون { أحمر ، أخضر ، أزرق ، };int main ( int argc , char * argv []) { Color c = Color :: RED ;// تعداد غير محدد النطاق على نمط لغة C، CardSuit card1 = Clubs ; // يمكن أن يكون غير محدد النطاق CardSuit card2 = CardSuit :: SPADES ; // عادةً ما يتم تعريفه على أنه محدد النطاق }النوع الأساسي للتعداد هو نوع صحيح مُعرَّف من قِبل التنفيذ، ويكون كبيرًا بما يكفي لاستيعاب جميع القيم المُعدّدة؛ ولا يشترط أن يكون أصغر نوع ممكن. يمكن تحديد النوع الأساسي مباشرةً، مما يسمح بـ"التصريحات المسبقة" للتعدادات.
// يجب أن يتناسب مع حجم وتخطيط الذاكرة لنوع التعداد 'long' فئة اللون : طويل { أحمر ، أخضر ، أزرق ، };// تعريف مسبق. إذا تم تعريف قيم لاحقاً // لا تتناسب مع 'char'، فسيكون ذلك خطأً. enum class Shapes : char ;يذهب
تستخدم لغة Goiota المعرف لإنشاء الثوابت المُعدّدة. [ 10 ] [ 11 ]
نوع حجم البايت intconst ( _ = iota // تجاهل القيمة الأولى بتعيينها لمعرف فارغ؛ 0 كيلوبايت ByteSize = 1 << ( 10 * iota ) // 1 << (10 * 1) == 1 << 10 == 1024؛ بالثنائي 10000000000 ميجابايت // 1 << (10 * 2) == 1048576؛ بالثنائي 1000000000000000000000 جيجابايت // 1 << (10 * 3) == 1073741824؛ بالثنائي 100000000000000000000000000000 )جافا
أضاف الإصدار 5.0 من لغة برمجة جافا (J2SE) أنواعًا مُعدّدة يكون تركيب تعريفها مشابهًا لتركيب تعريف لغة C :
enum CardSuit { CLUBS , DIAMONDS , SPADES , HEARTS , };أوراق اللعب الرابحة ؛مع ذلك، يتعامل نظام أنواع جافا مع التعدادات كنوع منفصل عن الأعداد الصحيحة، ولا يُسمح بخلط قيم التعداد مع قيم الأعداد الصحيحة. في الواقع، يُعد نوع التعداد في جافا فئة خاصة يُنشئها المُصرّف ، وليس نوعًا حسابيًا، وتتصرف قيم التعداد كنسخ عامة مُولّدة مسبقًا من تلك الفئة. يمكن أن تحتوي أنواع التعداد على توابع للنسخ ودالة إنشاء (يمكن تحديد وسائطها بشكل منفصل لكل قيمة تعداد). جميع أنواع التعداد تُوسّع ضمنيًا الفئة Enumالمجردة، وبالتالي لا يمكن للتعداد أن يُوسّع أي شيء آخر. الفئة java.lang.Enum<E>مُقيّدة بحيث لا يمكن إنشاء نسخة من نوع التعداد مباشرةً. [ 12 ]Enum<EextendsEnum<E>>
داخليًا، تحتوي كل قيمة من قيم التعداد على عدد صحيح، يُطابق ترتيب تعريفها في الكود المصدري، بدءًا من 0. لا يستطيع المبرمج تعيين عدد صحيح مخصص لقيمة التعداد مباشرةً، ولكن يُمكنه تعريف دوال إنشاء مُحمّلة تُتيح إسناد قيم عشوائية لأعضاء مُعرّفة ذاتيًا في فئة التعداد. يُتيح تعريف دوال الوصول الوصول إلى تلك الأعضاء المُعرّفة ذاتيًا. يُمكن الحصول على العدد الصحيح الداخلي من قيمة التعداد باستخدام الدالة ordinal()، كما يُمكن الحصول على قائمة قيم التعداد لنوع تعداد مُرتب باستخدام الدالة values(). يُنصح عمومًا بعدم تحويل التعدادات إلى أعداد صحيحة والعكس. [ 13 ] أنواع التعداد هي java.lang.Comparable<T>، باستخدام العدد الصحيح الداخلي؛ ونتيجةً لذلك، يُمكن فرزها.
توفر مكتبة جافا القياسية فئات مساعدة للتعامل مع التعدادات. EnumSetتُنفذ هذه الفئة تعدادًا java.util.Set<E>لقيم التعداد؛ وهي مُنفذة كمصفوفة بتات ، مما يجعلها مُختصرة للغاية وفعالة مثل معالجة البتات الصريحة، ولكنها أكثر أمانًا. EnumMapتُنفذ هذه الفئة تحويلًا java.util.Map<K, V>لقيم التعداد إلى كائن. وهي مُنفذة كمصفوفة، حيث تُستخدم القيمة الصحيحة للتعداد كمؤشر.
على عكس لغة C++، يمكن أن تحتوي تعدادات Java على طرق، ومنشئات، وحقول مثل أي فئة أخرى.
public enum Planet { // كوكب، متبوعًا بكتلته ونصف قطره MERCURY ( 3.303e+23 , 2.4397e6 ), VENUS ( 4.869e+24 , 6.0518e6 ), EARTH ( 5.976e+24 , 6.37814e6 ), MARS ( 6.421e+23 , 3.3972e6 ), JUPITER ( 1.9e+27 , 7.1492e7 ), SATURN ( 5.688e+26 , 6.0268e7 ), URANUS ( 8.686e+25 , 2.5559e7 ), NEPTUNE ( 1.024e+26 , 2.4746e7 );public static final double G = 6.67300E-11 ;كتلة نهائية مزدوجة خاصة ؛ نصف قطر نهائي مزدوج خاص ؛كوكب ( كتلة مضاعفة ، نصف قطر مضاعف ) { هذه . الكتلة = الكتلة ؛ هذه . نصف القطر = نصف القطر ؛ }private double mass () { return mass ; }private double radius () { return radius ; }double surfaceGravity () { return G * mass / ( radius * radius ); }double surfaceWeight ( double otherMass ) { return otherMass * surfaceGravity (); }public static void main ( String [] args ) { double earthWeight = Double . parseDouble ( args [ 0 ] ); double mass = earthWeight / EARTH . surfaceGravity (); for ( Planet p : Planet . values ()) { System . out . printf ( "Your weight on %s is %f%n" , p , p . surfaceWeight ( mass ) ); } } }بيرل
لا توفر اللغات ذات الكتابة الديناميكية، التي تتبع التقاليد النحوية للغة C (مثل Perl أو JavaScript )، تعدادات بشكل عام. ولكن في برمجة Perl، يمكن الحصول على النتيجة نفسها باستخدام الاختصارات strings list و hashes (وربما slices ):
my @enum = qw(Clubs Diamonds Hearts Spades) ; my ( %set1 , %set2 ); @set1 { @enum } = (); # تم مسح جميع القيم @set2 { @enum } = ( 1 ) x @enum ; # تم تعيين جميع القيم إلى 1 $set1 { Clubs } ... # false $set2 { Diamonds } ... # trueراكو
يدعم راكو (المعروف سابقًا باسم بيرل 6) التعدادات. توجد طرق متعددة لتعريف التعدادات في راكو، وكلها تُنشئ خريطة خلفية.
enum Cat <sphynx siamese bengal shorthair other> ; # استخدام "quote-words"enum Cat ( 'sphynx' , 'siamese' , 'bengal' , 'shorthair' , 'other' ); # استخدام قائمةenum Cat ( sphynx => 0 , siamese => 1 , bengal => 2 , shorthair => 3 , other => 4 ); # استخدام مُنشئات الزوجenum Cat (: sphynx ( 0 ), : siamese ( 1 ), : bengal ( 2 ), shorthair ( 3 ), : other ( 4 )); # طريقة أخرى لاستخدام الأزواج، يمكنك أيضًا استخدام `:0sphynx`PHP
تمت إضافة التعدادات في إصدار PHP 8.1.
enum CardSuit { case Hearts ; case Diamonds ; case Clubs ; case Spades ; }يمكن دعم المُعدِّدات بقيم نصية أو عددية صحيحة للمساعدة في عملية التسلسل:
enum CardSuit : string { case Hearts = 'H' ; case Diamonds = 'D' ; case Clubs = 'C' ; case Spades = 'S' ; }تُتيح واجهة Enum طريقةً تُعيد مجموعةً من عناصرها المُعدّدة وأسمائها. كما تُتيح Enums المدعومة بسلاسل نصية/أعداد صحيحة القيمةَ الأساسية وطرقَ (لمحاولة) فك التسلسل. ويمكن للمستخدمين إضافة طرق أخرى.
الصدأ
على الرغم من أن لغة Rust تستخدم enumالكلمة المفتاحية مثل لغة C، إلا أنها تستخدمها لوصف الاتحادات الموسومة ، والتي يمكن اعتبار التعدادات شكلاً متدهوراً منها. ولذلك، فإن تعدادات Rust أكثر مرونة بكثير ويمكن أن تحتوي على متغيرات من نوع struct و tuple.
enum Message { Quit , Move { x : i32 , y : i32 }, // struct Write ( String ), // tuple أحادي العنصر ChangeColor ( i32 , i32 , i32 ), // tuple ثلاثي العناصر }كما هو الحال في لغة C، تدعم لغة Rust أيضاً تحديد قيم كل متغير،
pub enum Weekday { Sunday = 1 , Monday = 2 , Tuesday = 4 , Wednesday = 8 , Thursday = 16 , Friday = 32 , Saturday = 64 , }سويفت
في لغة C، تُعيّن التعدادات أسماءً مترابطة لمجموعة من القيم الصحيحة. أما في لغة Swift ، فتتميز التعدادات بمرونة أكبر، ولا يلزم تحديد قيمة لكل حالة من حالات التعداد. إذا تم تحديد قيمة (تُسمى القيمة الأولية ) لكل حالة من حالات التعداد، فيمكن أن تكون هذه القيمة سلسلة نصية، أو حرفًا، أو قيمة من أي نوع عدد صحيح أو عدد عشري.
بدلاً من ذلك، يمكن لحالات التعداد تحديد القيم المرتبطة بها من أي نوع ليتم تخزينها مع كل قيمة حالة مختلفة، تمامًا كما تفعل الاتحادات أو المتغيرات في لغات أخرى. يمكن تعريف مجموعة مشتركة من الحالات ذات الصلة كجزء من تعداد واحد، ولكل منها مجموعة مختلفة من القيم من الأنواع المناسبة المرتبطة بها.
في لغة Swift، تُعتبر التعدادات نوعًا أساسيًا. فهي تتبنى العديد من الميزات التي كانت تدعمها الفئات فقط، مثل الخصائص المحسوبة لتوفير معلومات إضافية حول القيمة الحالية للتعداد، وأساليب النسخ لتوفير وظائف متعلقة بالقيم التي يمثلها التعداد. كما يمكن للتعدادات تعريف مُهيئات لتوفير قيمة أولية، ويمكن توسيعها لتوسيع وظائفها بما يتجاوز تنفيذها الأصلي؛ ويمكنها أيضًا التوافق مع البروتوكولات لتوفير وظائف قياسية.
enum CardSuit { case clubs case diamonds case hearts case spades }على عكس لغتي C و Objective-C ، لا تُعيّن قيمة عددية افتراضية لحالات التعداد في Swift عند إنشائها. ففي مثال CardSuit المذكور أعلاه، لا تُساوي أوراق النوادي والماس والقلوب والبستوني ضمنيًا 0 و1 و2 و3 على التوالي. بل تُمثّل حالات التعداد المختلفة قيمًا مستقلة تمامًا، بنوع مُحدّد صراحةً هو CardSuit.
يمكن أن تظهر حالات متعددة في سطر واحد، مفصولة بفواصل:
enum CardSuit { case club , diamonds , hearts , spades }عند العمل مع التعدادات التي تخزن قيمًا أولية من نوع عدد صحيح أو سلسلة نصية، لا يحتاج المرء إلى تعيين قيمة أولية بشكل صريح لكل حالة لأن Swift سيقوم بتعيين القيم تلقائيًا.
على سبيل المثال، عند استخدام الأعداد الصحيحة للقيم الأولية، تكون القيمة الضمنية لكل حالة أكبر بواحد من الحالة السابقة. إذا لم تُحدد قيمة للحالة الأولى، فإن قيمتها تساوي صفرًا. في مثال CardSuit، يمكن ترقيم المجموعات بدءًا من 1 بكتابة:
enum CardSuit { case clubs = 1 , diamonds , hearts , spades }تايب سكريبت
يضيف TypeScript نوع بيانات "enum" إلى JavaScript.
enum CardSuit { Clubs , Diamonds , Hearts , Spades };var c : CardSuit = CardSuit . Diamonds ;بشكل افتراضي، يتم ترقيم عناصر التعداد بدءًا من 0؛ ويمكن تجاوز ذلك عن طريق تعيين قيمة العنصر الأول:
enum CardSuit { Clubs = 1 , Diamonds , Hearts , Spades };var c : CardSuit = CardSuit . Diamonds ;يمكن ضبط جميع القيم:
enum CardSuit { Clubs = 1 , Diamonds = 2 , Hearts = 4 , Spades = 8 };var c : CardSuit = CardSuit . Diamonds ;يدعم TypeScript ربط القيمة الرقمية باسمها. على سبيل المثال، هذا يعثر على اسم القيمة 2:
enum CardSuit { Clubs = 1 , Diamonds , Hearts , Spades };var suitName : string = CardSuit [ 2 ];تنبيه ( اسم البدلة )؛بايثون
تمت إضافة وحدة enumنمطية إلى مكتبة بايثون القياسية في الإصدار 3.4. وهي تقدم الفئة Enumالتي يمكن توسيعها لتعريف الأنواع المعدودة.
من enum استورد Enumفئة CardSuit ( تعداد ): CLUBS : عدد صحيح = 1 DIAMONDS : عدد صحيح = 2 HEARTS : عدد صحيح = 3 SPADES : عدد صحيح = 4يوجد أيضًا واجهة برمجة تطبيقات وظيفية لإنشاء تعدادات بفهارس مُولّدة تلقائيًا (تبدأ برقم واحد):
البطاقات : Enum = Enum ( "البطاقات" , "النوادي، الماس، القلوب، البستوني" )لا تفرض تعدادات بايثون صحة دلالية (المقارنة غير ذات المعنى مع تعداد غير متوافق تُرجع دائمًا القيمة False بدلاً من إثارة خطأ TypeError ):
اللون : تعداد = تعداد ( "اللون" ، "أحمر أخضر أزرق" ) الشكل : تعداد = تعداد ( "الشكل" ، [ "دائرة" ، "مثلث" ، "مربع" ، "سداسي" ])دالة has_vertices ( shape : Enum ) -> bool : return shape != Shape . CIRCLEإذا كان __name__ يساوي "__main__" : has_vertices ( Color . GREEN ) # يُخرج "True"دارت
تدعم لغة دارت أبسط أشكال التعدادات ولها بنية نحوية مشابهة للغات الأخرى التي تدعم التعدادات.
enum CardSuit {النوادي ،الألماس ،قلوب ،البستوني}void main () {CardSuit card = CardSuit . Clubs ;// يستخدم Dart عامل التشغيل "switch" لمطابقة قيمة التعداد مع الناتج المطلوب.التبديل ( البطاقة ) {حالة أوراق اللعب . النوادي: {print ( "Clubs" );}استراحة ؛حالة CardSuit . Diamonds: {print ( "الماس" );}استراحة ؛حالة CardSuit . القلوب: {print ( "Hearts" );}استراحة ؛حالة CardSuit . Spades: {print ( "Spades" );}استراحة ؛تقصير : {اطبع ( "غير معروف" );}استراحة ؛}}لاحظ أنه قبل إصدار Dart 3، [ 14 ] لم يكن عامل التبديل يضمن اكتمال الحالات. هذا يعني أنه إذا حذفت حالة واحدة، فلن يُظهر المُصرّف خطأً.
لغات برمجة أخرى
كوبول
في لغة كوبول، المتغير الشرطي هو متغير عادي يحتوي على حقول فرعية من المستوى 88، تُعرف باسم أسماء الشروط. يجب أن يحتوي كل اسم شرطي على عبارة VALUE. يمكن لعبارة VALUE الخاصة بعبارة الشرط أن تحدد قيمة واحدة أو قائمة من القيم.
فورتران
قدّمت لغة فورتران 2003 المُعدِّدات لتحقيق التوافق مع لغة سي؛ لذا، فإن دلالاتها مشابهة لدلالات لغة سي، وكما هو الحال في لغة سي، فإن قيم المُعدِّد هي أعداد صحيحة فقط، ولا يتم إجراء أي فحص إضافي للأنواع. يمكن كتابة مثال لغة سي المذكور أعلاه بلغة فورتران كما يلي:
enum , bind ( C ) enumerator :: CLUBS = 1 , DIAMONDS = 2 , HEARTS = 4 , SPADES = 8 end enumأضافت لغة فورتران 2023 نوع تعداد حقيقي. تُرتّب القيم تسلسليًا وفقًا للمواصفات. تدعم الدوال المضمنة intالتعدادات . كما تتوفر hugeالدوال nextالأخرى .previous
نوع التعداد :: أيام_الأسبوع المُعَدِّد :: الاثنين ، الثلاثاء ، الأربعاء ، الخميس ، الجمعة المُعَدِّد :: السبت ، الأحد نهاية نوع التعدادنوع ( أيام_الأسبوع ) :: يوم : إذا ( يوم == الأربعاء ) فاطبع * ، 'يوم الأربعاء' نهاية إذا : حدد حالة ( يوم ) حالة ( الاثنين : الجمعة ) اطبع * ، 'يوم من أيام الأسبوع' حالة ( السبت ، الأحد ) اطبع * ، 'عطلة نهاية الأسبوع' نهاية التحديدعائلة مايكروسوفت فيجوال بيسك
| فيجوال بيسك (الكلاسيكي) و VBA | VB.NET | VBScript |
|---|---|---|
تعداد أوراق اللعب ' نوادي تبدأ من الصفر، ماس ، قلوب ، بستوني نهاية التعدادSub EnumExample () Dim suit As CardSuit suit = Diamonds MsgBox suit End Subيتم تعيين نوع البيانات " " تلقائيًا | تعداد أوراق اللعب : النوادي ، الماس، القلوب، البستوني ، نهاية التعدادSub EnumExample ( ) Dim suit As CardSuit suit = CardSuit.Diamonds MessageBox.show ( suit ) End Sub | غير متوفر |
التلعثم
تستخدم لغة Common Lisp مُحدِّد نوع العضو، على سبيل المثال،
( deftype cardsuit () ' ( member club diamond heart spade ))ينص هذا على أن الكائن من نوع أوراق اللعب إذا كان #'eqlمن فئة النادي أو الماس أو القلب أو البستوني. مع ذلك، فإن مُحدد نوع العضو غير صالح كمُحدد لمعاملات نظام كائنات Common Lisp(eql atom) (CLOS). بدلاً من ذلك ، يمكن استخدام مُحدد نوع العضو، وهو مُكافئ لـ (member atom)(أي أنه لا يمكن تحديد سوى عضو واحد من المجموعة باستخدام مُحدد نوع العضو، ومع ذلك، يمكن استخدامه كمُحدد لمعاملات CLOS). بعبارة أخرى، لتعريف طرق لتغطية نوع مُعدّد، يجب تعريف طريقة لكل عنصر مُحدد من هذا النوع.
بالإضافة إلى ذلك،
( deftype finite-element-set-type ( &rest elements ) ` ( member ,@ elements ))يمكن استخدامها لتعريف أنواع تعداد عشوائية في وقت التشغيل. على سبيل المثال
( مجموعة العناصر المحدودة - نادي، ماس، قلب، بستوني )سيشير ذلك إلى نوع مكافئ للتعريف السابق لرمز البطاقة، كما كان سيتم استخدامه ببساطة.
( نادي الأعضاء الماسي القلب البستوني )لكن قد يكون أقل إرباكاً فيما يتعلق بالوظيفة #'memberلأسباب أسلوبية.
نوع البيانات الجبرية في البرمجة الوظيفية
في لغات البرمجة الوظيفية المنتمية إلى سلالة ML (مثل Standard ML (SML) و OCaml و Haskell )، يمكن استخدام نوع بيانات جبري ذي مُنشئات صفرية فقط لتنفيذ نوع مُعدّد. على سبيل المثال (في صيغة توقيعات SML):
نوع البيانات cardsuit = Clubs | Diamonds | Hearts | Spades نوع البطاقة = { suit : cardsuit ; value : int } قيمة اليد : قائمة البطاقات قيمة الورقة الرابحة : cardsuitفي هذه اللغات، يكون تمثيل الأعداد الصحيحة الصغيرة مخفيًا تمامًا عن المبرمج، إن وُجد هذا التمثيل في التطبيق. مع ذلك، تحتوي لغة هاسكل على Enumفئة أنواع يمكن للنوع اشتقاقها أو تطبيقها للحصول على ربط بين النوع و Int.
قواعد البيانات
تدعم بعض قواعد البيانات أنواع البيانات المُعدّدة مباشرةً. يوفر MySQL نوعًا مُعدّدًا ENUMبقيم مسموح بها مُحددة كسلاسل نصية عند إنشاء جدول. تُخزّن القيم كمؤشرات رقمية، حيث تُخزّن السلسلة الفارغة كـ 0، والقيمة الأولى كـ 1، والقيمة الثانية كـ 2، وهكذا. يمكن تخزين القيم واسترجاعها كمؤشرات رقمية أو كقيم نصية. [ 15 ]
مثال:
إنشاء جدول القمصان ( الاسم VARCHAR ( 40 )، الحجم ENUM ( 'صغير جدًا' ، 'صغير' ، 'متوسط' ، 'كبير' ، 'كبير جدًا' ) )؛مخطط JSON
يمكن تعريفها في مخطط JSON باستخدام الكلمة المفتاحية "enum". [ 16 ]
{ "$schema" : "https://json-schema.org/draft/2020-12/schema" , "type" : "object" , "properties" : { "cardsuit" : { "type" : "string" , "enum" : [ "Clubs" , "Diamonds" , "Hearts" , "Spades" ] } }, "required" : [ "cardsuit" ] }مخطط XML
يدعم مخطط XML الأنواع المُعدّدة من خلال جانب التعداد المستخدم لتقييد معظم أنواع البيانات الأولية مثل السلاسل النصية.
<xs:element name= "cardsuit" > <xs:simpleType> <xs:restriction base= "xs:string" > <xs:enumeration value= "Clubs" /> <xs:enumeration value= "Diamonds" /> <xs:enumeration value= "Hearts" /> <xs:enumeration value= "Spades" /> </xs:restriction> </xs:simpleType> </xs:element>انظر أيضاً
ملحوظات
مراجع
- ↑ واندر، كوستا. "الطريق إلى الجحيم: تعدادات C++ وحقول البت › واندر لايرسون كوستا" . walac.github.io . تم الاطلاع عليه بتاريخ 26 سبتمبر 2025 .
- ↑ "بيانات وخصائص الحساب المشفر" (ملف PDF) . مرجع لغة Enterprise PL/I لنظام التشغيل z/OS 6.2 (ملف PDF) . شركة IBM . 2025. الصفحات 28-29 . SC31-5716-00 . تاريخ الاسترجاع: 8 يوليو 2025 .
- ↑ كيرنيغان، برايان دبليو .؛ ريتشي، دينيس إم. (فبراير 1978). لغة البرمجة سي ( الطبعة الأولى). إنجلوود كليفس، نيوجيرسي : برنتيس هول . ISBN 0-13-110163-3.
- ↑ "WG14-N3030 : تحسينات على عمليات التعداد" . 2022-07-19.
- ↑ مايكروسوفت ليرن (8 يناير 2024). "فئة System.Enum" . learn.microsoft.com . مايكروسوفت ليرن.
- ↑ "طريقة Enum.HasFlag(Enum) (النظام)" . learn.microsoft.com . تم الاطلاع عليه بتاريخ 6 ديسمبر 2024 .
- ↑ أوباسانجو، دار (2007). "مقارنة بين لغة برمجة سي شارب من مايكروسوفت ولغة برمجة جافا من صن مايكروسيستمز" . مؤرشف من الأصل بتاريخ 10 سبتمبر 2012. تم الاطلاع عليه بتاريخ 6 سبتمبر 2012.
في جافا، تُعدّ الأنواع المُعدّدة فئةً كاملةً، ما يعني أنها آمنة من حيث النوع ويمكن توسيعها بإضافة طرق أو حقول أو حتى تطبيق واجهات. أما في سي شارب، فالنوع المُعدّد هو مجرد اختصار برمجي لنوع صحيح (عادةً ما يكون int)، ما يعني أنه لا يمكن توسيعه وليس آمنًا من حيث النوع.
{{cite web}}: CS1 maint: bot: حالة عنوان URL الأصلي غير معروفة ( رابط ) - ^ جرونتز، دومينيك، بروفيسور د. (2005-04-08). “جافا 5: ترويض النمر: السكر النحوي” (بالألمانية). Fachhochschule أرجاو، نوردويستشفايز. مؤرشفة من الأصلي بتاريخ 2007-01-07 . تم الاسترجاع 2012/09/10 .
Enumerationen sind die heimlichen Sieger von Java 1.5. بعد إجراء تحسينات كبيرة خلال Sun، تظهر التعدادات في Java بشكل فائق ويمكن أن يتم تنفيذها بسهولة دون الحاجة إلى إدخالها. يمكن أن يكون التعداد البسيط في السنوات الماضية بمثابة تعداد صحيح لفن خاص من الفصل، وهو تعداد محدد. …
يمكن أن أتمكن من استخدام برامج أخرى مثل C/C++ وC# في Gleichheitszeichen التي لا يمكنها تحقيق النجاح.
{{cite web}}صيانة CS1: أسماء متعددة: قائمة المؤلفين ( رابط ) عنوان URL بديل مؤرشف بتاريخ 27-05-2013 في Wayback Machine - ↑ تروتر، كريستوف (2011-08-04). "الاختصار النحوي (C#): Enum" . CSTrüter. مؤرشف من الأصل في 2007-01-07 . تم الاسترجاع في 2012-09-10 .
// لا يقوم enum المصمم بشكل سيئ بهذا... من الواضح (كما هو الحال مع أي شيء آخر)، أنه يمكننا إساءة استخدام هذا الاختصار، مما يؤدي إلى نظام يعاني من خلل في البرمجة. ... بما أن النوع الأساسي لـ enum هو عدد صحيح (يمكن أيضًا استخدام أنواع عددية صحيحة أخرى)، فقد يؤدي ذلك إلى بعض المشكلات المثيرة للاهتمام عند استخدام enum كعلامات بت عبر عوامل التشغيل على مستوى البت.
{{cite web}}: CS1 maint: bot: حالة عنوان URL الأصلي غير معروفة ( رابط ) - ↑ "Effective Go" . golang.org . مؤلفو لغة Go . تم الاطلاع عليه بتاريخ 13-05-2014 .
- ↑ "ويكي Go: Iota - لغة برمجة Go" . go.dev . تاريخ الاسترجاع: 15-05-2025 .
يُستخدم مُعرّف iota في لغة Go في تعريفات const لتبسيط تعريفات الأعداد المتزايدة. ولأنه يُمكن استخدامه في التعبيرات، فإنه يُوفر عمومية تتجاوز نطاق التعدادات البسيطة.
- ↑ "أنواع التعداد" . أوراكل . تم الاسترجاع في 2013-12-05 .
- ↑ بلوخ، جوشوا ( 2008). جافا الفعالة ( الطبعة الثانية). أبر سادل ريفر، نيوجيرسي: أديسون-ويسلي. ص 158. ISBN 978-0-321-35668-0.
- ↑ "language/accepted/3.0/patterns/exhaustiveness.md at main · dart-lang/language" . GitHub . مؤرشف من الأصل بتاريخ 2024-12-03 . تم الاطلاع عليه بتاريخ 2025-06-20 .
- ↑ "MySQL :: دليل مرجعي لـ MySQL 8.0 :: 11.3.5 نوع ENUM" . dev.mysql.com . تم الاطلاع عليه بتاريخ 19 سبتمبر 2021 .
- ↑ رايت، أوستن. "التحقق من صحة مخطط JSON: مفردات للتحقق من صحة بنية JSON" . json-schema.org . تم الاطلاع عليه بتاريخ 22 يونيو 2025 .
روابط خارجية
- أنواع البيانات المُعدّدة في لغة C/C++ (مؤرشفة بتاريخ 3 أبريل 2008 على موقع Wayback Machine)
- أنواع التعداد في لغة C#
- أنواع البيانات المُعدّدة في جافا
- أنواع البيانات المُعدّدة في MySQL
- أنواع البيانات المُعدّدة في Obix
- أنواع البيانات المُعدّدة في لغة PHP
- أنواع البيانات المُعدّدة في لغة Swift
- أنواع البيانات المُعدّدة في XML
- أنواع التعداد في فيجوال بيسك
- أنواع البيانات
- نظرية الأنواع
