نوع الاتحاد

في علوم الحاسوب ، يُعرف الاتحاد بأنه قيمة يمكن أن تتخذ أيًا من التمثيلات أو التنسيقات المتعددة ضمن نفس مساحة الذاكرة ، أو متغير يمكنه استيعاب بنية بيانات كهذه. تدعم بعض لغات البرمجة نوع الاتحاد لهذا النوع من البيانات . بعبارة أخرى، يحدد نوع الاتحاد الأنواع المسموح بتخزينها في مثيلاته، مثل `float` floatو`int` int. على عكس السجل ، الذي يمكن تعريفه ليحتوي على كل من عدد عشري وعدد صحيح، لا يمكن للاتحاد استيعاب سوى نوع واحد في كل مرة.

يمكن تصور الاتحاد على أنه جزء من الذاكرة يُستخدم لتخزين متغيرات من أنواع بيانات مختلفة. عند تعيين قيمة جديدة لحقل ما، تُستبدل البيانات الموجودة بالبيانات الجديدة. لا يمتلك حيز الذاكرة الذي يخزن القيمة نوعًا جوهريًا (باستثناء البايتات أو الكلمات )، ولكن يمكن التعامل مع القيمة كواحد من عدة أنواع بيانات مجردة ، بحيث يكون لها نوع القيمة التي كُتبت آخر مرة في حيز الذاكرة.

في نظرية الأنواع ، يكون للاتحاد نوع مجموع ؛ وهذا يتوافق مع الاتحاد المنفصل في الرياضيات.

بحسب اللغة والنوع، قد تُستخدم قيمة الاتحاد في بعض العمليات، مثل الإسناد والمقارنة للتحقق من التساوي، دون معرفة نوعها المحدد. بينما قد تتطلب عمليات أخرى هذه المعرفة، إما من خلال معلومات خارجية، أو باستخدام اتحاد مُوسَم .

النقابات غير المصنفة

نظراً لمحدودية استخدامها، لا تُوفّر الاتحادات غير الموسومة عادةً إلا في اللغات غير المُصنّفة أو بطريقة غير آمنة من حيث النوع (كما في لغة C ). وتتميز هذه الاتحادات عن الاتحادات الموسومة البسيطة بعدم حاجتها إلى مساحة لتخزين علامة نوع البيانات.

يُستمد اسم "الاتحاد" من التعريف الرسمي للنوع. إذا اعتُبر نوعٌ ما مجموعة جميع القيم التي يمكن أن يأخذها، فإن نوع الاتحاد هو ببساطة الاتحاد الرياضي لأنواعه المكونة له، إذ يمكنه أن يأخذ أي قيمة يمكن أن يأخذها أي حقل من حقوله. كذلك، ولأن الاتحاد الرياضي يتجاهل القيم المكررة، فإذا كان بإمكان أكثر من حقل في الاتحاد أن يأخذ قيمة مشتركة واحدة، فمن المستحيل تحديد الحقل الذي كُتبت فيه القيمة الأخيرة من القيمة وحدها.

مع ذلك، تتمثل إحدى وظائف الاتحاد البرمجية المفيدة في ربط عناصر البيانات الأصغر بعناصر أكبر لتسهيل التعامل معها. فعلى سبيل المثال، يمكن لبنية بيانات تتكون من 4 بايتات وعدد صحيح 32 بت أن تُشكّل اتحادًا مع عدد صحيح غير مُوقّع 64 بت، وبالتالي يسهل الوصول إليها لأغراض المقارنة وغيرها.

الاتحادات في لغات البرمجة المختلفة

ALGOL 68

تستخدم لغة ALGOL 68 الاتحادات الموسومة، وتستخدم عبارة case لتمييز واستخراج نوع المكون أثناء التشغيل. يُعامل الاتحاد الذي يحتوي على اتحاد آخر على أنه مجموعة جميع احتمالات مكوناته، وإذا اقتضى السياق ذلك، يُحوّل الاتحاد تلقائيًا إلى الاتحاد الأوسع. يمكن أن يحتوي الاتحاد صراحةً على قيمة فارغة، وهو ما يمكن تمييزه أثناء التشغيل. مثال على ذلك:

mode node = union ( real , int , string , void ); node n := "abc"; case n in ( real r): print(("real:", r)), ( int i): print(("int:", i)), ( سلسلة نصية s): print(("سلسلة نصية:", s)), ( void ): print(("void:", "EMPTY")), out print(("?:", n)) esac

تم اشتقاق بنية نوع الاتحاد في لغة C/C++ ومفهوم التحويلات من لغة ALGOL 68، وإن كان ذلك في شكل غير موسوم. [ 1 ]

لغة C/C++

في لغتي C و C++ ، تُعبّر الاتحادات غير الموسومة بشكل مشابه تقريبًا للهياكل ( structs )، باستثناء أن كل عنصر بيانات يقع في نفس عنوان الذاكرة. وكما هو الحال في الهياكل، لا يشترط أن تكون عناصر البيانات قيمًا أولية، بل قد تكون هياكل أو حتى اتحادات أخرى. تسمح لغة C++ (منذ C++11 ) أيضًا بأن يكون عنصر البيانات أي نوع يمتلك مُنشئًا/مُدمِّرًا كاملًا و/أو مُنشئ نسخ، أو مُعامل إسناد نسخ غير تافه. على سبيل المثال، من الممكن أن يكون لدينا سلسلة C++ القياسية كعنصر في اتحاد.

يُستخدم الاتحاد بشكل أساسي للسماح بالوصول إلى موقع مشترك بواسطة أنواع بيانات مختلفة، مثل الوصول إلى مدخلات/مخرجات الأجهزة، ومشاركة حقول البت والكلمات، أو تورية الأنواع . كما يُمكن للاتحادات توفير تعدد الأشكال على مستوى منخفض . مع ذلك، لا يوجد فحص للأنواع، لذا يقع على عاتق المبرمج التأكد من الوصول إلى الحقول المناسبة في سياقات مختلفة. عادةً ما يتم تحديد الحقل ذي الصلة لمتغير الاتحاد بناءً على حالة متغيرات أخرى، ربما في بنية مُحيطة.

تستخدم إحدى طرق البرمجة الشائعة في لغة C الاتحادات لتنفيذ ما يُسمى في لغة C++ بـ "القراءة reinterpret_castمن حقل"، وذلك عن طريق إسناد قيمة إلى أحد حقول الاتحاد وقراءة قيمة من حقل آخر، كما هو الحال في التعليمات البرمجية التي تعتمد على التمثيل الأولي للقيم. ومن الأمثلة العملية على ذلك طريقة حساب الجذور التربيعية باستخدام تمثيل IEEE . مع ذلك، لا يُعد هذا استخدامًا آمنًا للاتحادات بشكل عام.

تتشابه مُحدِّدات البنية والاتحاد في الشكل. [...] حجم الاتحاد كافٍ لاحتواء أكبر عناصره. يمكن تخزين قيمة عنصر واحد على الأكثر في كائن الاتحاد في أي وقت. يشير مؤشر إلى كائن الاتحاد، بعد تحويله بشكل مناسب، إلى كل عنصر من عناصره (أو إلى الوحدة التي يوجد بها إذا كان العنصر حقل بت)، والعكس صحيح.

ANSI/ISO 9899:1990 (معيار ANSI C) القسم 6.5.2.1

اتحاد مجهول

في لغتي C++ و C11 ، وكامتداد غير قياسي في العديد من المترجمات، يمكن أن تكون الاتحادات مجهولة المصدر. لا تحتاج عناصر بياناتها إلى مرجع، بل يتم الوصول إليها مباشرةً. وتخضع هذه الاتحادات لبعض القيود مقارنةً بالاتحادات التقليدية: ففي C11، يجب أن تكون عضوًا في بنية أو اتحاد آخر، [ 2 ] وفي C++، لا يمكن أن تحتوي على دوال أو محددات وصول.

لا يكفي حذف جزء اسم الصنف من الصيغة لجعل الاتحاد اتحادًا مجهولًا. لكي يُعتبر الاتحاد اتحادًا مجهولًا، يجب ألا يُصرّح عن أي كائن. مثال:

union { float f ; uint32_t d ; // يفترض أن يكون عرض float هو 32 بت };f = 3.14f ; printf ( "التمثيل الست عشري لـ 3.14f: %x \n " , u . d );

تُعدّ الاتحادات المجهولة مفيدة أيضًا في structتعريفات لغة C لتوفير إحساس بمساحة الأسماء. [ 3 ]

اتحاد شفاف

في مُجمِّعات مثل GCC وClang وIBM XL C لنظام AIX، transparent_unionتتوفر سمة لأنواع الاتحاد. يمكن تحويل الأنواع المُضمنة في الاتحاد بشفافية إلى نوع الاتحاد نفسه في استدعاء دالة، شريطة أن تكون جميع الأنواع بنفس الحجم. وهي مُخصصة بشكل أساسي للدوال ذات واجهات المعاملات المتعددة، وهو استخدام فرضته امتدادات يونكس المبكرة وإعادة التوحيد القياسي اللاحقة. [ 4 ]

كوبول

في لغة كوبول ، تُعرَّف عناصر البيانات الموحدة بطريقتين. الأولى تستخدم الكلمة المفتاحية RENAMES (المستوى 66)، والتي تُضيف عنصر بيانات أبجدي رقمي ثانٍ إلى نفس موقع الذاكرة الذي يشغله عنصر البيانات السابق. في مثال الكود أدناه، يُعرَّف عنصر البيانات PERSON-REC كمجموعة تحتوي على مجموعة أخرى وعنصر بيانات رقمي. يُعرَّف PERSON-DATA كعنصر بيانات أبجدي رقمي يُعيد تسمية PERSON-REC ، مع اعتبار بايتات البيانات المتبقية داخله بيانات نصية.

 01 سجل الشخص . 05 اسم الشخص . 10 اسم الشخص الأخير صورة X(12) . 10 اسم الشخص الأول صورة X(16) . 10 اسم الشخص الأوسط صورة X. 05 معرف الشخص صورة 9(9) عدد عشري مضغوط .  01 بيانات الشخص تعيد تسمية سجل الشخص .

الطريقة الثانية لتعريف نوع الاتحاد هي استخدام الكلمة المفتاحية REDEFINES . في مثال الكود أدناه، يُعرَّف عنصر البيانات VERS-NUM على أنه عدد صحيح ثنائي مكون من بايتين يحتوي على رقم الإصدار. ويُعرَّف عنصر بيانات ثانٍ VERS-BYTES على أنه متغير أبجدي رقمي مكون من حرفين. بما أن العنصر الثاني مُعاد تعريفه على العنصر الأول، فإن العنصرين يشتركان في نفس العنوان في الذاكرة، وبالتالي يشتركان في نفس بايتات البيانات الأساسية. يُفسِّر العنصر الأول بايتات البيانات كقيمة ثنائية، بينما يُفسِّرها العنصر الثاني كقيم حرفية.

 01 VERS-INFO . 05 VERS-NUM PIC S9(4) COMP . 05 VERS-BYTES PIC X(2) REDEFINES VERS-NUM

باسكال

في لغة باسكال ، توجد طريقتان لإنشاء الاتحادات. الأولى هي الطريقة القياسية باستخدام سجل متغير. أما الثانية فهي طريقة غير قياسية لتعريف متغير على أنه مطلق، أي أنه يُوضع في نفس موقع الذاكرة مع متغير آخر أو في عنوان مطلق. مع أن جميع مُجمِّعات باسكال تدعم السجلات المتغيرة، إلا أن بعضها فقط يدعم المتغيرات المطلقة.

لأغراض هذا المثال، فإن ما يلي كلها أنواع أعداد صحيحة: يتكون البايت من 8 بتات، والكلمة من 16 بتًا، والعدد الصحيح من 32 بتًا.

يوضح المثال التالي الصيغة المطلقة غير القياسية:

var A : عدد صحيح ; B : مصفوفة [ 1 .. 4 ] من بايت مطلق A ; C : عدد صحيح مطلق 0 ;

في المثال الأول، يرتبط كل عنصر من عناصر المصفوفة B بأحد البايتات المحددة للمتغير A. في المثال الثاني، يتم تعيين المتغير C إلى عنوان الجهاز المحدد 0.

في المثال التالي، يحتوي السجل على متغيرات، بعضها يشترك في نفس الموقع مع متغيرات أخرى:

نوع الشكل = ( دائرة ، مربع ، مثلث ) ؛ الأبعاد = سجل الحالة الشكل : شكل الدائرة : ( القطر : حقيقي ) ؛ المربع : ( العرض : حقيقي ) ؛ المثلث : ( الضلع : حقيقي ؛ الزاوية 1 ، الزاوية 2 : 0 .. 360 ) نهاية ؛

PL/I

في لغة PL/I، كان المصطلح الأصلي للاتحاد هو "خلية " [ 5 ] ، والذي لا يزال مقبولًا كمرادف للاتحاد من قِبل العديد من المترجمات. يُشبه تعريف الاتحاد تعريف البنية، حيث تشغل العناصر الموجودة في نفس المستوى داخل تعريف الاتحاد نفس مساحة التخزين. يمكن أن تكون عناصر الاتحاد من أي نوع بيانات، بما في ذلك البنى والمصفوفات. [ 6 ] : الصفحات 192-193. هنا، يشغل كل من vers_num وvers_bytes نفس مواقع التخزين.

1 vers_info union , 5 vers_num fixed binary , 5 vers_bytes pic '(2)A';

يُعدّ السمة DEFINED بديلاً عن تعريف الاتحاد، إذ تسمح بتعريفات بديلة للتخزين، ولكن يجب أن تتطابق أنواع بيانات المتغيرات الأساسية والمُعرَّفة. [ 6 ] : ص 289-293

الصدأ

تُنفّذ لغة Rust كلاً من الاتحادات الموسومة وغير الموسومة. في Rust، تُنفّذ الاتحادات الموسومة باستخدام الكلمة enumالمفتاحية `enum`. على عكس الأنواع المُعدّدة في معظم اللغات الأخرى، يمكن أن تحتوي متغيرات `enum` في Rust على بيانات إضافية على شكل صف أو بنية، مما يجعلها اتحادات موسومة وليست مجرد أنواع مُعدّدة بسيطة. [ 7 ]

يدعم Rust أيضًا الاتحادات غير الموسومة باستخدام الكلمة unionالمفتاحية. يكون تخطيط الذاكرة للاتحادات في Rust غير مُحدد افتراضيًا، [ 8 ]#[repr(C)] ولكن سيتم تخطيط الاتحاد الذي يحتوي على السمة في الذاكرة تمامًا مثل الاتحاد المكافئ في C. [ 9 ] لا يمكن قراءة حقول الاتحاد إلا داخل دالة unsafeأو كتلة، حيث لا يستطيع المُصرّف ضمان أن تكون البيانات الموجودة في الاتحاد صالحة لنوع الحقل؛ إذا لم يكن الأمر كذلك، فسيؤدي ذلك إلى سلوك غير مُحدد . [ 10 ]

بناء الجملة والمثال

ج

في لغة C، يكون بناء الجملة كالتالي:

اتحاد < الاسم > { < نوع البيانات > < اسم المتغير الأول > ؛ < نوع البيانات > < اسم المتغير الثاني > ؛ ... < نوع البيانات > < اسم المتغير النوني > ؛ } < اسم متغير الاتحاد > ؛

يمكن أن يكون الهيكل أيضاً عضواً في اتحاد، كما يوضح المثال التالي:

اتحاد { بنية { عدد صحيح أ ؛ عدد عشري ب ؛ حرف ج ؛ } متغير ثابت ؛ عدد صحيح د ؛ } متغير غير ثابت ؛

يُعرّف هذا المثال متغيرًا uvarعلى أنه اتحاد يحتوي على عضوين، وبنية تسمى svar(والتي بدورها تحتوي على ثلاثة أعضاء)، ومتغير عدد صحيح يسمى d.

قد تحدث عمليات الاتحاد داخل الهياكل والمصفوفات، والعكس صحيح:

#حدد N 10000struct { int flags ; char * name ; int utype ; union { int ival ; float fval ; char * sval ; } u ; } symtab [ N ];

ivalيُشار إلى الرقم بـ symtab[i].u.ivalوإلى السلسلة svalبـ symtab[i].u.sval.

لغة سي++

تدعم لغة C++ الاتحادات مثل لغة C، لكن استخدامها بأمان في C++ صعب. وللغرضين الرئيسيين للاتحادات، توفر لغة C++ بدائل مناسبة: [ 11 ] [ 12 ]

  1. يمكن إجراء تحويل الأنواع عبر الاتحادات مثل تحويل قيمة الفاصلة العائمة إلى تمثيلها الثنائي كعدد صحيح باستخدام .union{uint32_tx;floaty;}reinterpret_cast
  2. بالنسبة للأنواع غير القابلة للاستبدال (غير POD) ، تتطلب الاتحادات إنشاءً وتدميرًا صريحين، مما يجعل استخدامها بأمان أمرًا معقدًا. std::variantأما `<input type="width">`، الذي تم تقديمه في C++17 ، فيعمل كاتحاد مُوسَم ، متجنبًا هذا التعقيد.
#include <cmath> #include <cstdint> #include <stdexcept> #include <variant>uint32_t encode_float_as_binary ( float f ) noexcept { return reinterpret_cast < uint32_t &> ( f ); }bool is_integral ( std :: variant < int , float >& v ) { if ( int * _ = std :: get_if <int> ( & v )) { return true ; } else if ( float * f = std :: get_if <float> ( & v )) { return std :: modff ( * f , nullptr ) == 0 ; } throw std :: invalid_argument ( " إدخال متغير غير صالح! " ) ; }

سي شارب

حتى الإصدار 15 من لغة C#، لم تكن هناك أنواع اتحادية في لغة C#. وكانت أقرب طريقة لمحاكاتها هي من خلال السجلات ومطابقة الأنماط .

namespace Wikipedia.Examples ;باستخدام النظام ؛سجل مجرد Shape ؛ سجل دائرة ( نصف قطر مزدوج ) : Shape ؛ سجل مستطيل ( عرض مزدوج ، ارتفاع مزدوج ) : Shape ؛public class Example { public static double Area ( Shape s ) => s switch { Circle c => Math . PI * c . Radius * c . Radius , Rectangle r => r . Width * r . Height , _ => throw new NotSupportedException () }; }

يمكن أيضًا محاكاتها بدقة باستخدام تخطيط منخفض المستوى. يوضح المثال التالي هذا النوع من الاتحاد، حيث تشغل الحقول نفس الذاكرة، ولكنه غير آمن من حيث النوع. يُفضل استخدامه لأغراض التوافق، والتسلسل، والمعالجة غير الآمنة.

باستخدام System.Runtime.InteropServices ؛// أقرب إلى اتحاد C IntFloatUnion { int i; float f; }; [StructLayout(LayoutKind.Explicit)] struct IntFloatUnion { [FieldOffset(0)] public int IntValue ;[FieldOffset(0)] public float FloatValue ; }

في C# 15، تم إدخال الاتحادات إلى اللغة، كما يمكن توضيحه بما يلي: [ 13 ]

فئة سجل عامة للسيارة ( سلسلة نصية ، طراز فئة سجل عامة للدراجة ( سلسلة نصية ، طراز فئة سجل عامة للحافلة ( سلسلة نصية، طراز مركبة النقابة العامة ( سيارة ، دراجة ، حافلة Vehicle car = new Car ( "Tesla Model 3" ) ; Console.WriteLine(car.Value ) ; // Car { Model = Tesla Model 3 }Vehicle bike = new Bicycle ( "Giant Escape 3" ); Console.WriteLine ( bike.Value ) ; // Bicycle { Model = Giant Escape 3 }Vehicle bus = new Bus ( " Volvo 9700" ) ; Console.WriteLine ( bus.Value ) ; // Bus { Model = Volvo 9700 }المركبة v = /* مركبة ما هنا */ ; سلسلة النموذج = v switch { سيارة c => c . النموذج , دراجة bk => b . النموذج , حافلة bs => bs . النموذج , };

قيمة defaultالاتحاد هي null، ولكن إذا كانت جميع الأنواع في الاتحاد غير قابلة للتصفير ، switchفلا داعي للتحقق من التعبير null.

جافا

لا توجد أنواع الاتحاد في لغة جافا، على الرغم من أنه يمكن محاكاتها إلى حد ما باستخدام الواجهات .

// يمكن اعتبار "الشكل" اتحادًا بين "الدائرة" و"المستطيل" // وأنواع أخرى تُنفذ "الشكل" // يمكننا تحديد ما هو موجود في الاتحاد بشكل صريح باستخدام واجهة مغلقة. تسمح الواجهة المغلقة " الشكل " بـ "الدائرة " و "المستطيل " {}record Circle ( double radius ) implements Shape {}record Rectangle ( double width , double height ) implements Shape {}class Example { double area ( Shape s ) { return switch ( s ) { case Circle ( double r ) -> Math . PI * r * r ; case Rectangle ( double w , double h ) -> w * h ; }; } }

يمكن أن يُعلن شرطٌ catchما عن اتحاد أنواع استثناءات متعددة. يشبه هذا التركيب تركيب أنواع الاتحاد في لغات أخرى، ولكنه لا يُدخل نوعًا جديدًا في الواقع. النوع الفعلي لمعامل الاستثناء هو النوع الفائق المشترك الأكثر تحديدًا من بين البدائل. لا يلتقط شرط catch إلا استثناءات الأنواع المُعلنة، ولا يلتقط أي فئات فرعية أخرى من النوع الفائق المشترك. [ 14 ]

class FooException extends RuntimeException { String name () { return "Foo" ; } }class BarException extends RuntimeException { String name () { return "Bar" ; } }void main ( ) { try { throw Math.random ( ) < 0.5 ? new FooException () : new BarException (); } catch ( FooException | BarException e ) { // e من النوع RuntimeException، وهو النوع الفائق المشترك بين FooException و BarException System.out.println ( e ) ; e.printStackTrace ( ); // System.out.println (e.name()); // نظرًا لعدم وجود دالة name() في RuntimeException، يفشل هذا في التجميع } }

PHP

تم تقديم أنواع الاتحاد في PHP 8.0. [ 15 ] يتم "وسم" القيم ضمنيًا بنوع بواسطة اللغة، ويمكن استردادها بواسطة "gettype()".

class Example { private int | float $foo ;public function squareAndAdd ( float | int $bar ) : int | float { return $bar ** 2 + $this -> foo ; } }

بايثون

تم تقديم دعم الكتابة في بايثون 3.5. [ 16 ] تم تقديم الصيغة الجديدة لأنواع الاتحاد في بايثون 3.10. [ 17 ]

من typing استورد الاتحادمثال على فئة : foo : int = 0# النمط القديم: def square_and_add ( self , bar : Union [ int , float ]) -> Union [ int , float ]: return bar ** 2 + self . foo# أسلوب جديد: def square_and_add ( self , bar : int | float ) -> int | float : return bar ** 2 + self . foo

تايب سكريبت

يدعم TypeScript أنواع الاتحاد. [ 18 ] تُصنّف القيم ضمنيًا بنوعٍ ما بواسطة اللغة، ويمكن استرجاعها باستخدام typeofاستدعاء للقيم الأولية ومقارنة instanceofلأنواع البيانات المعقدة. لا تحتاج الأنواع ذات الاستخدام المتداخل (مثل وجود دالة slice على كلٍ من السلاسل النصية والمصفوفات، وعمل عامل الجمع على كلٍ من السلاسل النصية والأرقام) إلى تضييق إضافي لاستخدام هذه الميزات.

دالة successor ( n : number | bigint ) : number | bigint { // الأنواع التي تدعم نفس العمليات لا تحتاج إلى تضييق return ++ n ; }دالة تعتمد على المعامل ( v : سلسلة نصية | مصفوفة سلاسل نصية | رقم ) { // يجب تحديد الأنواع المختلفة إذا ( v من نوع مصفوفة ) { // نفّذ شيئًا ما } وإلا إذا ( نوع ( v ) هو "سلسلة نصية" ) { // نفّذ شيئًا آخر } وإلا { // يجب أن يكون رقمًا } }

الصدأ

تستخدم الاتحادات الموسومة في لغة Rust الكلمة enumالمفتاحية، ويمكن أن تحتوي على متغيرات tuple و struct:

enum Foo { Bar ( i32 ), Baz { x : String , y : i32 }, }

تستخدم الاتحادات غير الموسومة في لغة Rust الكلمة unionالمفتاحية التالية:

اتحاد Foo { bar : i32 , baz : bool , }

تؤدي القراءة من حقول اتحاد غير موسوم إلى سلوك غير محدد إذا لم تكن البيانات الموجودة في الاتحاد صالحة كنوع الحقل، وبالتالي تتطلب unsafeكتلة:

let x = Foo { bar : 10 }; let y = unsafe { x . bar }; // سيؤدي هذا إلى تعيين قيمة y إلى 10، ولن ينتج عنه سلوك غير مُعرَّف. let z = unsafe { x . baz }; // ينتج عن هذا سلوك غير مُعرَّف، لأن القيمة المخزنة في x ليست قيمة منطقية صالحة.

مراجع

  1. ريتشي، دينيس م. (مارس 1993). "تطور لغة C" . نشرة ACM SIGPLAN . 28 (3): 201-208 . doi : 10.1145/155360.155580 . يدين نظام تركيب الأنواع الذي اعتمدته لغة C بالكثير للغة Algol 68، على الرغم من أنه ربما لم يظهر بالشكل الذي يرضي أنصار Algol. كان المفهوم الأساسي الذي استخلصته من Algol هو بنية الأنواع القائمة على الأنواع الذرية (بما في ذلك البنى)، والمُركبة في مصفوفات ومؤشرات (مراجع) ووظائف (إجراءات). كما كان لمفهوم الاتحادات والتحويلات في Algol 68 تأثير ظهر لاحقًا.
  2. "6.63 بنية غير مسماة وحقول الاتحاد" . تم الاسترجاع في 29-12-2016 .
  3. سيبنمان، كريس. "CUnionsForNamespaces" . utcc.utoronto.ca .
  4. "سمات النوع الشائعة: transparent_union" . باستخدام مجموعة مترجمات GNU (GCC) .
  5. شركة آي بي إم (مارس 1968). مواصفات لغة IBM System/360 PL/I (ملف PDF) . صفحة 52. تم الاطلاع عليه بتاريخ 22 يناير 2018 . 
  6. ١ ٢ شركة آي بي إم (ديسمبر ٢٠١٧). دليل لغة PL/I للمؤسسات لأنظمة z/OS و PL/I لأنظمة AIX و IBM Developer لأنظمة z و PL/I لأنظمة ويندوز (ملف PDF) . تم الاطلاع عليه بتاريخ ٢٢ يناير ٢٠١٨ .
  7. "كيفية تطبيق Rust للاتحادات الموسومة - بات شونيسي" . patshaughnessy.net . تم الاطلاع عليه بتاريخ 25-04-2023 .
  8. "أنواع الاتحاد - مرجع لغة رست" . doc.rust-lang.org . تم الاطلاع عليه بتاريخ 25-04-2023 .
  9. "تخطيط النوع - مرجع لغة رست" . doc.rust-lang.org . تم الاطلاع عليه بتاريخ 25-04-2023 .
  10. "الاتحادات - مرجع لغة رست" . doc.rust-lang.org . تم الاطلاع عليه بتاريخ 25-04-2023 .
  11. بانسيلا، ماريوس (2017). "استخدام std::variant كاتحاد آمن من حيث النوع". كتاب الطبخ الحديث لبرمجة C++ . دار نشر أورايلي . ISBN 9781786465184.
  12. "std::variant" . cppreference.com . مؤرشف من الأصل بتاريخ 11-10-2025 . تم الاطلاع عليه بتاريخ 16-12-2025 .
  13. بيل واغنر (2 أبريل 2026). "استكشف أنواع الاتحاد في لغة C# 15" . devblogs.microsoft.com . مايكروسوفت.
  14. جوسلينج، جيمس ؛ جوي، بيل ؛ ستيل، جاي ؛ براخا، جلعاد ؛ باكلي، أليكس؛ سميث، دانيال؛ بيرمان، جافين. "مواصفات لغة جافا. القسم 14.20: عبارة try" . تم الاطلاع عليه بتاريخ 22-04-2026 .
  15. كاروناراتني، أيش. "PHP 8.0: أنواع الاتحاد" . PHP.Watch . تم الاطلاع عليه بتاريخ 30 نوفمبر 2020 .
  16. "الكتابة - دعم تلميحات النوع - وثائق بايثون 3.9.7" . docs.python.org . تم الاطلاع عليه بتاريخ 8 سبتمبر 2021 .
  17. "PEP 604 -- السماح بكتابة أنواع الاتحاد كـ X | Y" . Python.org . تم الاطلاع عليه بتاريخ 8 سبتمبر 2021 .
  18. "دليل - الاتحادات وأنواع التقاطع" . www.typescriptlang.org . تم الاطلاع عليه بتاريخ 30 نوفمبر 2020 .