Advertisement
  1. Code
  2. Android SDK

ترميز تطبيقات Android الوظيفية في كوتلين: Null لامدا، سلامة آند أكثر

Scroll to top
Read Time: 10 min
This post is part of a series called Coding Android Apps in Kotlin.
Coding Functional Android Apps in Kotlin: Getting Started

() translation by (you can also view the original English article)

في هذه السلسلة من ثلاثة أجزاء، لقد اتخذنا نظرة متعمقة في كوتلين، لغة برمجة حديثة لتطبيقات الروبوت الذي يعمل في Java Virtual Machine (JVM).

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

في الدفعتين الأولى والثانية، ونحن تغطي ما يلي:

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

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

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

لا أكثر بالقيم الخالية

كم من المرات قد واجهت NullPointerException بينما تقوم باختبار التعليمات البرمجية الخاصة بك؟ اليوم، من الواضح جداً أن يسمح للمطورين لتعيين فارغة (null) إلى مرجع كائن لم يكن اختيار تصميم أفضل! محاولة استخدام مرجع كائن الذي يحتوي على قيمة فارغة مصدر كبير للأخطاء عبر العديد من لغات البرمجة المختلفة، بما في ذلك جافا. وفي الواقع، كانت NullPointerException مصدر كبير للانزعاج أن جافا 8 أضيف الشرح NonNull@ على وجه الخصوص في محاولة لإصلاح هذا الخلل في نظام نوع.

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

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

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

سلامة فارغة في الممارسة

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

1
var example: String = null

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

إذا كنت تريد أن تعلن صراحة أن متغير يمكن أن تقبل قيمة فارغة، ثم سوف تحتاج إلى إلحاق؟ لنوع المتغير. على سبيل المثال، التالية سيتم ترجمة:

1
var example: String? = null

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

1
var example : String? = null
2
example.size

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

إذا كنت تعمل مع مزيج ملفات كوتلين وجافا (أو ربما تحتاج على وجه التحديد لإدخال قيم خالية في التعليمات البرمجية الخاصة بك كوتلين) ثم كوتلين يتضمن مجموعة من العمليات الخاصة التي تم تصميمها لمساعدتك في أمان التعامل مع أي قيم خالية واجهتك.

1-عامل الاتصال الآمنة

المشغل "الاتصال الآمنة"؟. يوفر لك طريقة للتعامل مع الإشارات التي يحتمل أن تحتوي على قيمة فارغة، مع ضمان أن أي دعوة إلى هذا المرجع لن يسفر عن NullPointerException.

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

التالية على سبيل المثال، سوف يعود a.size إلا إذا a غير null – خلاف ذلك، فسوف ترجع null:

1
a?.size

يمكنك أيضا سلسلة "الاتصال الآمنة" مشغلي معا:

1
val number = person?.address?.street?.number

إذا كان أي من التعبيرات في هذه السلسلة null، فستكون النتيجة null، وإلا سوف تكون النتيجة القيمة المطلوبة.

2-عامل ألفيس

في بعض الأحيان يجب عليك تعبير يمكن أن يحتمل أن تحتوي على قيمة فارغة، ولكن لا تريد أن رمي NullPointerException حتى إذا كانت هذه القيمة تتحول إلى أن تكون فارغة.

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

دعونا نلقي نظرة على مثال للمشغل ألفيس في العمل:

1
 fun setName(name: String?) {
2
   username = name ?: "N/A"

هنا، إذا لم تكن القيمة إلى يسار المشغل ألفيس فارغة ثم الجانب الأيسر هو إرجاع القيمة (الاسم). ولكن إذا كانت القيمة إلى يسار المشغل ألفيس فارغة ثم التعبير على الحق سوف تعاد، وفي هذه الحالة هو n/A.

3-!! عامل التشغيل

إذا كنت تريد من أي وقت مضى إلى التعليمات البرمجية الخاصة بك كوتلين لرمي نولبوينتيريكسسيبشن على غرار جافا القوة، ثم يمكنك استخدام!!عامل التشغيل. على سبيل المثال:

1
val number = firstName!!.length

وهنا، نحن نستخدم!! عامل تشغيل لتأكيد أن المتغير firstName غير null. ما دام firstName يحتوي على مرجع صالح، يتم تعيين رقم متغير على length السلسلة. إذا كان لا يحتوي على firstName مرجعاً صحيحاً، ثم كوتلين سوف يلقي NullPointerException.

تعبيرات لامدا

تعبير لامدا يمثل دالة مجهول. لامدا هي طريقة رائعة لتقليل مقدار التعليمات البرمجية المطلوبة لأداء بعض المهام التي تأتي كل الوقت في ديفيلوبمينت الروبوت — على سبيل المثال، كتابة المستمعين وعمليات الاسترجاعات.

وأدخلت جافا 8 تعبيرات لامدا الأصلي، والآن هذه معتمدة في "نوجات الروبوت". على الرغم من أن هذه الميزة ليست شيئا فريداً كوتلين، لا يزال يستحق أن نلقي نظرة على منهم. بالإضافة إلى ذلك، إذا كنت تعمل في مشروع الذي يحتوي على رمز كوتلين وجافا، ثم يمكنك الآن استخدام تعبيرات لامدا عبر المشروع بأكمله!

تعبير لامدا يضم مجموعة من المعلمات، وعامل لامدا (<-) وهيئة دالة، مرتبة في التنسيق التالي:

1
{ x: Int, y: Int -> x + y }

عند بناء تعبيرات لامدا في كوتلين، تحتاج إلى مراعاة القواعد التالية:

  • تعبير لامدا يجب أن تكون محاطة بأقواس متعرجة.

  • إذا كان يحتوي التعبير على أية معلمات، فأنت بحاجة ليعلن لهم من قبل <- رمز السهم.

  • إذا كنت تعمل مع معلمات متعددة، ثم يمكنك يجب الفصل بينها بفواصل.

  • الجسم يذهب بعد <- تسجيل الدخول.

والفائدة الرئيسية من تعبيرات لامدا أنها تسمح لك بتعريف الدالات المجهولة وثم تمرير هذه الوظائف فورا كتعبير. هذا يسمح لك لأداء العديد من مهام التنمية المشتركة أكثر بلاغه مما كنت قد في جافا 7 والإصدارات السابقة، كما لم تعد بحاجة لكتابة مواصفات الوظيفة في فئة مجردة أو واجهة. في الواقع، عدم وجود لامدا في جافا 7 والإصدارات السابقة جزء كبير من السبب في كتابة المستمعين وعمليات الاسترجاعات تقليديا جداً عالي الكعب في الروبوت.

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

1
button.setOnClickListener(new View.OnClickListener() {
2
3
   @Override
4
   public void onClick(View v) {
5
       Toast.makeText(this, "Button clicked", Toast.LENGTH_LONG).show();
6
   }
7
});

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

1
button.setOnClickListener({ view -> toast("Button clicked") })

بالفعل، هذا أكثر إيجازاً وأسهل للقراءة، ولكن يمكننا أن نذهب كذلك – إذا كان يأخذ دالة دالة أخرى المعلمة الأخيرة، ثم يمكنك تمرير فإنه خارج قائمة الأقواس:

1
button.setOnClickListener() { toast("Button clicked") }

وإذا كان الدالة فقط معلمة واحدة وظيفة، يمكنك إزالة الأقواس تماما:

1
button.setOnClickListener { toast("Button clicked") }

وظائف ملحق

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

يمكنك إنشاء وظيفة ملحق باسم الفئة التي تريد توسيعها إلى اسم الدالة الذي تقوم بإنشائه.

على سبيل المثال:

1
fun AppCompatActivity.toast(msg: String) {
2
3
   Toast.makeText(this, msg, Toast.LENGTH_LONG).show()
4
}

لاحظ أنه هذه الكلمة داخل الدالة التمديد يتوافق مع مثيل AppCompatActivity   toast. التي تسمى على.

في هذا المثال، تحتاج فقط إلى استيراد أصناف AppComptActivity وToast في الملف.kt وثم كنت على استعداد الدعوة. التأشير على مثيلات الفئة الموسعة.

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

1
fun ViewGroup.inflate(
2
    @LayoutRes layoutRes: Int, 
3
    attachToRoot: Boolean = false): View {
4
    
5
    return LayoutInflater
6
        .from(context)
7
        .inflate(layoutRes, this, attachToRoot)
8
}

لذا بدلاً من الاضطرار إلى كتابة ما يلي:

1
val view = LayoutInflater
2
3
   .from(parent)
4
   .inflate(R.layout.activity_main, parent, false)

يمكنك ببساطة استخدام وظيفة الملحق الخاص بك:

1
val view = parent.inflate(R.layout.activity_main)

كائنات فردية

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

والنتيجة النهائية عادة شيئا من هذا القبيل:

1
public class Singleton {
2
3
  private static Singleton singleton = new Singleton( );
4
5
  private Singleton() { }
6
7
  public static Singleton getInstance( ) {
8
     return singleton;
9
  }

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

1
object KotlinSingleton {}

ثم يمكنك استخدام المفرد هذا الحق بعيداً، على سبيل المثال:

1
object KotlinSingleton {
2
   fun myFunction() { [...] }
3
}
4
KotlinSingleton.myFunction()

الاستنتاج

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

جنبا إلى جنب مع ما علمنا في الجزء 1: جافا مقابل كوتلين والجزء 2: "الشروع في العمل"، لديك الآن كل ما تحتاجه للبدء في بناء تطبيقات الروبوت فعالة باستخدام كوتلين لغة البرمجة.

المتعة مع اللغة كوتلين، و لماذا لم تحقق بعض الدورات الأخرى ودروس في برمجة الروبوت؟

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.