هل Go موجه للكائن؟

أحيانًا أقرأ مقالًا يقول "Go هو الهدف" في بعض الأحيان ، هناك مقال آخر يدعي أنه لا توجد برمجة موجهة للكائنات يمكن إجراؤها باستخدام Go ، فقط لأنه لا يحتوي على فئات.

لذلك كتبت هذا المنشور لتوضيح هذا الموضوع. هل Go موجه نحو الكائن أم لا؟

إذا كنت معتادًا على التفكير بلغة معينة ، اعتمادًا على اللغة التي أتيت منها ، فقد يكون لديك وجهة نظر مختلفة في هذا الموضوع. على سبيل المثال ، إذا كنت من C ، فمن الواضح أن Go لديه الكثير من ميزات البرمجة الموجهة للكائنات. قادمًا من Java ، لا يبدو رمز Go موجهًا نحو الكائن.

ما عليك القيام به في هذه الحالة هو التوقف عن التفكير في "اللغة الأخرى" ، والتفكير بعقلية Go أولاً.

ها هي إجابتي:نعم، Go هو وجوه المنحى ، وفيمنعشأعاقلطريق.

الالذهاب التعليماتيقول:

هل Go لغة موجهة؟

نعم و لا. على الرغم من أن Go يحتوي على أنواع وطرق ويسمح بنمط برمجة موجه للكائنات ، إلا أنه لا يوجد تسلسل هرمي للنوع. يوفر مفهوم "الواجهة" في Go نهجًا مختلفًا نعتقد أنه سهل الاستخدام وفي بعض النواحي أكثر عمومية. توجد أيضًا طرق لتضمين أنواع في أنواع أخرى لتوفير شيء مشابه - ولكن ليس مطابقًا - للتصنيف الفرعي. علاوة على ذلك ، تعد الطرق في Go أكثر عمومية من C ++ أو Java: يمكن تعريفها لأي نوع من البيانات ، حتى الأنواع المضمنة مثل الأعداد الصحيحة العادية "غير المعبأة". لا يقتصر الأمر على الهياكل (الطبقات).

بالإضافة إلى ذلك ، فإن عدم وجود تسلسل هرمي للنوع يجعل "الكائنات" في Go تشعر بخفة وزنها أكثر بكثير من لغات مثل C ++ أو Java.

مفاهيم قطف الكرز

اختار Go بعض المفاهيم من البرمجة الإجرائية ، والبرمجة الوظيفية ، والبرمجة الموجهة للكائنات ، وجمعها معًا ، وترك مفاهيم أخرى لخلق نكهة فريدة خاصة به من أسلوب البرمجة الاصطلاحية.

لا توجد فئات ، أدخل الهياكل

لا توجد فصول دراسية في Go ، بمفهومها التقليدي ، لكن Go لديها أنواع هياكل أقوى بكثير من تلك الأنواعجالنظير. تخدم أنواع الهياكل بالإضافة إلى الأساليب المرتبطة بها الهدف نفسه للفئة التقليدية ، حيث يحتفظ الهيكل بالحالة فقط ، وليس السلوك ، وتوفر لهم الأساليب السلوك ، من خلال السماح بتغيير الحالة.

التغليف

واحدة من أفضل ميزات Go: الحقول والأساليب والوظائف بأحرف كبيرة علنية. جميع الحقول الأخرى محلية للحزمة ولم يتم تصديرها. بنظرة واحدة تعرف ما إذا كان هناك شيء عام أم خاص. لا يوجدمحميلأنه لا وراثة.

لا وراثة

لا يوجد مفهوم الميراث. من الأسئلة الشائعة الخاصة بـ Go:

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

التكوين على الميراث

هذهمبدأ معروف، المذكورة أيضًا في كتاب Gang of Four ، تم العثور عليها كثيرًا في Go code.

عند الإعلان عن بنية ، يمكننا إضافة حقل غير مسمى (مجهول) ، مما يؤدي إلى كشف حقولها وطرقها على البنية. هذا يسميهيكل التضمين:

package main

import ( “fmt” )

type Dog struct { Animal } type Animal struct { Age int }

func (a Animal) Move() { fmt.Println(“Animal moved”) } func (a Animal) SayAge() { fmt.Printf(“Animal age: %d\n”, a.Age) } func main() { d := Dog{} d.Age = 3 d.Move() d.SayAge() }

لعب

واجهات

ننسى واجهات Java و PHP. تختلف واجهات Go اختلافًا كبيرًا ، ومن المفاهيم الأساسية أن الواجهات راضيةبشكل ضمني.

من الأسئلة الشائعة الخاصة بـ Go:

بدلاً من مطالبة المبرمج بالإعلان مسبقًا عن ارتباط نوعين ، في Go ، يلبي النوع تلقائيًا أي واجهة تحدد مجموعة فرعية من أساليبها.

عادة ما تكون الواجهات صغيرة جدًا ، حتى تكون طريقة واحدة فقط. لن ترى قوائم طويلة من الأساليب في اصطلاح Go.

توفر واجهات بأناقةتعدد الأشكال: بقبول الواجهة ، فإنك تقر بقبول أي نوع من الكائنات التي تلبي تلك الواجهة.

أساليب

الأنواع لها طرق. يتم تعريفها خارج تعريف النوع ، مع بناء جملة قد يتذكرJavaScriptتعريفات طريقة النموذج الأولي:

function Person(first, last) {
    this.firstName = first;
    this.lastName = last;
}
Person.prototype.name = function() {
    return this.firstName + " " + this.lastName;
};
p = new Person("Flavio", "Copes")
p.name() // Flavio Copes

في Go يتم كتابة نفس الرمز كما يلي:

package main

import ( “fmt” ) type Person struct { firstName string lastName string } func (p Person) name() string { return p.firstName + " " + p.lastName } func main() { p := Person{“Flavio”, “Copes”} fmt.Println(p.name()) }

طرق إرفاق الأنواع

يمكن إرفاق الأساليب بأي نوع ، حتى أنواع البيانات الأساسية. نظرًا لأنه لا يمكن إرفاق الطرق إلا في نفس الحزمة حيث يتم تعريف النوع ، فلا يمكننا "إثراء" الأنواع الأساسية المضمنة ، ولكن يمكننا إثراء أي نوع مسمى نقوم بإنشائه باستخدام تمثيل أساسي من النوع الأساسي:

package main

import ( “fmt” )

type Amount int

func (a Amount) Add(add Amount) { a += add }

func main() { var a Amount a = 1 a.Add(2) fmt.Println(a) }

لعب

المهام

فكر في لغة البرمجة الشيئية التقليدية مثل Java. كم مرة قمت بتعريف فئة "Utils" بالطرق الثابتة؟

هذا لحل فكرة أن كل شيء هو كائن ، ويجب أن تكون تعريفات الوظائف داخل الفئات. هذا الشيء لا يحدث مع Go ، لأن Go لديه وظائف. لا يجب أن يكون كل شيء شيئًا أو طريقة في العالم الحقيقي. تعتبر "الفئات" و "الكائنات" مفيدة جدًا ولكن لا يمكن استخدامها في كل شيء.

في Go ، لا يعتبر كل شيء كائنًا (ولا يعد أي شيء من الناحية الفنية كائنًا ، ولكن بعض الأشخاص يطلقون على قيم ومتغيرات النوع "كائنات") ، فالأساليب عبارة عن وظائف مرتبطة بنوع ما ، ولكن Go يسمح أيضًا للوظائف بالعيش خارج كائن ، تمامًا مثل C المهام.

لذلك ، على الرغم من أن Go يسمح بالطرق ، فإنه يسمح أيضًا بالوظائف ووظائف من الدرجة الأولى(يمكن تخزين الوظائف كحقول بنية ، ويمكن تمريرها كوسائط إلى وظائف أخرى ، ويمكن إرجاعها من دالة أو قيمة إرجاع طرق).

انتفاخ أقل

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


المزيد من دروس Go: