HeadlinesBriefing HeadlinesBriefing.com

طرق عامة في Go 1.27

Hacker News •
×

عندما قدمت Go 1.18 الجينيات في عام 2022، أحضرت معلمات نوع عامة للدوال والهياكل، لكنها استبعدت الطرق. مع إصدار Go 1.27، تمت إزالة هذا القيد الطويل الأمد. يمكن للطرق الآن تعريف معلماتها الخاصة بنوعها دون إضافتها إلى الهيكل المستقبل.

لماذا تم إدخال هذا التغيير؟ إذا كنت تريد إنشاء عقدة رسم بياني تحتفظ بقيمة عامة، فقد تنفذها بهذه الطريقة:

type Node[T any] struct {

value T

}

تخيل إضافة طريقة Map التي تحول عقدة من النوع T إلى عقدة من نوع آخر U. قبل Go 1.27، كنت مضطرًا لإضافة U مباشرة إلى هيكل Node نفسه:

type Node[T any, U any] struct {

value T

}

func (n *Node[T, U]) Map() Node[T, U] {

// ...

}

إضافة U إلى الهيكل نفسه تصميم سيء لأن U هو معلمة نوع خاصة بـ Map. على الرغم من أن الطرق الأخرى لن تستخدم U، إلا أنها لا تزال مطالبة بها في إعلاناتها. الحل الوحيد كان تنفيذ Map كدالة على مستوى الحزمة بدلاً من طريقة، لأن الدوال يمكنها تعريف معلماتها الخاصة بنوعها. لكن الطرق لا يمكنها، مما أدى إلى تصميمات API للكود غير المريحة والغير نموذجية. بدءًا من Go 1.27، يمكن تعريف U حصريًا على طريقة Map:

func (n *Node[T]) Map[U any]() Node[U] {

// ...

}

لماذا استغرق الأمر وقتًا طويلا؟ الإجابة تكمن في كيفية تنفيذ الجينيات في Go. يتعامل المترجم مع الجينيات في المقام الأول باستخدام التعددية (monomorphization)، مما يعني أنه سيقوم بإنشاء نسخة من الهياكل أو الدوال العامة لكل نوع محدد يتم استخدامه معه. لأنه في وقت ما، يجب تحويل المفهوم التجريدي للجينيات إلى رمز آل مباشر. ومع ذلك، يعمل نظام واجهات Go في وقت التشغيل. يتم حل النوع المحدد لقيمة تم تمريرها إلى معلمة الواجهة أثناء تشغيل البرنامج. هذه التوزيع الديناميكي يتعارض مع الجينيات التي تتم حلها في وقت الترجمة. فكر في ما سيحدث إذا أردنا الإعلان عن طريقتنا Map في واجهة:

type Mapper interface {

Map T any, U any U

}

لجعل هذا يعمل، سيحتاج وقت التشغيل إما إلى مترجم Just-In-Time لإنشاء رمز آل للأنواع المحددة على الطول، أو سيحتاج إلى إنشاء هذه النسخ لكل نوع ممكن مسبقًا، مما يؤدي إلى زيادة كبيرة في حجم الثنائي. في النهاية، قرر فريق Go فصل الطرق العامة عن الواجهات. تسمح Go 1.27 باستخدام الطرق العامة على الأنواع الملموسة، لكن ليس على الواجهات. هذا التمييز هو السبب في أن المثال أعلاه لن يتم تجميعه ولماذا استغرقت المناقشات حوله وقتًا طويلاً.

المصدر: Hacker News · لخّصه HeadlinesBriefing