Swift-style-guide: الوظائف مقابل الطرق

تم إنشاؤها على ٦ يوليو ٢٠١٥  ·  26تعليقات  ·  مصدر: raywenderlich/swift-style-guide

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

الطريقة هي وظيفة مرتبطة بفئة أو بنية أو تعداد. هذا ينطبق على كل من عمليات المثال والنوع. من ناحية أخرى ، يتم الإعلان عن الوظيفة في النطاق العالمي ولا تنتمي إلى أي نوع.

سيكون كافيا.

التعليق الأكثر فائدة

ماذا عن شيء مثل هذا:

الطرق مقابل الوظائف المجانية

الطرق هي وظائف مرتبطة بالنوع ومفضلة بسبب قابلية اكتشاف الإكمال التلقائي. تكون الوظائف المجانية أقل شيوعًا ولكنها تكون منطقية عندما لا ترتبط العملية ارتباطًا وثيقًا بنوع أو مثيل معين.

يفضل

let sorted = items.mergeSort()  // easily discoverable
rocket.launch()  // a mutating method

غير مفضل

let sorted = mergeSort(items)
launch(&rocket)

استثناءات الوظيفة الحرة

let tuples = zip(a, b)  // feels natural as a free function (symmetry)
let value = max(x,y,z)  // another free function that feels natural

ال 26 كومينتر

لقد رأيت أيضًا وظائف يشار إليها باسم "الوظائف المجانية". أفترض أن كلمة "مجانية" تعني "غير مرتبطة بأي كائن".

تحتوي الوظائف على خيارات نطاق أكثر من النوع والعامة ، في Swift.

افترضت للتو أن الطرق العادية في Objective-C يشار إليها الآن بـ functiona في Swift . جميع المواد التي قرأتها فيما يتعلق بالمنتديات والمدونات والبرامج التعليمية وما إلى ذلك أشارت إليها ببساطة على أنها functions ، حتى عندما تنتمي إلى فصل دراسي أو تعداد.

مستنداتmitchellporter الخاصة

تتبع البرامج التعليمية الموجودة على raywenderlich.com أيضًا إرشادات Apple هنا ، ولهذا السبب يجب تضمينها في دليل الأنماط.

هناك وظائف وطرق في Objective-C أيضًا ؛ ليس كل شيء هو وسيلة. 😉

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

هل أساليب "funcs" الداخلية "طرق متداخلة"؟
ما هي الوظائف داخل الإغلاق أو غيرها من الوظائف غير المسماة؟

struct Struct {
   let closure = {
      func whoAmI() {}
   }

   var any: Any? {
      func jeanValjean() {}
      return nil
   }
}

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

لا أعتقد أن "الوظيفة المجهولة" هي الاسم الصحيح هنا - والتي تشير عادةً إلى الإغلاق.

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

معذرةً ، لم أدرك أن عمليات الإغلاق تمت الإشارة إليها أيضًا على أنها وظائف مجهولة. :]

الوظائف المتداخلة تبدو جيدة بالنسبة لي. أوافق على أن النطاق لا يبدو صحيحًا تمامًا.

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

وعلى الرغم من أنني أعتقد أن الدوال المتداخلة التي لها أسماء تجعلها "غير متجانسة" ، إلا أنني لست واضحًا بشأن ما هو بالضبط "مجهول" ، ومع ذلك ، عندما يتعلق الأمر بالإغلاق ، خاصة تلك التي لا يمكن تغييرها ، والتي تشبه إلى حد كبير الوظائف. أنا أميل نحو الاعتقاد بأن الوظيفة المخزنة مجهولة بالفعل ، لكن الإغلاق الذي يلتقطها ، وربما بعض الحالات ، هو ما يحمل الاسم. هذه هي الطريقة التي تُدرس بها للغة C # ، حيث تُعد صيغة لامدا اختصارًا لبناء ما تسميه المندوب.
https://msdn.microsoft.com/en-us/library/system.delegate (v = مقابل 110) .aspx

func nonymous() {
   func nonymous() {}
}

let anonymouses: [() -> ()] = [].map
{$0} // This "transform" is also anonymous.

let unlcearToMeWhetherNonymous = {}

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

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

ماذا عن شيء مثل هذا:

الطرق مقابل الوظائف المجانية

الطرق هي وظائف مرتبطة بالنوع ومفضلة بسبب قابلية اكتشاف الإكمال التلقائي. تكون الوظائف المجانية أقل شيوعًا ولكنها تكون منطقية عندما لا ترتبط العملية ارتباطًا وثيقًا بنوع أو مثيل معين.

يفضل

let sorted = items.mergeSort()  // easily discoverable
rocket.launch()  // a mutating method

غير مفضل

let sorted = mergeSort(items)
launch(&rocket)

استثناءات الوظيفة الحرة

let tuples = zip(a, b)  // feels natural as a free function (symmetry)
let value = max(x,y,z)  // another free function that feels natural

بخصوص،

استثناءات الوظيفة الحرة

let tuples = zip(a, b)  // feels natural as a free function (symmetry)
let value = max(x,y,z)  // another free function that feels natural

"شعور طبيعي" غامضة وذاتية إلى حد ما.

هل يمكننا توضيح ما نعنيه هنا؟

أيضًا ، كلا من zip و max سيعاني أيضًا من مشكلة // hard to discover التي طرحتها في PR.

IMHO ، أعتقد أن zip مثال محرج. المشاكل التي لدي معها:

  • ما الذي تفعله في الواقع؟ الجمع بين a و b ؟ ضغط a و b بطريقة ما؟ شيء آخر؟ بدون مزيد من السياق ، من الصعب معرفة ذلك.

بدلا من

تكون الوظائف المجانية أقل شيوعًا ولكنها تكون منطقية عندما لا ترتبط العملية ارتباطًا وثيقًا بنوع أو مثيل معين.

وماذا عن هذا؟

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

تكون الوظائف المجانية أكثر ملاءمة عندما لا تكون مرتبطة بأي نوع أو مثيل معين.

سأعيد فتح هذه المشكلة للبحث عن مزيد من المناقشة حول Free Function Exceptions .

حسنًا ، هذه وظيفة مكتبة قياسية. لها الأسبقية في لغة مثل R و Python و C # و C ++. (عبر دفعة).

حسنًا ، هذه وظيفة مكتبة قياسية.

هل حقا؟ لم أستخدمه في iOS ... * محرج *

سوف أتحقق من ذلك ... إذا كان مفهومًا / مستخدمًا على نطاق واسع على نظام iOS ، فربما يكون قلقي هنا في غير محله ...

يعجبني اقتراحك اللفظي ... فأنا متردد في التخلي عن المثال المضغوط. (ملاحظة: يمتلك فريق RW Swift ميثاقًا أكبر (أو أصغر) من نظام iOS.)

يمتلك فريق RW Swift ميثاقًا أكبر (أو أصغر) من نظام iOS.

👍 صحيح. ؛]

بعد مراجعة ما يفعله ملف zip ، سأتركه كمثال. 👍

أعتذر عن تجربة Swift-newbie-moment الخاصة بي هنا. 😉

لا قلق. شكرا لمساعدتك كما هو الحال دائما. راجع للشغل ، لقد لاحظت للتو أنك غير مذكور في الاعتمادات. سوف أصلح ذلك أيضا.

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

الأعلى

let max = Swift.max(0, 1, 2)
let maxElement = [0, 1, 2].maxElement()!

يجب أن يكون maxElement خاصية وليست طريقة ، لكنني ما زلت أعتقد أن الوظيفة المجانية زائدة عن الحاجة. إذا لم يتم تجميعها لنفس الشيء ، فأعتقد أنه يجب تحسين المترجم ، ولكن حتى لو لم يتم تجميعها ، لا أعتقد أن الأداء سيكون مهمًا على الإطلاق ؛ لا أعتقد أن الناس سيستخدمون دالة max مع العديد من العناصر.

أزيز
في C # ، يتم تنفيذ zip بما يعادل طريقة تمديد بروتوكول Swift . لا أعتقد أن هذا أفضل ، لكنه مثال على كيفية التعامل مع zip مختلف.

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

zip([1...3], ["a"..."c"])
Zip2Sequence([1...3], ["a"..."c"])

العاملين
الغالبية العظمى من الوظائف المجانية التي كتبتها في Swift هي مشغلات. لقد رأيت Chris Lattner و Joe Groff يقترحان أنه سيتم تحديد المشغلين ضمن الأنواع ، على غرار C # ، في المستقبل ، لذلك قد يتمكن المشغلون أيضًا من اتباع أي اصطلاحات يتم اختيارها ، لوظائف أخرى ، إذن. ربما لا ينبغي استخدام تنفيذها الحالي على أنها وظيفة حرة فقط كمبدأ توجيهي.

العاملين
الغالبية العظمى من الوظائف المجانية التي كتبتها في Swift هي مشغلات. لقد رأيت كريس لاتنر وجو جروف يقترحان أنه سيكون من الممكن تحديد المشغلين ضمن الأنواع ، على غرار C # ، في المستقبل ...

نعم ، من المحتمل أن يكون هذا هو الاتجاه الذي سيتحرك فيه Swift في المستقبل. هذا اقتراح حديث إلى حد ما من Chris Lattner ، كما ذكرت.

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

أوافق بالتأكيد على أنه لا ينبغي استخدام المشغلين كمثال للوظائف المجانية المثالية.

شكرا على التعليقات @ Jessy-!

بعض الملاحظات:

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

من ناحية أخرى ، فإن بعض أشكال max<T: Comparable> هي O (1) ولديها القدرة على التخصص للاستفادة من الأجهزة. (أظن أن هذا هو سبب وجود إصدار مكون من معلمتين بالإضافة إلى الإصدار المتغير على الرغم من أنني لم أقم بتأكيد ذلك.)

على أي حال ، أعتقد أننا جميعًا متفقون على أنه يجب استخدام الوظائف المجانية باعتدال ، لكنني سأقاوم "أبدًا". الأمثلة المستخدمة تأتي من المكتبة القياسية. لم أر أي مقترحات لإزالة وظيفة zip من المكتبة القياسية. هل هناك اعتراضات على تفاصيل إعادة صياغة @ JRG-Developer أو نموذج طلب السحب المدمج حاليًا في إعادة الصياغة هذه؟

لا تتردد في إعادة الفتح إذا كنت تعتقد أن هناك شيئًا آخر يجب مناقشته. (تم دمجه في فرع التحديث.)

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات

القضايا ذات الصلة

samkim102 picture samkim102  ·  4تعليقات

rwenderlich picture rwenderlich  ·  29تعليقات

gokselkoksal picture gokselkoksal  ·  9تعليقات

samkim102 picture samkim102  ·  6تعليقات

grosch picture grosch  ·  6تعليقات