ما هي الفائدة المحتملة (إن وجدت) للسماح للمنشدين العودية؟

StackOverflow https://stackoverflow.com/questions/2594940

سؤال

في Java ، لا يمكن أن يكون المنشئون متكررين. خطأ في وقت الترجمة: "الاحتجاج مُنشئ العودية". دعنا نفترض أننا لم يكن لدينا هذا التقييد.

أشياء لتأخذها بالحسبان:

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

هل سيكون هناك أي فائدة من السماح للمنشدين العودية؟

هل كانت مفيدة؟

المحلول

المشاركين (عندما يتصلون ببعضهم البعض) يشبهون الطرق التي تعود void. وبالتالي فإن الطريقة الوحيدة التي يمكنهم من تحقيق نتائجها هي الآثار الجانبية. يقتصر هذا بعد ذلك على تحوير الكائن الذي يقومون بإنشائه أو عن طريق تحوير القيم التي تم تمريرها كمعلمات. هذا الأخير فكرة سيئة للغاية في مُنشئ ؛ عادة ما يأخذ المنشئ معلومات من معلماته دون تحورها.

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

استدعاء مُنشئ آخر (مع this) من داخل مُنشئ يختلف بالطبع تمامًا عن استخدام أ new التعبير داخل مُنشئ:

class Node
{
    Node _left, _right;

    public Node(Node left, Node right)
    {
        _left = left != null ? new Node(left._left, left._right) : null;
        _right = right != null ? new Node(right._left, right._right) : null;
    }
}

هنا Node المُنشئ يدعو نفسه ، لكن عبر تعبير جديد. هذا هو الفرق الحاسم. أ new ينتج عن التعبير قيمة ، لذلك هذا "وظيفي" بحت ، غير متطرف ، ويوفر طريقة مريحة لصنع نسخة عميقة من شجرة العقد.

نصائح أخرى

يمكن أن يكون المنشئون متكررين. (هذا في C#، ولكن يمكنك أن تفعل الشيء نفسه في Java)

دعونا نلقي نظرة على هذه المشكلة. بادئ ذي بدء ، ماذا يحدث عندما تستدعي new MyClass("foo");؟ حسنًا ، هناك شيئان يحدثان. بادئ ذي بدء ، سيقوم الجهاز الظاهري بتخصيص الذاكرة اللازمة لتخزين كائن من النوع MyClass. ثم ، يتم استدعاء المُنشئ. مهمة المنشئ هي تهيئة هذه الذاكرة المخصصة فقط. لذلك ، لا يحتوي المُنشئ على نوع إرجاع على الإطلاق (ولا حتى باطلة). القيمة التي يتم إرجاعها من قبل المشغل الجديد هي إشارة إلى الذاكرة المخصصة ، لذلك لا يمكن للمنشئ العودة أيضًا.

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

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

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

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

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

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

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

في مثال مُنشئ العودية التالية ، يمكنني الاتصال new User() أو new User("Marcus") ومع أي مُنشئ أستخدمه ، newUser تم تعيينه على true.

public class User() {
  public String userName;
  public boolean newUser;
  User() {
    newUser = true;
  }
  User(String userName) {
    // Recursively call no-argument constructor
    this();
    this.userName = userName;
  }
}

هذا هو نفس الشيء بدون منشئات متكررة. لاحظ خط الكود المكررة:

public class User() {
  public String userName;
  public boolean newUser;
  User() {
    newUser = true;
  }
  User(String userName) {
    newUser = true;
    this.userName = userName;
  }
}

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

public class User() {
  public String userName;
  User() {
    this.userName = "New User";
  }
  User(String userName) {
    this.userName = userName;
  }
}

سوف تستخدم فقط المُنشئين العودية إذا كنت:

  1. لديك أكثر من مُنشئ
  2. لديك رمز في مُنشئاتك
  3. تريد استخدام الكود بشكل متكرر في مُنشئ آخر

نوع العودة من المنشئ باطلة.

لا ليس كذلك.

يمكن للمُنشئ أن يستدعي نفسه (أو أي مُنشئ آخر) باستخدام هذا ()

لا ، لا يمكن أن تستدعي إلا مُنشئين آخرين ، وفقط إذا لم يؤدي ذلك إلى الاحتجاج العودية للمؤسس الحالي. لهذا السبب تحصل على رسالة الخطأ التي أشرت إليها.

يمكننا استخدام البيانات غير المحلية بين المكالمات المتتالية للاستمرار في الحصول على بعض المكاسب الممكنة من المنشآت العودية.

كيف؟ لماذا تريد إعادة-initializing ما؟ متى لا يمكنك فعل ذلك بالتتابع في ممر واحد؟ لم تواجه هذه المشكلة منذ 39 عامًا من برمجة الكمبيوتر ، و 20 عامًا من OO.

هل سيكون هناك أي فائدة من السماح للمنشدين العودية؟

لم تتوصل إلى أي ...

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top