<?xml version="1.0"?>
<rss version="2.0"><channel><title>&#x627;&#x644;&#x628;&#x631;&#x645;&#x62C;&#x629;: &#x644;&#x63A;&#x629; Kotlin</title><link>https://academy.hsoub.com/programming/kotlin/?d=2</link><description>&#x627;&#x644;&#x628;&#x631;&#x645;&#x62C;&#x629;: &#x644;&#x63A;&#x629; Kotlin</description><language>ar</language><item><title>Kotlin &#x647;&#x648; &#x62C;&#x627;&#x641;&#x627; &#x627;&#x644;&#x62C;&#x62F;&#x64A;&#x62F;</title><link>https://academy.hsoub.com/programming/kotlin/kotlin-%D9%87%D9%88-%D8%AC%D8%A7%D9%81%D8%A7-%D8%A7%D9%84%D8%AC%D8%AF%D9%8A%D8%AF-r641/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2018_09/5ba20883ada7d_kotln.png.5bdbf31891b9cdb4e9f22cec2bc716e7.png" /></p>
<p>
	السؤال الذي قد يتبادر إلى أذهان مُطوّري الجافا هو "ما الذي عليّ أن أتعلمه الآن؟". هناك مجموعة من اللغات التي تستحق الاعتبار، مثل Clojure, Rust  أو Haskell. ولكن ماذا لو كنت تريد أن تتعلم شيئًا يساعدك على دفع الفواتير وهو فوق ذلك سهل الاستخدام؟ Kotlin قد يكون خيارك الأفضل، وسنحاول في هذه المقالة أن نشرح لماذا.
</p>

<h3>
	ما هو Kotlin؟
</h3>

<p>
	 لغة برمجة مُطوّرة من قبل JetBrains، والذين كانوا وراء فكرة IntelliJ IDEA  IDE بالإضافة إلى أشياء أخرى.
</p>

<ul>
	<li>
		 بديل بسيط ومرن لجافا
	</li>
	<li>
		تتلاءم جيدًا مع أكواد جافا الموجودة
	</li>
	<li>
		تُترجم لجافا bytecode
	</li>
	<li>
		تعمل على JVM
	</li>
	<li>
		كما تُترجم أيضًا لجافا سكريبت
	</li>
</ul>

<p>
	إن كنت قد قرأت وثائقها فستلاحظ مجموعة من الأمور المهمة:
</p>

<ul>
	<li>
		تتيح لك القيام بالكثير من الأشياء بأكواد قليلة
	</li>
	<li>
		تحل الكثير من المشاكل الموجودة في جافا
	</li>
	<li>
		تساعدك على الاستمرار في استخدام النظام البيئي ecosystem المعتاد لجافا
	</li>
	<li>
		تتيح لك برمجة الواجهة الأمامية والخلفية بنفس اللغة
	</li>
	<li>
		100٪ متوافقة مع الجافا
	</li>
	<li>
		أداؤها جيد مقارنةً بالبدائل (Clojure, Scala)
	</li>
	<li>
		لا تضيف إلّا طبقةً رقيقة من التّعقيد على جافا
	</li>
</ul>

<p>
	يبدو هذا جيدًا، أليس كذلك؟ فيما يلي سنرى بعض الأمثلة لمقارنتها بالجافا.
</p>

<h3>
	عناصر القِيَم مقابل بيانات الأصناف Value objects vs data classes
</h3>

<p>
	ما تراه هنا هو كائن جافا قديم ((POJO مع الأنماط المعتادة:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_5624_9" style=""><span class="kwd">public</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">HexagonValueObject</span><span class="pln"> </span><span class="pun">{</span><span class="pln">


    </span><span class="kwd">private</span><span class="pln"> final </span><span class="typ">int</span><span class="pln"> x</span><span class="pun">;</span><span class="pln">
    </span><span class="kwd">private</span><span class="pln"> final </span><span class="typ">int</span><span class="pln"> y</span><span class="pun">;</span><span class="pln">
    </span><span class="kwd">private</span><span class="pln"> final </span><span class="typ">int</span><span class="pln"> z</span><span class="pun">;</span><span class="pln">


    </span><span class="kwd">public</span><span class="pln"> </span><span class="typ">HexagonValueObject</span><span class="pun">(</span><span class="typ">int</span><span class="pln"> x</span><span class="pun">,</span><span class="pln"> </span><span class="typ">int</span><span class="pln"> y</span><span class="pun">,</span><span class="pln"> </span><span class="typ">int</span><span class="pln"> z</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">x </span><span class="pun">=</span><span class="pln"> x</span><span class="pun">;</span><span class="pln">
        </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">y </span><span class="pun">=</span><span class="pln"> y</span><span class="pun">;</span><span class="pln">
        </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">z </span><span class="pun">=</span><span class="pln"> z</span><span class="pun">;</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">


    </span><span class="kwd">public</span><span class="pln"> </span><span class="typ">int</span><span class="pln"> getX</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        </span><span class="kwd">return</span><span class="pln"> x</span><span class="pun">;</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">


    </span><span class="kwd">public</span><span class="pln"> </span><span class="typ">int</span><span class="pln"> getY</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        </span><span class="kwd">return</span><span class="pln"> y</span><span class="pun">;</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">


    </span><span class="kwd">public</span><span class="pln"> </span><span class="typ">int</span><span class="pln"> getZ</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        </span><span class="kwd">return</span><span class="pln"> z</span><span class="pun">;</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">


    </span><span class="lit">@Override</span><span class="pln">
    </span><span class="kwd">public</span><span class="pln"> boolean equals</span><span class="pun">(</span><span class="typ">Object</span><span class="pln"> o</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="kwd">this</span><span class="pln"> </span><span class="pun">==</span><span class="pln"> o</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">return</span><span class="pln"> </span><span class="kwd">true</span><span class="pun">;</span><span class="pln">
        </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">o </span><span class="pun">==</span><span class="pln"> null </span><span class="pun">||</span><span class="pln"> getClass</span><span class="pun">()</span><span class="pln"> </span><span class="pun">!=</span><span class="pln"> o</span><span class="pun">.</span><span class="pln">getClass</span><span class="pun">())</span><span class="pln"> </span><span class="kwd">return</span><span class="pln"> </span><span class="kwd">false</span><span class="pun">;</span><span class="pln">
        </span><span class="typ">HexagonValueObject</span><span class="pln"> hexagon </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="typ">HexagonValueObject</span><span class="pun">)</span><span class="pln"> o</span><span class="pun">;</span><span class="pln">
        </span><span class="kwd">return</span><span class="pln"> getX</span><span class="pun">()</span><span class="pln"> </span><span class="pun">==</span><span class="pln"> hexagon</span><span class="pun">.</span><span class="pln">getX</span><span class="pun">()</span><span class="pln"> </span><span class="pun">&amp;&amp;</span><span class="pln">
                getY</span><span class="pun">()</span><span class="pln"> </span><span class="pun">==</span><span class="pln"> hexagon</span><span class="pun">.</span><span class="pln">getY</span><span class="pun">()</span><span class="pln"> </span><span class="pun">&amp;&amp;</span><span class="pln">
                getZ</span><span class="pun">()</span><span class="pln"> </span><span class="pun">==</span><span class="pln"> hexagon</span><span class="pun">.</span><span class="pln">getZ</span><span class="pun">();</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">


    </span><span class="lit">@Override</span><span class="pln">
    </span><span class="kwd">public</span><span class="pln"> </span><span class="typ">int</span><span class="pln"> hashCode</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        </span><span class="kwd">return</span><span class="pln"> </span><span class="typ">Objects</span><span class="pun">.</span><span class="pln">hash</span><span class="pun">(</span><span class="pln">getX</span><span class="pun">(),</span><span class="pln"> getY</span><span class="pun">(),</span><span class="pln"> getZ</span><span class="pun">());</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">


    </span><span class="lit">@Override</span><span class="pln">
    </span><span class="kwd">public</span><span class="pln"> </span><span class="typ">String</span><span class="pln"> toString</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        </span><span class="kwd">return</span><span class="pln"> </span><span class="str">"HexagonValueObject{"</span><span class="pln"> </span><span class="pun">+</span><span class="pln">
                </span><span class="str">"x="</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> x </span><span class="pun">+</span><span class="pln">
                </span><span class="str">", y="</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> y </span><span class="pun">+</span><span class="pln">
                </span><span class="str">", z="</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> z </span><span class="pun">+</span><span class="pln">
                </span><span class="str">'}'</span><span class="pun">;</span><span class="pln">
   </span><span class="pun">}</span></pre>

<p>
	إنشاء عناصر القِيَم هو عملية مرهقة حتى باستخدام المكتبات مثل Lombok) Lombok يتطلب تثبيت ملحقة في بيئة العمل IDE الخاصة بك من أجل أن يعمل، وهو أمر قد لا يكون ممكنًا في جميع بيئات التطوير، يمكن تجاوز هذا المشكل بأدوات مثل Delombok، ولكنه اختراق أكثر منه حل للمشكلة)، على الأقل IDEA (أو Eclipse) يمنحك بعض المساعدة في توليد الكثير من تلك الوظائف، ولكنّ إضافة حقل ونسيان تعديل الوظيفة equals سيؤدي إلى مفاجآت سيئة. دعونا ننظر الآن إلى الكود المقابل في Kotlin:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_5624_11" style=""><span class="pln">data </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">HexagonDataClass</span><span class="pun">(</span><span class="pln">val x</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Int</span><span class="pun">,</span><span class="pln"> val y</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Int</span><span class="pun">,</span><span class="pln"> val z</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Int</span><span class="pun">)</span></pre>

<p>
	مذهل! لقد اختصرنا الكثير من الكتابة بالمقارنة مع نسخة جافا. بيانات الأصناف في Kotlin تعطيك
</p>

<ul>
	<li>
		equals + hashCode و
	</li>
	<li>
		toString بالإضافة إلى
	</li>
	<li>
		المُحصّلات والمُعيِّنات (getters and setters). يمكنك أيضًا نسخها، مما يخلق كائنًا جديدًا مع إعادة كتابة بعض حقوله.
	</li>
</ul>

<h3>
	حشو سلاسل النصوص String interpolation
</h3>

<p>
	التعامل مع سلاسل النصوص في الجافا مرهق. ولكن يمكن تبسيطه باستخدام String.format ومع ذلك ستبقى قبيحة.
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_5624_13" style=""><span class="kwd">public</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">JavaUser</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">private</span><span class="pln"> final </span><span class="typ">String</span><span class="pln"> name</span><span class="pun">;</span><span class="pln">
    </span><span class="kwd">private</span><span class="pln"> final </span><span class="typ">int</span><span class="pln"> age</span><span class="pun">;</span><span class="pln">


    </span><span class="kwd">public</span><span class="pln"> </span><span class="typ">String</span><span class="pln"> toHumanReadableFormat</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        </span><span class="kwd">return</span><span class="pln"> </span><span class="str">"JavaUser{"</span><span class="pln"> </span><span class="pun">+</span><span class="pln">
                </span><span class="str">"name='"</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> name </span><span class="pun">+</span><span class="pln"> </span><span class="str">'\''</span><span class="pln"> </span><span class="pun">+</span><span class="pln">
                </span><span class="str">", age="</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> age </span><span class="pun">+</span><span class="pln">
                </span><span class="str">'}'</span><span class="pun">;</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">


    </span><span class="kwd">public</span><span class="pln"> </span><span class="typ">String</span><span class="pln"> toHumanReadableFormatWithStringFormat</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        </span><span class="kwd">return</span><span class="pln"> </span><span class="typ">String</span><span class="pun">.</span><span class="pln">format</span><span class="pun">(</span><span class="str">"JavaUser{name='%s', age=%s}"</span><span class="pun">,</span><span class="pln"> name</span><span class="pun">,</span><span class="pln"> age</span><span class="pun">);</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span></pre>

<p>
	Kotlin وجد حلّا لهذا، حيث أضاف مفهوم حشو السلاسل، مما بسّط استخدام المتغيرات في السلاسل الحرفية. ومكّن أيضًا استدعاء الوظائف منها!
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_5624_15" style=""><span class="kwd">class</span><span class="pln"> </span><span class="typ">KotlinUser</span><span class="pun">(</span><span class="pln">val name</span><span class="pun">:</span><span class="pln"> </span><span class="typ">String</span><span class="pun">,</span><span class="pln"> val age</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Int</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">


    fun toHumanReadableFormat</span><span class="pun">()</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">"JavaUser{name='$name', age=$age}"</span><span class="pln">


    fun toHumanReadableFormatWithMethodCall</span><span class="pun">()</span><span class="pln"> </span><span class="pun">=</span><span class="pln">
        </span><span class="str">"JavaUser{name='${name.capitalize()}', age=$age}"</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span></pre>

<h3>
	دوال التمديد Extension functions
</h3>

<p>
	كتابة المُلقّمات decorators في جافا يمكن أن يكون صعبًا، كما أنّها ليست مثالية.<br>
	إذا كنت تريد أن تكتب مُلقّمًا، والذي يمكن استخدامه مع جميع الأصناف التي تقدّم List فلا يمكنك ببساطة استخدامه في الملقم خاصتك لأنّه سيحتاج منك أن تقدم الكثير من الوظائف الأخرى، لذلك ستكون مضطرًّا لتمديد AbstractList.
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_5624_17" style=""><span class="kwd">public</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">ListPresenterDecorator</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;</span><span class="pln"> extends </span><span class="typ">AbstractList</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">{</span><span class="pln">

    </span><span class="kwd">private</span><span class="pln"> </span><span class="typ">List</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;</span><span class="pln"> </span><span class="typ">list</span><span class="pun">;</span><span class="pln">

    </span><span class="kwd">public</span><span class="pln"> </span><span class="typ">ListPresenterDecorator</span><span class="pun">(</span><span class="typ">List</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;</span><span class="pln"> </span><span class="typ">list</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        </span><span class="kwd">this</span><span class="pun">.</span><span class="typ">list</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">list</span><span class="pun">;</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">

    </span><span class="kwd">public</span><span class="pln"> </span><span class="typ">String</span><span class="pln"> present</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        </span><span class="kwd">return</span><span class="pln"> </span><span class="typ">list</span><span class="pun">.</span><span class="pln">stream</span><span class="pun">()</span><span class="pln">
                </span><span class="pun">.</span><span class="typ">map</span><span class="pun">(</span><span class="typ">Object</span><span class="pun">::</span><span class="pln">toString</span><span class="pun">)</span><span class="pln">
                </span><span class="pun">.</span><span class="pln">collect</span><span class="pun">(</span><span class="typ">Collectors</span><span class="pun">.</span><span class="pln">joining</span><span class="pun">(</span><span class="str">", "</span><span class="pun">));</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">

    </span><span class="lit">@Override</span><span class="pln">
    </span><span class="kwd">public</span><span class="pln"> T get</span><span class="pun">(</span><span class="typ">int</span><span class="pln"> index</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        </span><span class="kwd">return</span><span class="pln"> </span><span class="typ">list</span><span class="pun">.</span><span class="pln">get</span><span class="pun">(</span><span class="pln">index</span><span class="pun">);</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">

    </span><span class="lit">@Override</span><span class="pln">
    </span><span class="kwd">public</span><span class="pln"> </span><span class="typ">int</span><span class="pln"> size</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        </span><span class="kwd">return</span><span class="pln"> </span><span class="typ">list</span><span class="pun">.</span><span class="pln">size</span><span class="pun">();</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	إذا كنت بحاجة إلى تلقيم شيء ما ولكنه لا يوفر أصنافًا أساسية base classes مفيدةً مثل AbstractList أو الصنف final، فأنت لا تستطيع ذلك ببساطة. لكن وظائف التمديد Extension methods يمكن أن تعطيك الحل!
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_5624_19" style=""><span class="pln">fun </span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;</span><span class="pln"> </span><span class="typ">List</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;.</span><span class="pln">present</span><span class="pun">()</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">joinToString</span><span class="pun">(</span><span class="str">", "</span><span class="pun">)</span></pre>

<p>
	تتصرف هذه الوظيفة كمُلقّم لجميع الأصناف Lists. لو قارنّا هذا ببديله في الجافا فإنّ هذ السطر الصغير أبسط بكثير، والأكثر من ذلك سوف يعمل أيضًا مع الأصناف final. حاول ألّا تسيء استخدامها وحسب.
</p>

<h3>
	التحقق من العدمية Null safety
</h3>

<p>
	التحقق من القيم المعدومة null ينطوي على الكثير من التعابير المنطقية والأنماط. مع ظهور الجافا، يمكنك أخيرًا التعامل مع هذه المشكلة بواسطة الصنف Optional، لكن ماذا لو كان مرجعOptional معدومًا null؟ ستحصل على NullPointerException، فلا زلنا بعد مرور 20 عام على ظهور جافا لا نستطيع تحديد العنصر الذي كان معدومًا. نأخذ المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_5624_21" style=""><span class="kwd">public</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">JavaUser</span><span class="pln"> </span><span class="pun">{</span><span class="pln">

    </span><span class="kwd">static</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">Address</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        </span><span class="typ">String</span><span class="pln"> city</span><span class="pun">;</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">

    </span><span class="kwd">private</span><span class="pln"> final </span><span class="typ">String</span><span class="pln"> firstName</span><span class="pun">;</span><span class="pln">
    </span><span class="kwd">private</span><span class="pln"> final </span><span class="typ">String</span><span class="pln"> lastName</span><span class="pun">;</span><span class="pln">
    </span><span class="kwd">private</span><span class="pln"> final </span><span class="typ">List</span><span class="pun">&lt;</span><span class="typ">Address</span><span class="pun">&gt;</span><span class="pln"> addresses</span><span class="pun">;</span><span class="pln">

    </span><span class="com">/**
     * If you want to make sure nothing is `null`
     * you have to check everything.
     */</span><span class="pln">
    </span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">static</span><span class="pln"> </span><span class="typ">String</span><span class="pln"> getFirstCity</span><span class="pun">(</span><span class="typ">JavaUser</span><span class="pln"> user</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        </span><span class="kwd">if</span><span class="pun">(</span><span class="pln">user </span><span class="pun">!=</span><span class="pln"> null </span><span class="pun">&amp;&amp;</span><span class="pln"> user</span><span class="pun">.</span><span class="pln">addresses </span><span class="pun">!=</span><span class="pln"> null </span><span class="pun">&amp;&amp;</span><span class="pln"> </span><span class="pun">!</span><span class="pln">user</span><span class="pun">.</span><span class="pln">addresses</span><span class="pun">.</span><span class="pln">isEmpty</span><span class="pun">())</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
            </span><span class="kwd">for</span><span class="pun">(</span><span class="typ">Address</span><span class="pln"> address </span><span class="pun">:</span><span class="pln"> user</span><span class="pun">.</span><span class="pln">addresses</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
                </span><span class="kwd">if</span><span class="pun">(</span><span class="pln">address</span><span class="pun">.</span><span class="pln">city </span><span class="pun">!=</span><span class="pln"> null</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
                    </span><span class="kwd">return</span><span class="pln"> address</span><span class="pun">.</span><span class="pln">city</span><span class="pun">;</span><span class="pln">
                </span><span class="pun">}</span><span class="pln">
            </span><span class="pun">}</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">
        </span><span class="kwd">throw</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">IllegalArgumentException</span><span class="pun">(</span><span class="str">"This User has no cities!"</span><span class="pun">);</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	مع Kotlin، لديك العديد من الخيارات. إذا كان مشروعك متداخلًا مع مشاريع جافا يمكنك استخدام عامل التحقق من العدميّة (؟)null safety operator:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_5624_24" style=""><span class="pln">data </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">KotlinUserWithNulls</span><span class="pun">(</span><span class="pln">val firstName</span><span class="pun">:</span><span class="pln"> </span><span class="typ">String</span><span class="pun">?,</span><span class="pln">
       </span><span class="com">// String? means that it is either a String object or a null</span><span class="pln">
                               val lastName</span><span class="pun">:</span><span class="pln"> </span><span class="typ">String</span><span class="pun">?,</span><span class="pln">
                               val addresses</span><span class="pun">:</span><span class="pln"> </span><span class="typ">List</span><span class="pun">&lt;</span><span class="typ">Address</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">=</span><span class="pln">  listOf</span><span class="pun">())</span><span class="pln"> </span><span class="pun">{</span><span class="pln">

    data </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">Address</span><span class="pun">(</span><span class="pln">val city</span><span class="pun">:</span><span class="pln"> </span><span class="typ">String</span><span class="pun">?)</span><span class="pln">

    companion object </span><span class="pun">{</span><span class="pln">
        fun fetchFirstCity</span><span class="pun">(</span><span class="pln">user</span><span class="pun">:</span><span class="pln"> </span><span class="typ">KotlinUserWithNulls</span><span class="pun">?):</span><span class="pln"> </span><span class="typ">String</span><span class="pun">?</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
            user</span><span class="pun">?.</span><span class="pln">addresses</span><span class="pun">?.</span><span class="pln">forEach </span><span class="pun">{</span><span class="pln"> it</span><span class="pun">.</span><span class="pln">city</span><span class="pun">?.</span><span class="pln">let </span><span class="pun">{</span><span class="pln"> </span><span class="kwd">return</span><span class="pln"> it </span><span class="pun">}</span><span class="pln"> </span><span class="pun">}</span><span class="pln">
            </span><span class="kwd">return</span><span class="pln"> null
        </span><span class="pun">}</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	الكود الموجود بعد ؟ لن يُنفّذ إلا إن كان المعامل الأيسر operand غير معدوم not null. الدالة let تنشئ ارتباطًا محليًّا للكائن المُستدعى بحيث أنّ it سوف تشير إلى it.city. أما إن كان عملك مفصولًا عن الجافا فأقترح الابتعاد عن كل ما له علاقة بـ null
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_5624_26" style=""><span class="pln">data </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">KotlinUserWithoutNulls</span><span class="pun">(</span><span class="pln">val firstName</span><span class="pun">:</span><span class="pln"> </span><span class="typ">String</span><span class="pun">,</span><span class="pln">
                                  </span><span class="com">// this parameter can't be null</span><span class="pln">
                                  val lastName</span><span class="pun">:</span><span class="pln"> </span><span class="typ">String</span><span class="pun">,</span><span class="pln">
                                  val addresses</span><span class="pun">:</span><span class="pln"> </span><span class="typ">List</span><span class="pun">&lt;</span><span class="typ">Address</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> listOf</span><span class="pun">())</span><span class="pln"> </span><span class="pun">{</span><span class="pln">

    data </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">Address</span><span class="pun">(</span><span class="pln">val city</span><span class="pun">:</span><span class="pln"> </span><span class="typ">String</span><span class="pun">)</span><span class="pln">

    companion object </span><span class="pun">{</span><span class="pln">
        fun fetchFirstCity</span><span class="pun">(</span><span class="pln">user</span><span class="pun">:</span><span class="pln"> </span><span class="typ">KotlinUserWithNulls</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=</span><span class="pln">
            user</span><span class="pun">.</span><span class="pln">addresses</span><span class="pun">.</span><span class="pln">first</span><span class="pun">().</span><span class="pln">city
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	إذا لم يكن هناك أي استخدام لـ null (لا وجود لـ ؟) فكل شيء سيصبح أكثر بساطةً.
</p>

<h3>
	استنباط النوع Type Inference
</h3>

<p>
	Kotlin يدعم استنباط الأنواع، مما يعني أنه قادر على معرفة الأنواع من سياقها. أي مثل العامل الماسي diamond notation في الجافا &lt;&gt;! نأخذ المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_5624_29" style=""><span class="kwd">public</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">JavaUser</span><span class="pln"> </span><span class="pun">{</span><span class="pln">

    </span><span class="com">// ...</span><span class="pln">

    </span><span class="kwd">private</span><span class="pln"> final </span><span class="typ">String</span><span class="pln"> firstName</span><span class="pun">;</span><span class="pln">
    </span><span class="kwd">private</span><span class="pln"> final </span><span class="typ">String</span><span class="pln"> lastName</span><span class="pun">;</span><span class="pln">
    </span><span class="kwd">private</span><span class="pln"> final </span><span class="typ">List</span><span class="pun">&lt;</span><span class="typ">Address</span><span class="pun">&gt;</span><span class="pln"> addresses</span><span class="pun">;</span><span class="pln">

    </span><span class="kwd">public</span><span class="pln"> </span><span class="typ">Address</span><span class="pln"> getFirstAddress</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        </span><span class="typ">Address</span><span class="pln"> firstAddress </span><span class="pun">=</span><span class="pln"> addresses</span><span class="pun">.</span><span class="pln">get</span><span class="pun">(</span><span class="lit">0</span><span class="pun">);</span><span class="pln">
        </span><span class="kwd">return</span><span class="pln"> firstAddress</span><span class="pun">;</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	هذا يبدو نفسه تقريبًا في Kotlin:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_5624_31" style=""><span class="pln">data </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">KotlinUser</span><span class="pun">(</span><span class="pln">val firstName</span><span class="pun">:</span><span class="pln"> </span><span class="typ">String</span><span class="pun">,</span><span class="pln">
                      val lastName</span><span class="pun">:</span><span class="pln"> </span><span class="typ">String</span><span class="pun">,</span><span class="pln">
                      val addresses</span><span class="pun">:</span><span class="pln"> </span><span class="typ">List</span><span class="pun">&lt;</span><span class="typ">Address</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> listOf</span><span class="pun">())</span><span class="pln"> </span><span class="pun">{</span><span class="pln">

    data </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">Address</span><span class="pun">(</span><span class="pln">val city</span><span class="pun">:</span><span class="pln"> </span><span class="typ">String</span><span class="pun">)</span><span class="pln">

    </span><span class="com">/**
     * This is the same as in `JavaUser`.
     */</span><span class="pln">
    fun getFirstAddressNoInference</span><span class="pun">():</span><span class="pln"> </span><span class="typ">Address</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        val firstAddress</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Address</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> addresses</span><span class="pun">.</span><span class="pln">first</span><span class="pun">()</span><span class="pln">
        </span><span class="kwd">return</span><span class="pln"> firstAddress
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	وذلك حتى تدع Kotlin تكتشف أنواع المتغيرات الخاصة بك:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_5624_35" style=""><span class="com">/**
 * Here the type of `firstAddress` is inferred from the context.
 */</span><span class="pln">
fun getFirstAddressInferred</span><span class="pun">():</span><span class="pln"> </span><span class="typ">Address</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    val firstAddress </span><span class="pun">=</span><span class="pln"> addresses</span><span class="pun">.</span><span class="pln">first</span><span class="pun">()</span><span class="pln">
    </span><span class="kwd">return</span><span class="pln"> firstAddress
</span><span class="pun">}</span></pre>

<p>
	أو حتى الوظائف:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_5624_37" style=""><span class="com">/**
 * Here the return type is inferred. Note that
 * if a method consists of only one statement
 * you can omit the curly braces.
 */</span><span class="pln">
fun getFirstAddress</span><span class="pun">()</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> addresses</span><span class="pun">.</span><span class="pln">first</span><span class="pun">()</span></pre>

<h3>
	لا داعي للتحقق من الاستثناءات No checked exceptions
</h3>

<p>
	ربما رأيت الكود التالي مليون مرة من قبل:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_5624_39" style=""><span class="kwd">public</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">JavaLineLoader</span><span class="pln"> </span><span class="pun">{</span><span class="pln">

    </span><span class="kwd">public</span><span class="pln"> </span><span class="typ">List</span><span class="pun">&lt;</span><span class="typ">String</span><span class="pun">&gt;</span><span class="pln"> loadLines</span><span class="pun">(</span><span class="typ">String</span><span class="pln"> path</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        </span><span class="typ">List</span><span class="pun">&lt;</span><span class="typ">String</span><span class="pun">&gt;</span><span class="pln"> lines  </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">ArrayList</span><span class="pun">&lt;&gt;();</span><span class="pln">
        </span><span class="kwd">try</span><span class="pun">(</span><span class="typ">BufferedReader</span><span class="pln"> br </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">BufferedReader</span><span class="pun">(</span><span class="kwd">new</span><span class="pln"> </span><span class="typ">FileReader</span><span class="pun">(</span><span class="pln">path</span><span class="pun">)))</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
            </span><span class="typ">String</span><span class="pln"> line</span><span class="pun">;</span><span class="pln">
            </span><span class="kwd">while</span><span class="pun">((</span><span class="pln">line </span><span class="pun">=</span><span class="pln"> br</span><span class="pun">.</span><span class="pln">readLine</span><span class="pun">())</span><span class="pln"> </span><span class="pun">!=</span><span class="pln"> null</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
                lines</span><span class="pun">.</span><span class="pln">add</span><span class="pun">(</span><span class="pln">line</span><span class="pun">);</span><span class="pln">
            </span><span class="pun">}</span><span class="pln">
        </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">catch</span><span class="pln"> </span><span class="pun">(</span><span class="typ">IOException</span><span class="pln"> e</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
            e</span><span class="pun">.</span><span class="pln">printStackTrace</span><span class="pun">();</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">
        </span><span class="kwd">return</span><span class="pln"> lines</span><span class="pun">;</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	لأصحاب المدرسة القديمة في (IO in Java). لاحظوا التعليمة try في الكود أعلاه، الأمر نفسه سيُكتب هكذا في Kotlin:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_5624_41" style=""><span class="kwd">class</span><span class="pln"> </span><span class="typ">KotlinLineLoader</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    fun loadLines</span><span class="pun">(</span><span class="pln">path</span><span class="pun">:</span><span class="pln"> </span><span class="typ">String</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">File</span><span class="pun">(</span><span class="pln">path</span><span class="pun">).</span><span class="pln">readLines</span><span class="pun">()</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	هناك بضعة أشياء ينبغي الانتباه إليها، أولًا: Kotlin ألغى التحقق من الاستثناءات. ثانيًا: Kotlin أضاف استخدام الكائنات من نوع Closeable أي:
</p>

<blockquote class="ipsQuote" data-ipsquote="">
	<div class="ipsQuote_citation">
		اقتباس
	</div>

	<div class="ipsQuote_contents ipsClearfix" data-gramm="false">
		<p>
			ينفذ [الكتلة block] المعينة على هذا المورد ثم يقوم بإغلاقها بشكل صحيح بغض النظر عن طرح استثناء من عدمه. (وثائق Kotlin)
		</p>
	</div>
</blockquote>

<p>
	يمكنك أن تلاحظ أيضًا أنّ دالة التمديد (readLines) أضيفت إلى الصنف File. هذا النمط موجود بكثرة في Kotlin. إذا كنت قد استخدمت Guava أو Apache Commons أو شيء مماثل من قبل، فغالبًا سترى وظائف مشتركة تضاف منها إلى الصنف JDK كدالة تمديد. وهذا قد يكون مفيدًا لصحتك (أعصابك على الأقل).
</p>

<h3>
	دعم لامبدا Lambda support
</h3>

<p>
	دعونا نلقي نظرة على دعم lambda في الجافا:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_5624_43" style=""><span class="kwd">public</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">JavaFilterOperation</span><span class="pln"> </span><span class="pun">{</span><span class="pln">

    </span><span class="kwd">private</span><span class="pln"> </span><span class="typ">List</span><span class="pun">&lt;</span><span class="typ">String</span><span class="pun">&gt;</span><span class="pln"> items</span><span class="pun">;</span><span class="pln">

    </span><span class="lit">@FunctionalInterface</span><span class="pln">
    interface </span><span class="typ">FilterOperation</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        </span><span class="typ">Boolean</span><span class="pln"> filter</span><span class="pun">(</span><span class="typ">String</span><span class="pln"> element</span><span class="pun">);</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">

    </span><span class="kwd">private</span><span class="pln"> </span><span class="typ">List</span><span class="pun">&lt;</span><span class="typ">String</span><span class="pun">&gt;</span><span class="pln"> filterBy</span><span class="pun">(</span><span class="typ">FilterOperation</span><span class="pln"> fn</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        </span><span class="kwd">return</span><span class="pln"> items</span><span class="pun">.</span><span class="pln">stream</span><span class="pun">()</span><span class="pln">
                </span><span class="pun">.</span><span class="pln">filter</span><span class="pun">(</span><span class="pln">fn</span><span class="pun">::</span><span class="pln">filter</span><span class="pun">)</span><span class="pln"> </span><span class="com">// applying the function</span><span class="pln">
                </span><span class="pun">.</span><span class="pln">collect</span><span class="pun">(</span><span class="typ">Collectors</span><span class="pun">.</span><span class="pln">toList</span><span class="pun">());</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">

    </span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> doFilter</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        filterBy</span><span class="pun">((</span><span class="pln">element</span><span class="pun">)</span><span class="pln"> </span><span class="pun">-&gt;</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
            </span><span class="kwd">return</span><span class="pln"> element</span><span class="pun">.</span><span class="pln">length</span><span class="pun">()</span><span class="pln"> </span><span class="pun">&gt;</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln">
            </span><span class="com">// calling the function with an actual lambda</span><span class="pln">
        </span><span class="pun">});</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	بما أنّه لا توجد قاعدة محددة لكتابة أنواع معاملات الوظائف method parameter types، فسيكون علينا إنشاء واجهة لها بأنفسنا. لاحظ أننا يمكن أن نستخدم Function&lt;String, Boolean&gt; هنا، ولكنها لن تعمل إلّا على الدوال ذات المعامل الواحد! هناك بعض الواجهات في JDK لحل هذه المشكلة، ولكن الكود سيكون مربكًا وغير واضح (مثلًا، ما دور BiFunction هنا؟)، Kotlin يحسّن هذا قليلًا:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_5624_45" style=""><span class="kwd">class</span><span class="pln"> </span><span class="typ">KotlinFilterOperation</span><span class="pln"> </span><span class="pun">{</span><span class="pln">

    </span><span class="kwd">private</span><span class="pln"> val items </span><span class="pun">=</span><span class="pln"> listOf</span><span class="pun">&lt;</span><span class="typ">String</span><span class="pun">&gt;()</span><span class="pln">

    fun filterBy</span><span class="pun">(</span><span class="pln">fn</span><span class="pun">:</span><span class="pln"> </span><span class="pun">(</span><span class="typ">String</span><span class="pun">)</span><span class="pln"> </span><span class="pun">-&gt;</span><span class="pln"> </span><span class="typ">Boolean</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> items</span><span class="pun">.</span><span class="pln">filter</span><span class="pun">(</span><span class="pln">fn</span><span class="pun">)</span><span class="pln">

    fun doFilter</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        filterBy</span><span class="pun">(</span><span class="typ">String</span><span class="pun">::</span><span class="pln">isNotEmpty</span><span class="pun">)</span><span class="pln">
        </span><span class="com">// note the exension function `isNotEmpty` added to `String`!</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	Kotlin يضيف قاعدةً نحويةً من أجل تمرير الدوال كمعاملات: (ParamType1, ...ParamTypeN) -&gt; ReturnType. Kotlin يوفر مراجع للوظائف والحقول، كما يمكنك أيضًا التأشير إلى وظيفة من كائن ملموس! باستخدام المثال أعلاه يمكنني التأشير إلى الوظيفة filterBy من عيّنة instance ملموسة، هكذا:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_5624_47" style=""><span class="pln">val reference </span><span class="pun">=</span><span class="pln"> </span><span class="typ">KotlinFilterOperation</span><span class="pun">()::</span><span class="pln">filterBy</span></pre>

<h3>
	البرمجة الوظيفيّة Functional programming
</h3>

<p>
	البرمجة الوظيفيّة أصبح لها ضجة في الوقت الحاضر. ومع جافا 8، قدمت Oracle مقاربتها لهذا الموضوع: الواجهة البرمجية Stream<br>
	(Stream <abbr title="Application Programming Interface | واجهة برمجية"><abbr title="Application Programming Interface | واجهة برمجية">API</abbr></abbr>). وهي تعمل كالتالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_5624_49" style=""><span class="kwd">public</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">JavaUser</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
 
    </span><span class="com">// ...</span><span class="pln">
    
    </span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">static</span><span class="pln"> </span><span class="typ">Set</span><span class="pun">&lt;</span><span class="typ">String</span><span class="pun">&gt;</span><span class="pln"> fetchCitiesOfUsers</span><span class="pun">(</span><span class="pln">
                                  </span><span class="typ">List</span><span class="pun">&lt;</span><span class="typ">JavaUser</span><span class="pun">&gt;</span><span class="pln"> users</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        </span><span class="kwd">return</span><span class="pln"> users</span><span class="pun">.</span><span class="pln">stream</span><span class="pun">()</span><span class="pln">
                </span><span class="pun">.</span><span class="pln">flatMap</span><span class="pun">(</span><span class="pln">user </span><span class="pun">-&gt;</span><span class="pln"> user</span><span class="pun">.</span><span class="pln">addresses</span><span class="pun">.</span><span class="pln">stream</span><span class="pun">())</span><span class="pln">
                </span><span class="pun">.</span><span class="typ">map</span><span class="pun">(</span><span class="typ">JavaUser</span><span class="pun">.</span><span class="typ">Address</span><span class="pun">::</span><span class="pln">getCity</span><span class="pun">)</span><span class="pln">
                </span><span class="pun">.</span><span class="pln">collect</span><span class="pun">(</span><span class="typ">Collectors</span><span class="pun">.</span><span class="pln">toSet</span><span class="pun">());</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	المقابل في Kotlin مشابه إلى حد ما، ولكن باختلافات دقيقة:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_5624_51" style=""><span class="pln">fun fetchCitiesOfUsers</span><span class="pun">(</span><span class="pln">users</span><span class="pun">:</span><span class="pln"> </span><span class="typ">List</span><span class="pun">&lt;</span><span class="typ">KotlinUser</span><span class="pun">&gt;)</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> users
            </span><span class="pun">.</span><span class="pln">flatMap</span><span class="pun">(</span><span class="typ">KotlinUser</span><span class="pun">::</span><span class="pln">addresses</span><span class="pun">)</span><span class="pln">
            </span><span class="pun">.</span><span class="typ">map</span><span class="pun">(</span><span class="typ">Address</span><span class="pun">::</span><span class="pln">city</span><span class="pun">)</span><span class="pln">
            </span><span class="pun">.</span><span class="pln">toSet</span><span class="pun">()</span></pre>

<p>
	لا يوجد تحويل صريح للتسلسلات streams بما أنّ كل تجميعات Kotlin تدعمها.  كنتيجة مباشرة لذلك، لن يكون عليك تمرير لامبدا لـ flatMap. تجميع النتيجة يحدث تلقائيًّا (لا حاجة لاستدعاء الوظيفة *Collectors.to). واستخدامنا لـ toSet هنا سببه الوحيد أننا نريد إرجاع عنصر من نوع Set. وإلا فيمكن حذف.toSet()
</p>

<h3>
	توافقية جافا وKotlin 
</h3>

<p>
	يمكن أن يكون هذا معقدًا لمعظم النّاس، لكن JetBrains تعاملت مع هذا الأمر بالشكل الصحيح:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_5624_53" style=""><span class="kwd">public</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">KotlinInterop</span><span class="pln"> </span><span class="pun">{</span><span class="pln">

    </span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> helloJava</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        </span><span class="typ">System</span><span class="pun">.</span><span class="pln">out</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">"Hello from Java!"</span><span class="pun">);</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">

    </span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> helloKotlin</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        </span><span class="typ">JavaInterop</span><span class="pun">.</span><span class="pln">createInstance</span><span class="pun">().</span><span class="pln">helloKotlin</span><span class="pun">();</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_5624_55" style=""><span class="kwd">class</span><span class="pln"> </span><span class="typ">JavaInterop</span><span class="pln"> </span><span class="pun">{</span><span class="pln">

    fun helloJava</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        </span><span class="typ">KotlinInterop</span><span class="pun">().</span><span class="pln">helloJava</span><span class="pun">()</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">

    fun helloKotlin</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        println</span><span class="pun">(</span><span class="str">"Hello from Kotlin!"</span><span class="pun">)</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">

    companion object </span><span class="pun">{</span><span class="pln">

        </span><span class="lit">@JvmStatic</span><span class="pln">
        fun createInstance</span><span class="pun">()</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">JavaInterop</span><span class="pun">()</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	التداخل هنا سلس وسهل. جافا وKotlin يمكن أن يتعايشا معًا في نفس المشروع، كما يقدم Kotlin مجموعة من التعبيرات (مثل @JvmStatic) لتسهيل استدعاء كود Kotlin من الجافا دون أية مشاكل.
</p>

<p>
	قد تكون قد لاحظت من هذه الأمثلة أن Kotlin يستعير الأفكار الجيدة من جافا ويُحسّنها ويحاول أن يختصر عليك الوقت والعمل إلى أدنى حد ممكن. الأنباء الأخيرة حول اعتزام جوجل جعل Kotlin واحدةً من اللغات المعتمدة علىAndroid تدعم هذا التوجه أيضًا.
</p>

<h4>
	أشياء لتخبر بها مديرك:
</h4>

<p>
	إذا كنت ترغب في إعطاء Kotlin فرصة فإليك بعض النصائح التي ستساعدك عند التفاوض مع مديرك أو زملائك في الفريق:
</p>

<ul>
	<li>
		Kotlin خرج من عالم الصناعة، وليس من العالم الأكاديمي. فهو يحل المشاكل التي يواجها المبرمجون اليوم.
	</li>
	<li>
		حر ومفتوح المصدر
	</li>
	<li>
		يأتي ومعه أداة مفيدة لتحويل جافا إلى Kotlin
	</li>
	<li>
		يمكنك مزج Kotlin وجافا دون جهد يُذكر
	</li>
	<li>
		يمكنك استخدام جميع أدوات وأُطُر عمل جافا الموجودة
	</li>
	<li>
		Kotlin مدعوم من قبل أفضل بيئة عمل في السوق (مع نسخة مجانية)
	</li>
	<li>
		من السهل قراءته، فحتى المبرمجون غير المتخصصون في Kotlin يمكنهم مراجعة الأكواد المكتوبة به
	</li>
	<li>
		لا تحتاج إلى رهن مشروعك بـ Kotlin: يمكنك البدء في المرحلة الأولى بكتابة الاختبارات فيه.
	</li>
	<li>
		من غير المرجح أن تتخلى JetBrains عن Kotlin لأنه يُقوّي مبيعاتها
	</li>
	<li>
		Kotlin لديه مجتمع حيوي، كما يمكنك بسهولة أن تساهم في Kotlin وتقترح ميزات جديدة باستخدام <a href="https://github.com/Kotlin/KEEP" rel="external nofollow">KEEP</a>
	</li>
</ul>

<p>
	إذن، هل يستحق Kotlin الضجة المثارة حوله؟ الحكم لك.
</p>

<p>
	ترجمة -وبتصرّف- للمقال <a href="https://the-cogitator.com/posts/blog/2017/05/19/kotlin-is-the-new-java.html" rel="external nofollow">Kotlin is the new Java</a> لكاتبه Adam Arold
</p>
]]></description><guid isPermaLink="false">641</guid><pubDate>Wed, 19 Sep 2018 08:28:00 +0000</pubDate></item><item><title>&#x628;&#x64A;&#x626;&#x627;&#x62A; &#x62A;&#x637;&#x648;&#x64A;&#x631; &#x623;&#x646;&#x62F;&#x631;&#x648;&#x64A;&#x62F; &#x627;&#x644;&#x62A;&#x64A; &#x62A;&#x633;&#x62A;&#x62E;&#x62F;&#x645; &#x627;&#x644;&#x62A;&#x623;&#x634;&#x64A;&#x631; Annotation Processing &#x641;&#x64A; KOTLIN</title><link>https://academy.hsoub.com/programming/kotlin/%D8%A8%D9%8A%D8%A6%D8%A7%D8%AA-%D8%AA%D8%B7%D9%88%D9%8A%D8%B1-%D8%A3%D9%86%D8%AF%D8%B1%D9%88%D9%8A%D8%AF-%D8%A7%D9%84%D8%AA%D9%8A-%D8%AA%D8%B3%D8%AA%D8%AE%D8%AF%D9%85-%D8%A7%D9%84%D8%AA%D8%A3%D8%B4%D9%8A%D8%B1-annotation-processing-%D9%81%D9%8A-kotlin-r622/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2018_02/5a8a6876889fb_19-2(1).png.5daab468741980d6b924133f7279c286.png" /></p>

<p>
	في هذا الدرس سنتعلّم كيفية استخدام بيئات التطوير ومكتبات أندرويد الشهيرة التي تستخدم التأشير annotation processing في Kotlin.<br>
	يوجد في عالم الأندرويد العديد من بيئات التطوير الشهيرة التي تبسّط التطوير. يمكنك استخدام نفس البيئات لأجل التطوير في Kotlin كما تفعل في جافا. يقدم هذا الدرس بعض الأمثلة ويسلّط الضوء على الفروقات في الإعدادات.<br>
	سنلقي نظرة على <a href="https://kotlinlang.org/docs/tutorials/android-frameworks.html#dagger" rel="external nofollow">Dagger</a>, <a href="https://kotlinlang.org/docs/tutorials/android-frameworks.html#butterknife" rel="external nofollow">Butterknife</a>, <a href="https://kotlinlang.org/docs/tutorials/android-frameworks.html#data-binding" rel="external nofollow">Data Binding</a>, <a href="https://kotlinlang.org/docs/tutorials/android-frameworks.html#auto-parcel" rel="external nofollow">Auto-parcel</a> و <a href="https://kotlinlang.org/docs/tutorials/android-frameworks.html#dbflow" rel="external nofollow">DBFlow</a> (بقية بيئات التطوير يمكن إعدادها بشكل مماثل). كل بيئات التطوير هذه تعمل بنظام التأشير annotation processing: حيث تقوم بالتأشير على الشيفرة البرمجيّة وسيتمّ توليد أكواد جاهزة لأجلك. تقلّل التأشيرات من الإسهاب غير الضروري وتبسّط الشيفرة البرمجية، وإن كنت تريد أن تفهم ما الذي يحدث فعلا في وقت التنفيذ runtime، يمكنك إلقاء نظرة على الشيفرة التي تم إنشاؤها. تذكّر أن كل بيئات التطوير هذه تولّد الأكواد في جافا، وليس Kotlin.<br>
	في Kotlin تقوم بتحديد الارتباطات (dependencies بطريقة مماثلة لجافا باستخدام <a href="https://kotlinlang.org/docs/reference/kapt.html" rel="external nofollow">Kotlin Annotation processing tool</a> (<code>kapt</code> بدلاً من <code>annotationProcessor</code>.
</p>

<h2 id="dagger">
	Dagger
</h2>

<p>
	<a href="https://google.github.io/dagger/" rel="external nofollow">Dagger</a> هو بيئة تطوير تحقن الارتباطات dependency injection. إن لم يكن مألوفًا لديك، يمكنك القراءة عنه في <a href="https://google.github.io/dagger/users-guide.html" rel="external nofollow">دليل المستخدم</a>. لقد حوّلنا <a href="https://github.com/google/dagger/tree/master/examples/simple" rel="external nofollow">مثال القهوة</a> المذكور في هذا الدليل إلى Kotlin، ويمكنك إيجاد النتيجة <a href="https://github.com/JetBrains/kotlin-examples/tree/master/gradle/kotlin-dagger" rel="external nofollow">هنا</a>. الشيفرة البرمجية لـ Kotlin تبدو مشابهة إلى حد كبير للشيفرة الأصليّة. يمكنك تصفح المثال كله في <a href="https://github.com/JetBrains/kotlin-examples/tree/master/gradle/kotlin-dagger/src/main/kotlin/Coffee.kt" rel="external nofollow">ملف</a> واحد.<br>
	كما هو الحال في جافا، يمكنك استخدام<code>Inject@</code> للتأشير على المنشئ <code>constructor</code> المستخدم من قبل Dagger لإنشاء عيّنات <code>instances</code>من صنف ما. لدى Kotlin أسلوب مختصر للإعلان عن خاصية ما وعن معامل (parameter) منشئ ما في نفس الوقت. ولكي تؤشّر على المنشئ، استخدم الكلمة <code>constructor</code> بشكل صريح وضَع التأشير <code>Inject@</code> قبله:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1694_6" style="">
<span class="kwd">class</span><span class="pln"> </span><span class="typ">Thermosiphon</span><span class="pln"> 
</span><span class="lit">@Inject</span><span class="pln"> constructor</span><span class="pun">(</span><span class="pln">
        </span><span class="kwd">private</span><span class="pln"> val heater</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Heater</span><span class="pln">
</span><span class="pun">)</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><span class="typ">Pump</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="com">// ...</span><span class="pln">
</span><span class="pun">}</span><span class="pln"> </span></pre>

<p>
	التأشير على الوظائف methods يبدو تمامًا بنفس الشكل. في المثال التالي <code>Binds@</code> تحدّد أنّ الكائن <code>Thermosiphon</code> سيستخدم حيثما كان <code>Pump</code> مطلوبًا، تحدّد <code>Provides@</code> طريقة بناء Heater، كما توضّح <code>Singleton@</code> أنّ <code>Heater</code> نفسه ينبغي أن يستخدم في كل مكان:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1694_8" style="">
<span class="lit">@Module</span><span class="pln">
abstract </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">PumpModule</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="lit">@Binds</span><span class="pln">
    abstract fun providePump</span><span class="pun">(</span><span class="pln">pump</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Thermosiphon</span><span class="pun">):</span><span class="pln"> </span><span class="typ">Pump</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

</span><span class="lit">@Module</span><span class="pun">(</span><span class="pln">includes </span><span class="pun">=</span><span class="pln"> arrayOf</span><span class="pun">(</span><span class="typ">PumpModule</span><span class="pun">::</span><span class="kwd">class</span><span class="pun">))</span><span class="pln">
</span><span class="kwd">class</span><span class="pln"> </span><span class="typ">DripCoffeeModule</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="lit">@Provides</span><span class="pln"> </span><span class="lit">@Singleton</span><span class="pln">
    fun provideHeater</span><span class="pun">():</span><span class="pln"> </span><span class="typ">Heater</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">ElectricHeater</span><span class="pun">()</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	الأصناف المؤشّرة بـ <code>Module@</code> تحدّد كيفية توفير مختلف الكائنات. انتبه إلى أنه عند تمرير معامل تأشير (<code>annotation argument</code>) كمعامل <code>vararg</code>، فسيكون عليك أن تغلّفه بـ <code>arrayOf</code>، كما هو الحال في (<code>Module(includes = arrayOf(PumpModule::class)@</code> أعلاه.<br>
	لكي يتمّ توليد تطبيق محقون الارتباط (dependency-injected implementation) لأجل نوع ما, قم بالتأشير عليه بـ <code>Component@</code>. الصّنف المُولّد سيكون له اسم هذا النوع مسبوقًا بـ <code>Dagger</code>، مثل <code>DaggerCoffeeShop</code><br>
	أدناه:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1694_10" style="">
<span class="lit">@Singleton</span><span class="pln">
</span><span class="lit">@Component</span><span class="pun">(</span><span class="pln">modules </span><span class="pun">=</span><span class="pln"> arrayOf</span><span class="pun">(</span><span class="typ">DripCoffeeModule</span><span class="pun">::</span><span class="kwd">class</span><span class="pun">))</span><span class="pln">
interface </span><span class="typ">CoffeeShop</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    fun maker</span><span class="pun">():</span><span class="pln"> </span><span class="typ">CoffeeMaker</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

fun main</span><span class="pun">(</span><span class="pln">args</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Array</span><span class="pun">&lt;</span><span class="typ">String</span><span class="pun">&gt;)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    val coffee </span><span class="pun">=</span><span class="pln"> </span><span class="typ">DaggerCoffeeShop</span><span class="pun">.</span><span class="pln">builder</span><span class="pun">().</span><span class="pln">build</span><span class="pun">()</span><span class="pln">
    coffee</span><span class="pun">.</span><span class="pln">maker</span><span class="pun">().</span><span class="pln">brew</span><span class="pun">()</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	يقوم Dagger بتوليد تطبيق لـ <code>CoffeeShop</code> والذي يسمح لك بالحصول على صنف <code>CoffeeMaker</code> محقون بالكامل. يمكنك التنقل ومشاهدة تطبيق <code>DaggerCoffeeShop</code> إذا قمت بفتح المشروع في بيئة التطوير.<br>
	لاحظنا أن التأشير على الأكواد البرمجية لم يتغيّر تقريبًا عند التحوّل إلى Kotlin. الآن دعونا نرى التغييرات التي ينبغي إدخالها على نص البناء البرمجي.<br>
	في جافا تقوم بربط Dagger بـ <code>annotationProcessor</code> (أو apt):
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1694_12" style="">
<span class="pln">dependencies </span><span class="pun">{</span><span class="pln">
  </span><span class="pun">...</span><span class="pln">
  annotationProcessor </span><span class="str">"com.google.dagger:dagger-compiler:$dagger-version"</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	في Kotlin عليك إضافة ملحقة <code>kotlin-kapt</code> لإتاحة <code>kapt</code>, ثم قم باستبدال <code>annotationProcessor</code> بـ <code>kapt</code>:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1694_14" style="">
<span class="pln">apply plugin</span><span class="pun">:</span><span class="pln"> </span><span class="str">'kotlin-kapt'</span><span class="pln">
dependencies </span><span class="pun">{</span><span class="pln">
    </span><span class="pun">...</span><span class="pln">
    kapt </span><span class="str">"com.google.dagger:dagger-compiler:$dagger-version"</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	هذا كل شيء! لاحظ أن <code>kapt</code> يعتني بملفات جافا كذلك، لذلك لا تحتاج الإبقاء على الارتباط بـ <code>annotationProcessor</code>.<br>
	النص البرمجي الكامل لبناء لهذا المشروع يمكن العثور عليه <a href="https://github.com/JetBrains/kotlin-examples/tree/master/gradle/kotlin-dagger/build.gradle" rel="external nofollow">هنا</a> . يمكنك أيضا الاطّلاع على الكود البرمجي المحوَّل <a href="https://github.com/JetBrains/kotlin-examples/tree/master/gradle/android-dagger" rel="external nofollow">لأندرويد</a>.
</p>

<h2 id="butterknife">
	ButterKnife
</h2>

<p>
	يسمح <a href="http://jakewharton.github.io/butterknife/" rel="external nofollow">ButterKnife</a> بربط العروض views بالحقول مباشرة بدلاً من استدعاء <code>findViewById</code>.<br>
	لاحظ أن ملحقات أندرويد الإضافية لـ Kotlin (مُدمجة تلقائيًا في ملحقة Kotlin في أندرويد ستوديو) تحل المسألة نفسها: استبدال <code>findViewById</code> بكود برمجي موجز وواضح. ربّما عليك استخدامه إلا إذا كنت تستخدم <code>ButterKnife</code> سلفًا ولا تنوي الهجرة.<br>
	يمكنك استخدام <code>ButterKnife</code> مع Kotlin بنفس طريقة استخدامه مع جافا. دعونا نرى أوّلا التغيرات التي طرأت على نص البناء البرمجي في Gradle، ومن ثم تسليط الضوء على بعض الاختلافات في الكود البرمجي.<br>
	في ارتباطات Gradle استخدم الملحقة <code>kotlin-kapt</code> وقم باستبدال <code>annotationProcessor</code> بـ <code>kapt</code>:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1694_16" style="">
<span class="pln">apply plugin</span><span class="pun">:</span><span class="pln"> </span><span class="str">'kotlin-kapt'</span><span class="pln">

dependencies </span><span class="pun">{</span><span class="pln">
    </span><span class="pun">...</span><span class="pln">
    compile </span><span class="str">"com.jakewharton:butterknife:$butterknife-version"</span><span class="pln">
    kapt </span><span class="str">"com.jakewharton:butterknife-compiler:$butterknife-version"</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	لقد قمنا بتحويل <a href="https://github.com/JakeWharton/butterknife/tree/master/sample/app/src/main/java/com/example" rel="external nofollow">عيّنة</a> <code>ButterKnife</code> إلى Kotlin. يمكن العثور على الكود الناتج <a href="https://github.com/JetBrains/kotlin-examples/tree/master/gradle/android-butterknife" rel="external nofollow">هنا</a>.<br>
	دعونا نلقي نظرة أكثر عليه لمعرفة ما الذي تغيّر. في جافا تؤشّر على الحقل وتربطه بالعرض view المقابل:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1694_18" style="">
<span class="lit">@BindView</span><span class="pun">(</span><span class="pln">R2</span><span class="pun">.</span><span class="pln">id</span><span class="pun">.</span><span class="pln">title</span><span class="pun">)</span><span class="pln"> </span><span class="typ">TextView</span><span class="pln"> title</span><span class="pun">;</span></pre>

<p>
	في Kotlin لا يمكنك العمل مع الحقول مباشرة، ولكن بدل ذلك يمكنك العمل مع الخصائص. حيث تؤشّر على الخاصّية:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1694_21" style="">
<span class="lit">@BindView</span><span class="pun">(</span><span class="pln">R2</span><span class="pun">.</span><span class="pln">id</span><span class="pun">.</span><span class="pln">title</span><span class="pun">)</span><span class="pln">
lateinit var title</span><span class="pun">:</span><span class="pln"> </span><span class="typ">TextView</span></pre>

<p>
	يتم تعريف التأشير <code>BindView@</code> ليتم تطبيقه على الحقول فقط، مُترجم Kotlin يدرك هذا ويقوم بالتأشير على الحقل المقابل تلقائيا عندما تقوم بالتأشير على كامل الخاصيّة.<br>
	لاحظ كيف أن مُعدِّل <code>lateinit</code> يسمح بالتصريح بأنواع غير معدومة<code>non-null</code> مُبتدَأً (<code>initialized</code>) بعد إنشاء الكائن (بعد استدعاء المنشئ). بدون <code>lateinit</code> سيكون عليك أن تُصرّح بنوع ذي قيمة معدومةً (<code>nullable type</code>) وتقوم بإضافة تحقيقات إضافية لاختبار العدميّة <code>nullability</code>.<br>
	يمكنك أيضًا إعداد الوظائف كمُصغيات <code>listeners</code>، باستخدام تأشيرات <code>ButterKnife</code>:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1694_23" style="">
<span class="lit">@OnClick</span><span class="pun">(</span><span class="pln">R2</span><span class="pun">.</span><span class="pln">id</span><span class="pun">.</span><span class="pln">hello</span><span class="pun">)</span><span class="pln">
internal fun sayHello</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="typ">Toast</span><span class="pun">.</span><span class="pln">makeText</span><span class="pun">(</span><span class="kwd">this</span><span class="pun">,</span><span class="pln"> </span><span class="str">"Hello, views!"</span><span class="pun">,</span><span class="pln"> LENGTH_SHORT</span><span class="pun">).</span><span class="pln">show</span><span class="pun">()</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	يحدد هذا الكود إجراءً ليتم تنفيذه عند النقر على الزر “hello”. لاحظ أنه باستخدام صيغة <code>lambdas</code> فإن الكود يبدو موجزًا عند كتابته مباشرةً في Kotlin:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1694_27" style="">
<span class="pln">hello</span><span class="pun">.</span><span class="pln">setOnClickListener </span><span class="pun">{</span><span class="pln">
    toast</span><span class="pun">(</span><span class="str">"Hello, views!"</span><span class="pun">)</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	الدالّة toast مُعرّفة في المكتبة <a href="https://github.com/Kotlin/anko" rel="external nofollow">Anko</a> .
</p>

<h2 id="ربط-البيانات">
	ربط البيانات
</h2>

<p>
	مكتبة ربط البيانات تسمح لك بربط بيانات تطبيقك بالخُطاطةlayouts بطريقة موجزة.<br>
	يمكنك إتاحة المكتبة باستخدام نفس الإعدادات في جافا:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1694_25" style="">
<span class="pln">android </span><span class="pun">{</span><span class="pln">
    </span><span class="pun">...</span><span class="pln">
    dataBinding </span><span class="pun">{</span><span class="pln">
        enabled </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">true</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	لجعله يعمل مع أصناف Kotlin قم بإضافة الارتباط <code>kapt</code>:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1694_29" style="">
<span class="pln">apply plugin</span><span class="pun">:</span><span class="pln"> </span><span class="str">'kotlin-kapt'</span><span class="pln">
dependencies </span><span class="pun">{</span><span class="pln">
    kapt </span><span class="str">"com.android.databinding:compiler:$android_plugin_version"</span><span class="pln">
</span><span class="pun">}</span><span class="pln"> </span></pre>

<p>
	عند التبديل إلى Kotlin، لا تتغير ملفات خطاطة<code>xml</code> على الإطلاق. على سبيل المثال، يمكنك استخدام <code>variable</code>في <code>data</code> لوصف متغير يمكن استخدامه في الخطاطة. يمكنك تعريف متغير من نوع Kotlin:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1694_31" style="">
<span class="str">&lt;data&gt;</span><span class="pln">
    </span><span class="pun">&lt;</span><span class="pln">variable name</span><span class="pun">=</span><span class="str">"data"</span><span class="pln"> type</span><span class="pun">=</span><span class="str">"org.example.kotlin.databinding.WeatherData"</span><span class="pun">/&gt;</span><span class="pln">
</span><span class="pun">&lt;/</span><span class="pln">data</span><span class="pun">&gt;</span></pre>

<p>
	يمكنك استخدام الصيغة <code>{}@</code> لكتابة العبارات، بحيث يمكن الإحالة إلى خصائص Kotlin :
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1694_33" style="">
<span class="pun">&lt;</span><span class="typ">ImageView</span><span class="pln">
    android</span><span class="pun">:</span><span class="pln">layout_width</span><span class="pun">=</span><span class="str">"wrap_content"</span><span class="pln">
    android</span><span class="pun">:</span><span class="pln">layout_height</span><span class="pun">=</span><span class="str">"wrap_content"</span><span class="pln">
    android</span><span class="pun">:</span><span class="pln">src</span><span class="pun">=</span><span class="str">"@{data.imageUrl}"</span><span class="pln">
    android</span><span class="pun">:</span><span class="pln">contentDescription</span><span class="pun">=</span><span class="str">"@string/image"</span><span class="pln"> </span><span class="pun">/&gt;</span></pre>

<p>
	لاحظ أن لغة التعبير عن ربط البيانات تستخدم نفس القواعد للإحالة إلى الخصائص كما هو الحال في Kotlin، أي: <code>data.imageUrl</code> . في Kotlin يمكنك كتابة <code>v.prop</code> بدلا من <code>()v.getProp</code> حتى لو كانت <code>()getProp</code> من وظائف جافا. وبالمثل، بدلًا من استدعاء مُحدِّدٍ setter مباشرة، فيمكنك استخدام الإحالة:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1694_35" style="">
<span class="kwd">class</span><span class="pln"> </span><span class="typ">MainActivity</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><span class="typ">AppCompatActivity</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="com">// ...</span><span class="pln">
    override fun onCreate</span><span class="pun">(</span><span class="pln">savedInstanceState</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Bundle</span><span class="pun">?)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        super</span><span class="pun">.</span><span class="pln">onCreate</span><span class="pun">(</span><span class="pln">savedInstanceState</span><span class="pun">)</span><span class="pln">
        val binding</span><span class="pun">:</span><span class="pln"> </span><span class="typ">ActivityMainBinding</span><span class="pln"> </span><span class="pun">=</span><span class="pln">
                </span><span class="typ">DataBindingUtil</span><span class="pun">.</span><span class="pln">setContentView</span><span class="pun">(</span><span class="kwd">this</span><span class="pun">,</span><span class="pln"> R</span><span class="pun">.</span><span class="pln">layout</span><span class="pun">.</span><span class="pln">activity_main</span><span class="pun">)</span><span class="pln">

        binding</span><span class="pun">.</span><span class="pln">data </span><span class="pun">=</span><span class="pln"> weather
        </span><span class="com">// the same as</span><span class="pln">
        </span><span class="com">// binding.setData(weather)</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	يمكنك ربط مُصغي لإطلاق إجراء ما عندما يحدث حدث معين:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1694_37" style="">
<span class="pun">&lt;</span><span class="typ">Button</span><span class="pln">
    android</span><span class="pun">:</span><span class="pln">text</span><span class="pun">=</span><span class="str">"@string/next"</span><span class="pln">
    android</span><span class="pun">:</span><span class="pln">layout_width</span><span class="pun">=</span><span class="str">"match_parent"</span><span class="pln">
    android</span><span class="pun">:</span><span class="pln">layout_height</span><span class="pun">=</span><span class="str">"wrap_content"</span><span class="pln">
    android</span><span class="pun">:</span><span class="pln">onClick</span><span class="pun">=</span><span class="str">"startOtherActivity"</span><span class="pln"> </span><span class="pun">/&gt;</span></pre>

<p>
	هنا <code>startOtherActivity</code> هي وظيفة محددة في النشاط الرئيسي <code>MainActivity</code>:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1694_39" style="">
<span class="kwd">class</span><span class="pln"> </span><span class="typ">MainActivity</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><span class="typ">AppCompatActivity</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="com">// ...</span><span class="pln">
    fun startOtherActivity</span><span class="pun">(</span><span class="pln">view</span><span class="pun">:</span><span class="pln"> </span><span class="typ">View</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> startActivity</span><span class="pun">&lt;</span><span class="typ">OtherActivity</span><span class="pun">&gt;()</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
 </span></pre>

<p>
	يستخدم هذا المثال الدالة <code>startActivity</code> التي تنشئ نيّة <code>intent</code> بدون بيانات وتبدأ نشاطًا جديدًا، والذي يأتي من المكتبة Anko. لأجل تمرير البيانات يمكنك كتابة (<code>startActivity&lt;OtherActivity&gt;("KEY" to "VALUE"</code>.
</p>

<p>
	لاحظ أنه بدلًا من الإعلان باستخدام <code>lambdas</code> في <code>xml</code> كما في المثال التالي، يمكنك ربط الإجراءات مباشرةً في الكود البرمجي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1694_41" style="">
<span class="pun">&lt;</span><span class="typ">Button</span><span class="pln"> 
    android</span><span class="pun">:</span><span class="pln">layout_width</span><span class="pun">=</span><span class="str">"wrap_content"</span><span class="pln"> 
    android</span><span class="pun">:</span><span class="pln">layout_height</span><span class="pun">=</span><span class="str">"wrap_content"</span><span class="pln">
    android</span><span class="pun">:</span><span class="pln">onClick</span><span class="pun">=</span><span class="str">"@{() -&gt; presenter.onSaveClick(task)}"</span><span class="pln"> </span><span class="pun">/&gt;</span></pre>

<p>
	 
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1694_43" style="">
<span class="com">// the same logic written in Kotlin code</span><span class="pln">
button</span><span class="pun">.</span><span class="pln">setOnClickListener </span><span class="pun">{</span><span class="pln"> presenter</span><span class="pun">.</span><span class="pln">onSaveClick</span><span class="pun">(</span><span class="pln">task</span><span class="pun">)</span><span class="pln"> </span><span class="pun">}</span></pre>

<p>
	في السّطر الأخير تم تحديد button بالرّجوع إلى رقم تعريفها id باستخدام ملحقة أندرويد لـ Kotlin. يمكنك استخدام هذه الملحقة كبديل وهو ما سيسمح لك بالحفاظ على منطق الربط في الكود البرمجي والحصول على نص برمجي موجز في نفس الوقت.<br>
	يمكنك العثور على مشروع تمثيليّ <a href="https://github.com/JetBrains/kotlin-examples/tree/master/gradle/android-databinding" rel="external nofollow">هنا</a>.
</p>

<h2 id="dbflow">
	DBFlow
</h2>

<p>
	<a href="https://github.com/Raizlabs/DBFlow" rel="external nofollow">DBFlow</a> هي مكتبةSQLite تسمح بتبسيط التفاعل مع قواعد البيانات. كما تعتمد بشكل كبير على التأشير.<br>
	لاستخدامها مع Kotlin قم بإعداد ارتباطات التأشير باستخدام <code>kapt</code>:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1694_45" style="">
<span class="pln">apply plugin</span><span class="pun">:</span><span class="pln"> </span><span class="str">'kotlin-kapt'</span><span class="pln">

dependencies </span><span class="pun">{</span><span class="pln">
    kapt </span><span class="str">"com.github.raizlabs.dbflow:dbflow-processor:$dbflow_version"</span><span class="pln">
    compile </span><span class="str">"com.github.raizlabs.dbflow:dbflow-core:$dbflow_version"</span><span class="pln">
    compile </span><span class="str">"com.github.raizlabs.dbflow:dbflow:$dbflow_version"</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	إن كان تطبيقك يستخدم بالفعل <code>DBFlow</code>، فيمكنك إقحام Kotlin في المشروع بدون مشاكل. يمكنك التّحويل التّدريجي لأكوادك البرمجية الموجودة إلى Kotlin (لضمان ترجمة كل شيء بشكل متناسق). الكود البرمجي المُحوّل لا يختلف كثيرا عن نظيره في جافا. على سبيل المثال، التصريح بجدول يبدو مشابهًا لجافا مع فارق صغير يتمثّل في أنّ القيم الافتراضية للخصائص يجب تحديدها صراحة:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1694_47" style="">
<span class="lit">@Table</span><span class="pun">(</span><span class="pln">name</span><span class="pun">=</span><span class="str">"users"</span><span class="pun">,</span><span class="pln"> database </span><span class="pun">=</span><span class="pln"> </span><span class="typ">AppDatabase</span><span class="pun">::</span><span class="kwd">class</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">class</span><span class="pln"> </span><span class="typ">User</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><span class="typ">BaseModel</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">

    </span><span class="lit">@PrimaryKey</span><span class="pun">(</span><span class="pln">autoincrement </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">true</span><span class="pun">)</span><span class="pln">
    </span><span class="lit">@Column</span><span class="pun">(</span><span class="pln">name </span><span class="pun">=</span><span class="pln"> </span><span class="str">"id"</span><span class="pun">)</span><span class="pln">
    var id</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Long</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pln">

    </span><span class="lit">@Column</span><span class="pln">
    var name</span><span class="pun">:</span><span class="pln"> </span><span class="typ">String</span><span class="pun">?</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> null
</span><span class="pun">}</span></pre>

<p>
	بالإضافة إلى تحويل الوظائف الموجودة إلى Kotlin، يمكنك أيضًا الاستفادة من الدعم الخاص بـ Kotlin. على سبيل المثال، يمكن أن تقوم بتعريف الجداول كـ أصناف بيانات data classes.
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1694_49" style="">
<span class="lit">@Table</span><span class="pun">(</span><span class="pln">database </span><span class="pun">=</span><span class="pln"> </span><span class="typ">KotlinDatabase</span><span class="pun">::</span><span class="kwd">class</span><span class="pun">)</span><span class="pln">
data </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">User</span><span class="pun">(</span><span class="lit">@PrimaryKey</span><span class="pln"> var id</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Long</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">@Column</span><span class="pln"> var name</span><span class="pun">:</span><span class="pln"> </span><span class="typ">String</span><span class="pun">?</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> null</span><span class="pun">)</span></pre>

<p>
	يعرّف <code>DBFlow</code> مجموعة من الإضافات لجعل استخدامه في Kotlin أكثر سلاسةً، بحيث يمكنك إدراجه في الارتباطات خاصتك:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1694_51" style="">
<span class="pln">dependencies </span><span class="pun">{</span><span class="pln">
    compile </span><span class="str">"com.github.raizlabs.dbflow:dbflow-kotlinextensions:$dbflow_version"</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	هذا سيمنحك وسيلة للتعبير عن الاستعلامات بأسلوب مشابه لـ C#/LINQ ، استخدم lambdas لكتابة أكواد أبسط بكثير لأجل العمليّات المتزامنة وغيرها.
</p>

<h2 id="التّحزيم-التلقائي-auto-parcel">
	التّحزيم التلقائي Auto-Parcel
</h2>

<p>
	يسمح التحزيم التلقائي بتوليد قيم محزومة Parcelable من الأصناف المؤشّرة بـ <code>AutoValue@</code>.<br>
	عند تحديد الارتباطات <code>dependency</code> استخدم مرةً أخرى <code>kapt</code> كمُؤشّر لمعالجة ملفات Kotlin:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1694_53" style="">
<span class="pln">apply plugin</span><span class="pun">:</span><span class="pln"> </span><span class="str">'kotlin-kapt'</span><span class="pln">

dependencies </span><span class="pun">{</span><span class="pln">
    </span><span class="pun">...</span><span class="pln">
    kapt </span><span class="str">"frankiesardo:auto-parcel:$latest-version"</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	يمكنك العثور على <a href="https://github.com/frankiesardo/auto-parcel/tree/master/sample" rel="external nofollow">النّموذج</a> المُحوّل من <a href="https://github.com/JetBrains/kotlin-examples/tree/master/gradle/android-auto-parcel" rel="external nofollow">هنا</a>.<br>
	يمكنك التأشير على أصناف Kotlin بـ <code>AutoValue@</code>. دعونا نلقي نظرة على الصّنف المحوّل<code>Address</code> الذي سيتمّ توليد صياغته المحزومة Parcelable implementation :
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1694_55" style="">
<span class="lit">@AutoValue</span><span class="pln">
abstract </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">Address</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><span class="typ">Parcelable</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    abstract fun coordinates</span><span class="pun">():</span><span class="pln"> </span><span class="typ">DoubleArray</span><span class="pln">
    abstract fun cityName</span><span class="pun">():</span><span class="pln"> </span><span class="typ">String</span><span class="pln">

    companion object </span><span class="pun">{</span><span class="pln">
        fun create</span><span class="pun">(</span><span class="pln">coordinates</span><span class="pun">:</span><span class="pln"> </span><span class="typ">DoubleArray</span><span class="pun">,</span><span class="pln"> cityName</span><span class="pun">:</span><span class="pln"> </span><span class="typ">String</span><span class="pun">):</span><span class="pln"> </span><span class="typ">Address</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
            </span><span class="kwd">return</span><span class="pln"> builder</span><span class="pun">().</span><span class="pln">coordinates</span><span class="pun">(</span><span class="pln">coordinates</span><span class="pun">).</span><span class="pln">cityName</span><span class="pun">(</span><span class="pln">cityName</span><span class="pun">).</span><span class="pln">build</span><span class="pun">()</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">
        
        fun builder</span><span class="pun">():</span><span class="pln"> </span><span class="typ">Builder</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="pun">`</span><span class="pln">$AutoValue_Address</span><span class="pun">`.</span><span class="typ">Builder</span><span class="pun">()</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
    
    </span><span class="lit">@AutoValue</span><span class="pun">.</span><span class="typ">Builder</span><span class="pln">
    interface </span><span class="typ">Builder</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        fun coordinates</span><span class="pun">(</span><span class="pln">x</span><span class="pun">:</span><span class="pln"> </span><span class="typ">DoubleArray</span><span class="pun">):</span><span class="pln"> </span><span class="typ">Builder</span><span class="pln">
        fun cityName</span><span class="pun">(</span><span class="pln">x</span><span class="pun">:</span><span class="pln"> </span><span class="typ">String</span><span class="pun">):</span><span class="pln"> </span><span class="typ">Builder</span><span class="pln">
        fun build</span><span class="pun">():</span><span class="pln"> </span><span class="typ">Address</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	ليس لـ Kotlin وظائف ثابتة static methods، لذلك ينبغي تضمينها داخل كائن مرافق. إذا كنت مصرًّا على استخدامها من داخل الأكواد البرمجية لجافا، قم بالتأشير عليهم بـ <code>JvmStatic</code>.<br>
	إن كنت ترغب في الوصول إلى صنف أو وظيفة من جافا باسم غير صالح في Kotlin، يمكنك تمرير الاسم داخل علامتي تنصيص (``)، كما هو الحال مع الصّنف التي تم إنشاؤه <code>AutoValue_Address$</code>.<br>
	عمومًا الكود البرمجي المُحوّل يبدو مشابها كثيرا لكود جافا الأصلي.
</p>

<p>
	ترجمة -وبتصرّف- للمقال <a href="https://kotlinlang.org/docs/tutorials/android-frameworks.html" rel="external nofollow">Android Frameworks Using Annotation Processing</a> من توثيقيات KOTLIN
</p>

<p>
	هذا المقال منشور تحت رخصة  <a href="https://github.com/JetBrains/kotlin-web-site/blob/master/LICENSE" rel="external nofollow">Apache 2 license</a>
</p>
]]></description><guid isPermaLink="false">622</guid><pubDate>Mon, 19 Feb 2018 06:10:24 +0000</pubDate></item><item><title>&#x625;&#x636;&#x627;&#x641;&#x627;&#x62A; &#x623;&#x646;&#x62F;&#x631;&#x648;&#x64A;&#x62F; &#x644;&#x644;&#x63A;&#x629; &#x627;&#x644;&#x628;&#x631;&#x645;&#x62C;&#x629; Kotlin</title><link>https://academy.hsoub.com/programming/kotlin/%D8%A5%D8%B6%D8%A7%D9%81%D8%A7%D8%AA-%D8%A3%D9%86%D8%AF%D8%B1%D9%88%D9%8A%D8%AF-%D9%84%D9%84%D8%BA%D8%A9-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D8%A9-kotlin-r618/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2018_02/5a7c9c60b2980_12-2(1).png.b995fac5788b6c1250f707d00696364a.png" /></p>

<p>
	يصف هذا الدرس كيفية استخدام إضافات أندرويد فيKotlin لتحسين دعم تطوير أندرويد. في هذا الدرس سوف نستعرض الخطوات اللازمة لاستخدام ملحقات أندرويد الإضافية في لغة البرمجة Kotlin، لتعزيز تجربة التطوير في أندرويد.
</p>

<h2 id="ربط-العرض-view-binding">
	ربط العرض View Binding
</h2>

<h3 id="الخلفية">
	الخلفية
</h3>

<p>
	كل مطوري أندرويد يعرفون جيدًا الدالة <code>()findViewById</code>. والتي هي من دون أدنى شك، مصدر لكثير من المتاعب والأخطاء المحتملة والشيفرات السيئة والتي يصعب قراءتها وصيانتها. صحيح أن هناك العديد من المكتبات المتاحة لتوفير حلول لهذه المشكلة، إلّا أن هذه المكتبات تتطلب حقول تأشير annotating fields لكل عنصر معروض من نوع View.<br>
	توفر لنا ملحقات أندرويد الإضافية لـ Kotlin تجربة مماثلة لما توفره بعض تلك المكتبات، دون أن نكون في حاجة إلى كتابة شيفرات إضافية.<br>
	في الأساس، هذا يسمح لنا بكتابة الشيفرة التالية:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1030_7" style="">
<span class="com">// Using R.layout.activity_main from the 'main' source set</span><span class="pln">
</span><span class="kwd">import</span><span class="pln"> kotlinx</span><span class="pun">.</span><span class="pln">android</span><span class="pun">.</span><span class="pln">synthetic</span><span class="pun">.</span><span class="pln">main</span><span class="pun">.</span><span class="pln">activity_main</span><span class="pun">.*</span><span class="pln">

</span><span class="kwd">class</span><span class="pln"> </span><span class="typ">MyActivity</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><span class="typ">Activity</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    override fun onCreate</span><span class="pun">(</span><span class="pln">savedInstanceState</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Bundle</span><span class="pun">?)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        super</span><span class="pun">.</span><span class="pln">onCreate</span><span class="pun">(</span><span class="pln">savedInstanceState</span><span class="pun">)</span><span class="pln">
        setContentView</span><span class="pun">(</span><span class="pln">R</span><span class="pun">.</span><span class="pln">layout</span><span class="pun">.</span><span class="pln">activity_main</span><span class="pun">)</span><span class="pln">
        
        </span><span class="com">// Instead of findViewById&lt;TextView&gt;(R.id.textView)</span><span class="pln">
        textView</span><span class="pun">.</span><span class="pln">setText</span><span class="pun">(</span><span class="str">"Hello, world!"</span><span class="pun">)</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	<code>textView</code> هي خاصية إضافية لـ Activity، ولها نفس النوع المعلن في <code>activity_main.xml</code> (أي <code>TextView</code>).
</p>

<h2 id="استخدام-إضافات-أندرويد-لـkotlin">
	استخدام إضافات أندرويد لـKotlin
</h2>

<h3 id="إعداد-الارتباطات--------------configuring-the-dependency">
	إعداد الارتباطات Configuring the Dependency
</h3>

<p>
	سنستخدم في هذا الدرس Gradle، لكن يمكنك تحقيق نفس النتائج باستخدام IntelliJ IDEA project structure أو Maven.<br>
	إضافات أندرويد هي جزء من ملحقة Kotlin الخاصة بكل من IntelliJ IDEA وAndroid Studio. لذلك لا تحتاج إلى تثبيت ملحقات إضافية.<br>
	كل ما تحتاجه هو إتاحة ملحقة Gradle لأندرويد في ملف الوحدة <code>build.gradle</code>:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1030_9" style="">
<span class="pln">apply plugin</span><span class="pun">:</span><span class="pln"> </span><span class="str">'kotlin-android-extensions'</span></pre>

<h3 id="استيراد-الخصائص-التركيبية-synthetic-properties">
	استيراد الخصائص التركيبية synthetic properties
</h3>

<p>
	من الملائم استيراد جميع خصائص الودجةwidget) ) لخطاطة (layout) معينة دفعة واحدة:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1030_11" style="">
<span class="kwd">import</span><span class="pln"> kotlinx</span><span class="pun">.</span><span class="pln">android</span><span class="pun">.</span><span class="pln">synthetic</span><span class="pun">.</span><span class="pln">main</span><span class="pun">.&lt;</span><span class="pln">layout</span><span class="pun">&gt;.*</span></pre>

<p>
	وهكذا إذا كان اسم ملف الخطاطة هو <code>activity_main.xml</code>، فسنقوم باستيراد
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1030_41" style="">
<span class="pln">kotlinx</span><span class="pun">.</span><span class="pln">android</span><span class="pun">.</span><span class="pln">synthetic</span><span class="pun">.</span><span class="pln">main</span><span class="pun">.</span><span class="pln">activity_main</span><span class="pun">.*</span></pre>

<p>
	إن كنّا نريد أن نستدعي الخصائص التركيبية على View، فيجب علينا أيضًا استيراد
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1030_43" style="">
<span class="pln">kotlinx</span><span class="pun">.</span><span class="pln">android</span><span class="pun">.</span><span class="pln">synthetic</span><span class="pun">.</span><span class="pln">main</span><span class="pun">.</span><span class="pln">activity_main</span><span class="pun">.</span><span class="pln">view</span><span class="pun">.*</span></pre>

<p>
	وبمجرد أن نفعل ذلك، يمكننا حينها استدعاء الإضافات المقابلة والتي هي اسماء خصائص سُمّيت على إثر عناصر العرضviews الموجودة في ملف XML. فعلى سبيل المثال، بالنسبة لهذا العرض:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1030_13" style="">
<span class="pln">    </span><span class="pun">&lt;</span><span class="typ">TextView</span><span class="pln">
        android</span><span class="pun">:</span><span class="pln">id</span><span class="pun">=</span><span class="str">"@+id/hello"</span><span class="pln">
        android</span><span class="pun">:</span><span class="pln">layout_width</span><span class="pun">=</span><span class="str">"fill_parent"</span><span class="pln">
        android</span><span class="pun">:</span><span class="pln">layout_height</span><span class="pun">=</span><span class="str">"wrap_content"</span><span class="pun">/&gt;</span></pre>

<p>
	ستكون هناك خاصية اسمها <code>hello</code>:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1030_15" style="">
<span class="pln">activity</span><span class="pun">.</span><span class="pln">hello</span><span class="pun">.</span><span class="pln">text </span><span class="pun">=</span><span class="pln"> </span><span class="str">"Hello World!"</span></pre>

<h3 id="الوضع-التجريبي-experimental-mode">
	الوضع التجريبي Experimental Mode
</h3>

<p>
	تشمل الملحقات الإضافية لأندرويد العديد من الميزات التجريبية مثل دعم LayoutContainer ومولّدات تقديم الصنف Parcelable (Parcelable implementation generator). هذه الميزات لا تُعتبر جاهزة بعدُ للإنتاج، لذلك نحتاج إلى التحوّل للوضع التجريبي في <code>build.gradle</code> من أجل استخدامها:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1030_17" style="">
<span class="pln">androidExtensions </span><span class="pun">{</span><span class="pln">
    experimental </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">true</span><span class="pln">
</span><span class="pun">}</span></pre>

<h3 id="دعم-layoutcontainer">
	دعم LayoutContainer
</h3>

<p>
	تدعم الملحقات الإضافية لأندرويد أنواع مختلفة من الحاويات containers. وأبسط تلك الحاويات <a href="https://developer.android.com/reference/android/app/Activity.html" rel="external nofollow">Activity</a>، <a href="https://developer.android.com/reference/android/support/v4/app/Fragment.html" rel="external nofollow">Fragment</a> و<a href="https://developer.android.com/reference/android/view/View.html" rel="external nofollow">View</a>. ولكن يمكنك أن تحوّل (افتراضيًا) أي صنف إلى حاوية لإضافات أندرويد من خلال تطبيق الواجهةLayoutContainer ، على سبيل المثال:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1030_19" style="">
<span class="kwd">import</span><span class="pln"> kotlinx</span><span class="pun">.</span><span class="pln">android</span><span class="pun">.</span><span class="pln">extensions</span><span class="pun">.</span><span class="typ">LayoutContainer</span><span class="pln">

</span><span class="kwd">class</span><span class="pln"> </span><span class="typ">ViewHolder</span><span class="pun">(</span><span class="pln">override val containerView</span><span class="pun">:</span><span class="pln"> </span><span class="typ">View</span><span class="pun">)</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><span class="typ">ViewHolder</span><span class="pun">(</span><span class="pln">containerView</span><span class="pun">),</span><span class="pln"> </span><span class="typ">LayoutContainer</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    fun setup</span><span class="pun">(</span><span class="pln">title</span><span class="pun">:</span><span class="pln"> </span><span class="typ">String</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        itemTitle</span><span class="pun">.</span><span class="pln">text </span><span class="pun">=</span><span class="pln"> </span><span class="str">"Hello World!"</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	لاحظ أنك تحتاج إلى التحوّل إلى الوضع التجريبي لاستخدام LayoutContainer.
</p>

<h3 id="دعم-النكهات-flavor-support">
	دعم النكهات Flavor Support
</h3>

<p>
	تدعم ملحقات أندرويد الإضافية نكهات أندرويد ((Android flavors. لنفترض أن لديك نكهة اسمها <code>free</code> في ملف <code>build.gradle</code> خاصّتك:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1030_21" style="">
<span class="pln">android </span><span class="pun">{</span><span class="pln">
    productFlavors </span><span class="pun">{</span><span class="pln">
        free </span><span class="pun">{</span><span class="pln">
            versionName </span><span class="str">"1.0-free"</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	يمكنك استيراد كافة الخصائص التركيبية للخطاطة <code>free/res/layout/activity_free.xml</code> بإضافة هذا الاستيراد:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1030_23" style="">
<span class="kwd">import</span><span class="pln"> kotlinx</span><span class="pun">.</span><span class="pln">android</span><span class="pun">.</span><span class="pln">synthetic</span><span class="pun">.</span><span class="pln">free</span><span class="pun">.</span><span class="pln">activity_free</span><span class="pun">.*</span></pre>

<p>
	<br>
	في الوضع التجريبي، يمكنك تحديد أي اسم آخر (وليس فقط flavor)، على سبيل المثال <code>freeDebug</code> أو <code>freeRelease</code> يصلحان كذلك.
</p>

<h3 id="التخزين-المؤقت-لعناصرview">
	التخزين المؤقت لعناصرView
</h3>

<p>
	استدعاء <code>()findViewById</code> يمكن أن يكون بطيئًا، خصوصًا في حالة تشعبات العرض (view hierarchies) الكبيرة، لذلك تحاول إضافات أندرويد التقليل من عدد مرّات استدعاء <code>()findViewById</code> بواسطة التخزين المؤقت للعروض في الحاويات.<br>
	افتراضيًا، اضافات أندرويد تضيف دالة تخزين مؤقت مخفية وحقل تخزين إلى كل حاوية (Activity، Fragment، View أو LayoutContainer implementation) مكتوبة بـ Kotlin. التابع method)) صغير جدًا لذلك لا يزيد حجم APK كثيرًا.<br>
	في المثال التالي، يتم استدعاء <code>()findViewById</code> مرة واحدة فقط:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1030_25" style="">
<span class="kwd">class</span><span class="pln"> </span><span class="typ">MyActivity</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><span class="typ">Activity</span><span class="pun">()</span><span class="pln">

fun </span><span class="typ">MyActivity</span><span class="pun">.</span><span class="pln">a</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> 
    textView</span><span class="pun">.</span><span class="pln">text </span><span class="pun">=</span><span class="pln"> </span><span class="str">"Hidden view"</span><span class="pln">
    textView</span><span class="pun">.</span><span class="pln">visibility </span><span class="pun">=</span><span class="pln"> </span><span class="typ">View</span><span class="pun">.</span><span class="pln">INVISIBLE
</span><span class="pun">}</span></pre>

<p>
	لكن في الحالة التالية:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1030_27" style="">
<span class="pln">fun </span><span class="typ">Activity</span><span class="pun">.</span><span class="pln">b</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> 
    textView</span><span class="pun">.</span><span class="pln">text </span><span class="pun">=</span><span class="pln"> </span><span class="str">"Hidden view"</span><span class="pln">
    textView</span><span class="pun">.</span><span class="pln">visibility </span><span class="pun">=</span><span class="pln"> </span><span class="typ">View</span><span class="pun">.</span><span class="pln">INVISIBLE
</span><span class="pun">}</span></pre>

<p>
	لا يمكننا أن نعرف ما إذا كان سيتم استدعاء هذه الدالة في أنشطة مصادرنا فقط أم أيضا في كل أنشطة جافا. لهذا السبب، لن نستخدم التخزين المؤقت هنا، حتى لو تم تمرير أحد عيّنات instance الصنف <code>MyActivity</code> من المثال السابق كمستقبِل.
</p>

<h3 id="تغيير-استراتيجية-التخزين-المؤقت-للصنف-view">
	تغيير استراتيجية التخزين المؤقت للصنف View
</h3>

<p>
	يمكنك تغيير استراتيجية التخزين المؤقت بشكل شامل أو بالنسبة لكل حاوية على حدة. وهذا أيضًا يتطلب التحول إلى الوضع التجريبي.<br>
	يتم تحديد استراتيجية التخزين المؤقت الشاملة للمشروع في ملف <code>build.gradle</code>:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1030_29" style="">
<span class="pln">androidExtensions </span><span class="pun">{</span><span class="pln">
    defaultCacheImplementation </span><span class="pun">=</span><span class="pln"> </span><span class="str">"HASH_MAP"</span><span class="pln"> </span><span class="com">// also SPARSE_ARRAY, NONE</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	افتراضيًا، الملحقات الإضافية لأندرويد تستخدم <code>HashMap</code> كمرجع احتياطي للتخزين، ولكن يمكنك التبديل لتطبيق <code>SparseArray</code>، أو إيقاف التخزين المؤقت وحسب. هذا الأخير مفيد بشكل خاص إن أردت الاكتفاء باستخدام الجزء المقسّم Parcelable من إضافات Android.<br>
	يمكنك أيضًا التأشير على حاوية ما بـ <code>ContainerOptions@</code> لتغيير استراتيجية التخزين المؤقت:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1030_31" style="">
<span class="kwd">import</span><span class="pln"> kotlinx</span><span class="pun">.</span><span class="pln">android</span><span class="pun">.</span><span class="pln">extensions</span><span class="pun">.</span><span class="typ">ContainerOptions</span><span class="pln">

</span><span class="lit">@ContainerOptions</span><span class="pun">(</span><span class="pln">cache </span><span class="pun">=</span><span class="pln"> </span><span class="typ">CacheImplementation</span><span class="pun">.</span><span class="pln">NO_CACHE</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">class</span><span class="pln"> </span><span class="typ">MyActivity</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><span class="typ">Activity</span><span class="pun">()</span><span class="pln">

fun </span><span class="typ">MyActivity</span><span class="pun">.</span><span class="pln">a</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> 
    </span><span class="com">// findViewById() will be called twice</span><span class="pln">
    textView</span><span class="pun">.</span><span class="pln">text </span><span class="pun">=</span><span class="pln"> </span><span class="str">"Hidden view"</span><span class="pln">
    textView</span><span class="pun">.</span><span class="pln">visibility </span><span class="pun">=</span><span class="pln"> </span><span class="typ">View</span><span class="pun">.</span><span class="pln">INVISIBLE
</span><span class="pun">}</span></pre>

<h2 id="parcelable">
	Parcelable
</h2>

<p>
	بدءًا من الإصدار Kotlin 1.1.4، وفّرت الملحقات الإضافية لأندرويد مولّدات تطبيق للصنف Parcelable كميزة تجريبية.
</p>

<h3 id="إتاحة-دعم-parcelable">
	إتاحة دعم Parcelable
</h3>

<p>
	قم بتطبيق ملحقة Gradle المسمّاة <code>kotlin-android-extensions</code> كما هو موضح [أعلاه] (#إعداد الارتباطات) وقم بتشغيل الوضع التجريبي.
</p>

<h3 id="كيفية-الاستخدام">
	كيفية الاستخدام
</h3>

<p>
	قم بالتأشير على الصنف بـ <code>Parcelize@</code>، وسيتم إنشاء تطبيق Parcelable تلقائيًا.
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1030_33" style="">
<span class="kwd">import</span><span class="pln"> kotlinx</span><span class="pun">.</span><span class="pln">android</span><span class="pun">.</span><span class="pln">parcel</span><span class="pun">.</span><span class="typ">Parcelize</span><span class="pln">

</span><span class="lit">@Parcelize</span><span class="pln">
</span><span class="kwd">class</span><span class="pln"> </span><span class="typ">User</span><span class="pun">(</span><span class="pln">val firstName</span><span class="pun">:</span><span class="pln"> </span><span class="typ">String</span><span class="pun">,</span><span class="pln"> val lastName</span><span class="pun">:</span><span class="pln"> </span><span class="typ">String</span><span class="pun">,</span><span class="pln"> val age</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Int</span><span class="pun">):</span><span class="pln"> </span><span class="typ">Parcelable</span></pre>

<p>
	يتطلّب <code>Parcelize@</code> التصريح بجميع الخصائص المتسلسلة في المنشئ constructor الأولي. ستقوم إضافات أندرويد بإطلاق تحذير على كل الخصائص ذات الحقول المصرّح بها في جسم الصّنف، كما أنّه لا يمكن تطبيق <code>Parcelize@</code> إذا لم تكن كل معاملات المنشئ الأوّلية خصائصًا.<br>
	إن كان صنفك يتطلب تسلسلاً منطقيًا أكثر تقدمًا، فيمكنك كتابته داخل صنف مرافق:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1030_35" style="">
<span class="lit">@Parcelize</span><span class="pln">
data </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">Value</span><span class="pun">(</span><span class="pln">val firstName</span><span class="pun">:</span><span class="pln"> </span><span class="typ">String</span><span class="pun">,</span><span class="pln"> val lastName</span><span class="pun">:</span><span class="pln"> </span><span class="typ">String</span><span class="pun">,</span><span class="pln"> val age</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Int</span><span class="pun">)</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><span class="typ">Parcelable</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">private</span><span class="pln"> companion object </span><span class="pun">:</span><span class="pln"> </span><span class="typ">Parceler</span><span class="pun">&lt;</span><span class="typ">User</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        override fun </span><span class="typ">User</span><span class="pun">.</span><span class="pln">write</span><span class="pun">(</span><span class="pln">parcel</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Parcel</span><span class="pun">,</span><span class="pln"> flags</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Int</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
            </span><span class="com">// Custom write implementation</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">

        override fun create</span><span class="pun">(</span><span class="pln">parcel</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Parcel</span><span class="pun">):</span><span class="pln"> </span><span class="typ">User</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
            </span><span class="com">// Custom read implementation</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre>

<h3 id="الأنواع-المدعومة">
	الأنواع المدعومة
</h3>

<p>
	يدعم <code>Parcelize@</code> طيفًا واسعًا من الأنواع:
</p>

<ul>
<li>
		الأنواع الأولية Primitive types (ونسخها المغلّفة boxed versions).
	</li>
	<li>
		Objects وenums .
	</li>
	<li>
		<code>String</code>، <code>CharSequence</code>.
	</li>
	<li>
		<code>Exception</code>.
	</li>
	<li>
		<code>Size</code>، <code>SizeF</code>، <code>Bundle</code>، <code>IBinder</code>، <code>IInterface</code>، <code>FileDescriptor</code>
	</li>
	<li>
		<code>SparseArray</code>، <code>SparseIntArray</code>، <code>SparseLongArray</code>، <code>SparseBooleanArray</code>.
	</li>
	<li>
		كل الأنواع المتسلسلة <code>Serializable</code> (حتى <code>Date</code> مدعوم) وتطبيقات <code>Parcelable</code>.
	</li>
	<li>
		تجميعات كل الأنواع المدعومة: <code>List</code> (مُحالة على <code>ArrayList</code>)، و <code>Set</code> (مُحالة على <code>LinkedHashSet</code>)، و <code>Map</code> (مُحالة على <code>LinkedHashMap</code>).
	</li>
	<li>
		بالإضافة إلى عدد من التطبيقات الملموسة: <code>ArrayList</code>، <code>LinkedList</code>، <code>SortedSet</code>، <code>NavigableSet</code>، <code>HashSet</code>، <code>LinkedHashSet</code>، <code>TreeSet</code>، <code>SortedMap</code>، <code>NavigableMap</code>، <code>HashMap</code>، <code>LinkedHashMap</code>، <code>TreeMap</code>، <code>ConcurrentHashMap</code>.
	</li>
	<li>
		الجداول التي تحتوي الأنواع المدعومة.
	</li>
	<li>
		النسخ الفارغة Nullable versions من كل الأنواع المدعومة.
	</li>
</ul>
<h3 id="تخصيص-الـ-parcelers">
	تخصيص الـ Parcelers
</h3>

<p>
	حتى إن لم يكن النوع مدعوما مباشرة، يمكنك كتابة كائن <code>Parceler</code> لأجل دعمه.
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1030_37" style="">
<span class="kwd">class</span><span class="pln"> </span><span class="typ">ExternalClass</span><span class="pun">(</span><span class="pln">val value</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Int</span><span class="pun">)</span><span class="pln">

object </span><span class="typ">ExternalClassParceler</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><span class="typ">Parceler</span><span class="pun">&lt;</span><span class="typ">ExternalClass</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    override fun create</span><span class="pun">(</span><span class="pln">parcel</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Parcel</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">ExternalClass</span><span class="pun">(</span><span class="pln">parcel</span><span class="pun">.</span><span class="pln">readInt</span><span class="pun">())</span><span class="pln">

    override fun </span><span class="typ">ExternalClass</span><span class="pun">.</span><span class="pln">write</span><span class="pun">(</span><span class="pln">parcel</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Parcel</span><span class="pun">,</span><span class="pln"> flags</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Int</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        parcel</span><span class="pun">.</span><span class="pln">writeInt</span><span class="pun">(</span><span class="pln">value</span><span class="pun">)</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	أمّا عناصر Parcelers الخارجية يمكن تطبيقها باستخدام التأشيرات <code>TypeParceler@</code> أو <code>WriteWith@</code>:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1030_39" style="">
<span class="com">// Class-local parceler</span><span class="pln">
</span><span class="lit">@Parcelable</span><span class="pln">
</span><span class="lit">@TypeParceler</span><span class="pun">&lt;</span><span class="typ">ExternalClass</span><span class="pun">,</span><span class="pln"> </span><span class="typ">ExternalClassParceler</span><span class="pun">&gt;()</span><span class="pln">
</span><span class="kwd">class</span><span class="pln"> </span><span class="typ">MyClass</span><span class="pun">(</span><span class="pln">val external</span><span class="pun">:</span><span class="pln"> </span><span class="typ">ExternalClass</span><span class="pun">)</span><span class="pln">

</span><span class="com">// Property-local parceler</span><span class="pln">
</span><span class="lit">@Parcelable</span><span class="pln">
</span><span class="kwd">class</span><span class="pln"> </span><span class="typ">MyClass</span><span class="pun">(</span><span class="lit">@TypeParceler</span><span class="pun">&lt;</span><span class="typ">ExternalClass</span><span class="pun">,</span><span class="pln"> </span><span class="typ">ExternalClassParceler</span><span class="pun">&gt;()</span><span class="pln"> val external</span><span class="pun">:</span><span class="pln"> </span><span class="typ">ExternalClass</span><span class="pun">)</span><span class="pln">

</span><span class="com">// Type-local parceler</span><span class="pln">
</span><span class="lit">@Parcelable</span><span class="pln">
</span><span class="kwd">class</span><span class="pln"> </span><span class="typ">MyClass</span><span class="pun">(</span><span class="pln">val external</span><span class="pun">:</span><span class="pln"> </span><span class="lit">@WriteWith</span><span class="pun">&lt;</span><span class="typ">ExternalClassParceler</span><span class="pun">&gt;()</span><span class="pln"> </span><span class="typ">ExternalClass</span><span class="pun">)</span></pre>

<p>
	ترجمة -وبتصرّف- للمقال <a href="https://kotlinlang.org/docs/tutorials/android-plugin.html#view-binding" rel="external nofollow">Kotlin Android Extensions</a> لصاحبه Yan Zhulanow
</p>
]]></description><guid isPermaLink="false">618</guid><pubDate>Thu, 08 Feb 2018 18:52:49 +0000</pubDate></item><item><title>&#x625;&#x646;&#x634;&#x627;&#x621; &#x62A;&#x637;&#x628;&#x64A;&#x642; Kotlin &#x628;&#x633;&#x64A;&#x637; &#x644;&#x644;&#x623;&#x646;&#x62F;&#x631;&#x648;&#x64A;&#x62F;</title><link>https://academy.hsoub.com/programming/kotlin/%D8%A5%D9%86%D8%B4%D8%A7%D8%A1-%D8%AA%D8%B7%D8%A8%D9%8A%D9%82-kotlin-%D8%A8%D8%B3%D9%8A%D8%B7-%D9%84%D9%84%D8%A3%D9%86%D8%AF%D8%B1%D9%88%D9%8A%D8%AF-r614/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2018_01/5a718d7b48353_05-2(1).png.7595c84d0bedfb4495a51581eda8b5dd.png" /></p>

<p>
	في هذا الدرس ستتعلّم كيفيّة إنشاء تطبيق Kotlin بسيط لأندرويد باستخدام Android Studio.
</p>

<h3>
	<a id="__Kotlin_3" rel=""></a>تثبيت ملحقة Kotlin
</h3>

<p>
	تمّ إدماج ملحقة Kotlin مع Android Studio بدءًا من <a href="https://developer.android.com/studio/preview/index.html" rel="external nofollow">النسخة 3.0</a>. إن كنت تستخدم إصدارًا سابقًا، فستحتاج تثبيت ملحقة Kotlin. اذهب إلى
</p>

<p style="text-align: center;">
	<strong>File | Settings | Plugins | Install JetBrains plugin…</strong>
</p>

<p>
	بعد ذلك ابحث عنKotlin وقم بتثبيته. إن كنت تبحث في الشاشة " Welcome to Android Studio"، فقم باختيار
</p>

<p style="text-align: center;">
	<strong>Configure | Plugins | Install JetBrains plugin…</strong>
</p>

<p>
	عليك إعادة تشغيل بيئة التطوير بعد الانتهاء.
</p>

<h3>
	<a id="__13" rel=""></a>إنشاء مشروع
</h3>

<p>
	من السهل للغاية البدء في استخدام Kotlin لتطوير أندرويد. في هذا الدرس سنعمل على Android Studio. ولكن إن كنت تستخدم Intellij IDEA مع أندرويد، فالعمليّة هي نفسها تقريبًا.<br>
	لنقم أوّلاً بإنشاء مشروع جديد. اختر <strong>Start a new Android Studio project</strong> أو <strong>File | New project</strong>. سيساعدك صندوق الحوار التالي في عملية إنشاء مشروع جديد. ستحتاج إلى اختيار اسم للمشروع وتحديد أيّ إصدارات Android SDK قمت بتثبيتها. معظم الخيارات يمكن إبقاؤها على قيمها الافتراضية، لذلك يمكنك الضغط على Enter مرارًا.<br>
	تسميّة المشروع:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="26845" href="https://academy.hsoub.com/uploads/monthly_2018_01/5a7178ee5349c_01(3).png.ca92320da3a150347ffe4b1d9480b8cf.png" rel=""><img alt="01 (3).png" class="ipsImage ipsImage_thumbnailed" data-fileid="26845" data-unique="7sgee6fck" src="https://academy.hsoub.com/uploads/monthly_2018_01/5a7178ef48d35_01(3).thumb.png.3ea1218ba12de9c8153d4e2ece3590b0.png"></a>
</p>

<p>
	يوفر Android Studio 3.0 خيارًا لتمكين دعم Kotlin على هذه الشاشة. يمكنك التحقق من هذا الخيار وتجاوز الخطوة " Configuring Kotlin in the project" أدناه.<br>
	اختيار إصدار الأندرويد:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="26846" href="https://academy.hsoub.com/uploads/monthly_2018_01/5a7178f0cdbbb_02(2).png.052fd3c1a753c56a228920db58d566d8.png" rel=""><img alt="02 (2).png" class="ipsImage ipsImage_thumbnailed" data-fileid="26846" data-unique="f4g78lfkm" src="https://academy.hsoub.com/uploads/monthly_2018_01/5a7178f1eab2e_02(2).thumb.png.8f6daee25cb935d5b883f7dfb14a885c.png"></a>
</p>

<p>
	اختر إنشاء النشاط الذي سيتم تجهيزه لك:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="26847" href="https://academy.hsoub.com/uploads/monthly_2018_01/5a7178f313ae5_03(3).png.d439c6660cad5a5e47cb093fe84c2ba4.png" rel=""><img alt="03 (3).png" class="ipsImage ipsImage_thumbnailed" data-fileid="26847" data-unique="k2f3oop0u" src="https://academy.hsoub.com/uploads/monthly_2018_01/5a7178f485ae1_03(3).thumb.png.5c95af85828e48b58f2128a32b8f2fae.png"></a>
</p>

<p>
	قم بتسمية النّشاط:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="26848" href="https://academy.hsoub.com/uploads/monthly_2018_01/5a7178f5e2a85_04(2).png.18e565bb8f49d49bee7159c06d6853f1.png" rel=""><img alt="04 (2).png" class="ipsImage ipsImage_thumbnailed" data-fileid="26848" data-unique="haq5wqrh8" src="https://academy.hsoub.com/uploads/monthly_2018_01/5a7178f79bb11_04(2).thumb.png.66ed10b78e1e0de0214c88c78485ce20.png"></a>
</p>

<p>
	في Android Studio 3.0، يمكنك أن تختار إنشاء النشاط في Kotlin على الفور، حتى تتمكن من تجاوز الخطوة “Converting Java code to Kotlin”. الإصدارات السابقة تخلق النشاط في Java، ويمكنك بعدها استخدام أداة التحويل الآلي لتحويله. بشكل عام، أسهل طريقة للبدء في استخدام Kotlin هي بالتحويل التلقائي لنشاط جافا إلى نشاط Kotlin. يرجى ملاحظة أنه بدلاً من البحث في الوثائق عن وسيلة جديدة للتعبير عن نمط برمجي قديم، يمكنك كتابته بالجافا، ثم نسخ-لصق كود الجافا في ملف Kotlin، وسيقترح عليك IntelliJ IDEA (أو Android Studio) تحويله.
</p>

<h2>
	<a id="____Kotlin_34" rel=""></a>تحويل كود الجافا إلى Kotlin
</h2>

<p>
	افتح ملف <code>MainActivity.java</code>. ثم قم باستدعاء الإجراء <strong>Convert Java File to Kotlin File</strong>. يمكنك القيام بذلك بعدّة طرق أسهلها استدعاء <a href="https://www.jetbrains.com/idea/help/navigating-to-action.html" rel="external nofollow">Find Action</a> ثمّ البدء في كتابة اسم الإجراء (كما هو مبيّن في المقتطف أدناه). أو يمكنك بدلا من ذلك استدعاء هذا الخيار <strong>Code | Convert Java File to Kotlin File</strong> من القائمة أو استخدام الاختصار المقابل (يمكنك العثور عليه في عنصر القائمة).
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="26849" href="https://academy.hsoub.com/uploads/monthly_2018_01/5a7178f8ad161_05(2).png.c6ae368cdcaaa281f8a28287cf4a9441.png" rel=""><img alt="05 (2).png" class="ipsImage ipsImage_thumbnailed" data-fileid="26849" data-unique="yx9f4u998" src="https://academy.hsoub.com/uploads/monthly_2018_01/5a7178f98d7c1_05(2).thumb.png.cf71eb9f54d5f878712aea11ca48bb28.png"></a>
</p>

<p>
	بعد التحويل من المفروض أن تحصل على نشاط مكتوب بـ Kotlin.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="26850" href="https://academy.hsoub.com/uploads/monthly_2018_01/5a7178fa4fecd_06(2).png.3f2acbfad5399ec55a6a7efdf03ca17f.png" rel=""><img alt="06 (2).png" class="ipsImage ipsImage_thumbnailed" data-fileid="26850" data-unique="gti6vlwm4" src="https://academy.hsoub.com/uploads/monthly_2018_01/5a7178faa4ba8_06(2).thumb.png.76913d141dc8c58c338da9b03c61711d.png"></a>
</p>

<h3>
	<a id="_Kotlin___43" rel=""></a>إعداد Kotlin في المشروع
</h3>

<p>
	إن بدأت في تحرير هذا الملف، Android Studio سيُلمّح لك في الموجّه prompt بأنّ Kotlin لم يتم إعداده بعد لكي تقوم بإعداده. أو بدلاً من ذلك، يمكنك أن تبدأ الإعداد بأن تختار <strong>Tools | Kotlin | Configure Kotlin in Project</strong> من القائمة الرئيسيّة.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="26851" href="https://academy.hsoub.com/uploads/monthly_2018_01/5a71792b8a688_07(2).png.8b46f97da0dd394a8235a79190119ebf.png" rel=""><img alt="07 (2).png" class="ipsImage ipsImage_thumbnailed" data-fileid="26851" data-unique="0l0derktz" src="https://academy.hsoub.com/uploads/monthly_2018_01/5a71792cce806_07(2).thumb.png.b19d5612b777e8a9ba4d736a01344666.png"></a>
</p>

<p>
	ثم ستتم مطالبتك بتحديد إصدار Kotlin. قم باختيار أحدث الإصدارات المتاحة في قائمة الإصدارات المثبّتة.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="26852" href="https://academy.hsoub.com/uploads/monthly_2018_01/5a71792e3a649_08(1).png.5765e145b2ef6d80c68b0e884fe20d3d.png" rel=""><img alt="08 (1).png" class="ipsImage ipsImage_thumbnailed" data-fileid="26852" data-unique="21dl5pu2v" src="https://academy.hsoub.com/uploads/monthly_2018_01/5a71792e93273_08(1).thumb.png.7ebf453fc03342746b710f11498308ae.png"></a>
</p>

<p>
	بعد إعداد Kotlin، ينبغي تحديث ملف التطبيق <code>build.gradle</code>. وحينها يمكنك أن ترى أنه تمّت إضافة ملحقة التطبيق: "<code>kotlin-android</code>" ومكتبتها المتعلّقة <code>kotlin-stdlib</code>.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="26853" href="https://academy.hsoub.com/uploads/monthly_2018_01/5a71792f25bab_09(1).png.1cd5ad4592f8e7a1963aaedcb31e68a6.png" rel=""><img alt="09 (1).png" class="ipsImage ipsImage_thumbnailed" data-fileid="26853" data-unique="e4obgqlux" src="https://academy.hsoub.com/uploads/monthly_2018_01/5a71792f493ed_09(1).thumb.png.6aa5ae0b368decf888007e962eabebb6.png"></a>
</p>

<p>
	الخطوة الأخيرة هي مزامنة المشروع. يمكنك الضغط على “Sync Now” في الموجّه أو استدعاء الإجراء <strong>Sync Project with Gradle Files</strong>.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="26854" href="https://academy.hsoub.com/uploads/monthly_2018_01/5a71793002f5e_10(1).png.5fe8f456a5a30f879ddb1fbff62d135d.png" rel=""><img alt="10 (1).png" class="ipsImage ipsImage_thumbnailed" data-fileid="26854" data-unique="un1ynzsbd" src="https://academy.hsoub.com/uploads/monthly_2018_01/5a717930f1e14_10(1).thumb.png.92e0bf1308088eb24fcb14ee5056f2b8.png"></a>
</p>

<h3>
	<a id="___Kotlin__60" rel=""></a>بناء ونشر تطبيقات Kotlin لأندرويد
</h3>

<p>
	أنت الآن جاهز لإنشاء التطبيق وتشغيله على محاكٍ أو جهاز. وهذا يجري تمامًا بنفس الطريقة في جافا. يمكنك إطلاق التطبيق والتوقيع عليه على غرار ما تفعله في تطبيقات أندرويد المكتوبة بلغة جافا.<br>
	حجم ملف تشغيل Kotlin صغير: فحجم المكتبة في حدود 932 KB (الإصدار 1.2.10). وهذا يعني أنّ Kotlin لا يضيف إلا قدرًا قليلًا إلى حجم الملف apk.<br>
	يُنتج مترجم Kotlin رُقامات byte-code، وبالتالي فليس هناك حقّا أيّ فرق من حيث الشكل والمظهر بين التطبيقات المكتوبة بـ Kotlin وتلك المكتوبة بلغة جافا.
</p>

<p>
	<br>
	من توثيقيات <a href="https://kotlinlang.org/docs/tutorials/kotlin-android.html" rel="external nofollow">Kotlin</a>
</p>
]]></description><guid isPermaLink="false">614</guid><pubDate>Mon, 05 Feb 2018 17:07:02 +0000</pubDate></item><item><title>&#x627;&#x644;&#x62F;&#x644;&#x64A;&#x644; &#x627;&#x644;&#x633;&#x631;&#x64A;&#x639; &#x625;&#x644;&#x649; &#x644;&#x63A;&#x629; &#x627;&#x644;&#x628;&#x631;&#x645;&#x62C;&#x629; Kotlin</title><link>https://academy.hsoub.com/programming/kotlin/%D8%A7%D9%84%D8%AF%D9%84%D9%8A%D9%84-%D8%A7%D9%84%D8%B3%D8%B1%D9%8A%D8%B9-%D8%A5%D9%84%D9%89-%D9%84%D8%BA%D8%A9-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D8%A9-kotlin-r603/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2018_01/22-2.png.fdcdf76e061f4e2a47b44d513486e687.png" /></p>

<p>
	كوتلن (Kotlin) هي لغة برمجة مخصّصة لمنصّة جافا الافتراضية (Java Virtual Machine أو اختصارًا JVM)، الأندرويد، والمتّصفح. تنتمي للغات statically typed (التي تفحص الأنواع وقت الترجمة). وهي متوافقة مع جافا 100%.
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<span class="com">// (//)التعليقات على سطر واحد تبدأ بـ/*</span><span class="pln">
</span><span class="pun">التعليقات</span><span class="pln"> </span><span class="pun">المؤلفة</span><span class="pln"> </span><span class="pun">من</span><span class="pln"> </span><span class="pun">عدة</span><span class="pln"> </span><span class="pun">أسطر</span><span class="pln"> </span><span class="pun">تبدو</span><span class="pln"> </span><span class="pun">كهذه</span><span class="pln">
</span><span class="pun">*/</span></pre>

<p>
	تعمل الكلمة المفتاحية <code>package</code> بنفس طريقة جافا
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code>package com.learnxinyminutes.kotlin
</code></pre>

<p>
	نقطة الإدخال لبرامج Kotlin هي دالة(تابع) تسمى <code>main </code>،يمرر التّابع مصفوفة تحتوي على وسطاء arguments لسطر الأوامر.
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code>fun main(args: Array&lt;String&gt;) {
</code></pre>

<p>
	التّصريح عن القيم يتم باستخدام إما <code>var</code> أو <code>val </code>،تصريح <code>val</code> لا يمكن إعادة تعيينه، في حين يمكن ذلك في <code>var</code>
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">val fooVal =10
</code></pre>

<p>
	لا يمكننا لاحقًا إعادة تعيين قيمة <code>fooVal</code> لقيمة أخرى.
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">var fooVar =10
fooVar =20
</code></pre>

<p>
	من الممكن إعادة تعيين قيمة <code>fooVar</code>. في أغلب الحالات، يمكن لكوتلن أن تحدّد ما هو نوع المتغير، لذلك لا داعي لتحديده صراحة في كل مرّة. يمكننا أن نصرّح بنوع المتغير بوضوح كالتالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">val foo:Int=7
</code></pre>

<p>
	يمكن تمثيل السلاسل بطريقة مماثلة في java. يتم الهروب باستخدام backslash.
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">val fooString ="My String Is Here!"
val barString ="Printing on a new line?\nNo Problem!"
val bazString ="Do you want to add a tab?\tNo Problem!"
println(fooString)
println(barString)
println(bazString)
</code></pre>

<p>
	تُحدد السلسلة الخام string raw باستخدام triple quote (<code>"""</code>). ويمكن أن تحتوي أسطر جديدة و أية محارف أخرى.
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">val fooRawString ="""
fun helloWorld(val name :String){
println("Hello, world!")}"""
println(fooRawString)
</code></pre>

<p>
	السلاسل ممكن أن تحتوي تعابير القالب template expressions. تبدأ تعابير القالب بالرمز <code>$</code>.
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">val fooTemplateString ="$fooString has ${fooString.length} characters"
println(fooTemplateString)// =&gt; My String Is Here! has 18 characters
</code></pre>

<p>
	من أجل المتغيرات التي تحوي قيمة فارغة <code>null</code> يجب تحديد ذلك صراحة <code>nullable</code>. يمكن تحديد المتغير قابلاً للقيمة <code>null</code> بإلحاق<code>?</code> بنوعه. ويمكننا الوصول إلى المتحولات القابلة لـ <code>null</code> باستخدام مُعامل التشغيل<code>? </code>،ويمكننا استخدام عامل التشغيل <code>:?</code> لتحديد قيمة بديلة للاستخدام إذا كان المتغير فارغ <code>null</code>.
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">var fooNullable:String?="abc"
println(fooNullable?.length)// =&gt; 3
println(fooNullable?.length ?:-1)// =&gt; 3
fooNullable = null
println(fooNullable?.length)// =&gt; null
println(fooNullable?.length ?:-1)// =&gt; -1
</code></pre>

<p>
	يمكن التصريح عن الدوال باستخدام الكلمة المفتاحية <code>fun</code>. وتحدد وسطاء الدالة بين قوسين بعد اسم الدالة. ويمكن لوسطاء الدالة اختياريًا الاحتواء على قيمة افتراضية. ويحدّد نوع إرجاع الدالة، إذا لزم الامر بعد المعطيات.
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">fun hello(name:String="world"):String{return"Hello, $name!"}
println(hello("foo"))// =&gt; Hello, foo!
println(hello(name ="bar"))// =&gt; Hello, bar!
println(hello())// =&gt; Hello, world!
</code></pre>

<p>
	يمكن لبارامتر الدالة أن يوسم بالكلمة المفتاحية <code>vararg</code> للسماح بتمرير عدد متغير من المعطيات إلى الدالة.
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">fun varargExample(vararg names:Int){
    println("Argument has ${names.size} elements")}
varargExample()// =&gt; لا يحوي الوسيط أية عناصر
varargExample(1)// =&gt; يحوي الوسيط عنصر واحد
varargExample(1,2,3)// =&gt; يحوي  الوسيط 3 عناصر
</code></pre>

<p>
	عندما تتكوّن الدّالة من تعبير واحد فقط، يمكن حذف الأقواس المنحنية <code>{ }</code> ويتم تحديد الجسم(العملية) بعد رمز <code>=</code>
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">fun odd(x:Int):Boolean= x %2==1
println(odd(6))// =&gt; false
println(odd(7))// =&gt; true
</code></pre>

<p>
	إذا كان نوع الاسترجاع يمكن استنتاجه فلسنا بحاجة لتحديده.
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">fun even(x:Int)= x %2==0
println(even(6))// =&gt; true
println(even(7))// =&gt; false
</code></pre>

<p>
	الدوال يمكن أن تأخذ دوال كوسطاء وترجع دالة.
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">fun not(f:(Int)-&gt;Boolean):(Int)-&gt;Boolean{return{n -&gt;!f.invoke(n)}}
</code></pre>

<p>
	يمكن للدوال المسمّاة أن تحدّد كوسائط باستخدام معامل التشغيل
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">val notOdd = not(::odd)
val notEven = not(::even)
</code></pre>

<p>
	يمكن تحديد تعابير Lambda كوسائط
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">val notZero = not {n -&gt; n ==0}
</code></pre>

<p>
	إذا احتوت lambda على بارامتر واحد فقط يمكن حذف التصريح عنه (جنبًا إلى جنب مع<code>&lt;-</code> )وسيكون اسم البارامتر الوحيد <code>it</code>.
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">val notPositive = not {it &gt;0}for(i in 0..4){
    println("${notOdd(i)} ${notEven(i)} ${notZero(i)} ${notPositive(i)}")}
</code></pre>

<p>
	تستخدم الكلمة المفتاحية <code>class</code> للتّصريح عن الأصناف.
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_9334_7" style="">
<span class="kwd">class</span><span class="pln"> </span><span class="typ">ExampleClass</span><span class="pun">(</span><span class="pln">val x</span><span class="pun">:</span><span class="typ">Int</span><span class="pun">){</span><span class="pln">
    fun memberFunction</span><span class="pun">(</span><span class="pln">y</span><span class="pun">:</span><span class="typ">Int</span><span class="pun">):</span><span class="typ">Int</span><span class="pun">{</span><span class="kwd">return</span><span class="pln"> x </span><span class="pun">+</span><span class="pln"> y
    </span><span class="pun">}</span><span class="pln">

    infix fun infixMemberFunction</span><span class="pun">(</span><span class="pln">y</span><span class="pun">:</span><span class="typ">Int</span><span class="pun">):</span><span class="typ">Int</span><span class="pun">{</span><span class="kwd">return</span><span class="pln"> x </span><span class="pun">*</span><span class="pln"> y
    </span><span class="pun">}}</span></pre>

<p>
	لإنشاء حالة instance جديدة نستدعي الباني. ولاحظ أن Kotlin لا تحوي الكلمة المفتاحية <code>new</code>.
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">val fooExampleClass =ExampleClass(7)
</code></pre>

<p>
	يمكن استدعاء دوال المستخدم باستخدام التنويت النقطي <code>.</code>
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">println(fooExampleClass.memberFunction(4))// =&gt; 11
</code></pre>

<p>
	إذا وُسمت الدالة بالكلمة المفتاحية <code>infix</code> يمكن عندها أن يستدعى باستخدام التنويت الداخلي
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">println(fooExampleClass infixMemberFunction 4)// =&gt; 28
</code></pre>

<p>
	أصناف البيانات Data classes هي طريقة مختصرة لإنشاء الأصناف التي تحتوي بيانات فقط وتنشئ دوال <code>hashCode</code>،<code>equals</code> و <code>toString</code> تلقائيًا.
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">data classDataClassExample(val x:Int, val y:Int, val z:Int)
val fooData =DataClassExample(1,2,4)
println(fooData)// =&gt; DataClassExample(x=1, y=2, z=4)
</code></pre>

<p>
	أصناف البيانات لديها دالة <code>copy</code>
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">val fooCopy = fooData.copy(y =100)
println(fooCopy)// =&gt; DataClassExample(x=1, y=100, z=4)
</code></pre>

<p>
	يمكن أن تفكَك الكائنات Objects في متغيرات متعددة
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">val (a, b, c)= fooCopy
println("$a $b $c")// =&gt; 1 100 4
</code></pre>

<p>
	التفكيك باستخدام حلقة <code>for</code>
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">for((a, b, c) in listOf(fooData)){
    println("$a $b $c")// =&gt; 1 100 4}
val mapData = mapOf("a" to 1,"b" to 2)
</code></pre>

<p>
	Map.Entry قابل للتفكيك كذلك
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">for((key, value) in mapData){
    println("$key -&gt; $value")}
</code></pre>

<p>
	الدالة <code>with</code> مشابهة لعبارة <code>with</code> في جافا
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">data classMutableDataClassExample(var x:Int, var y:Int, var z:Int)
val fooMutableData =MutableDataClassExample(7,4,9)
with (fooMutableData){
    x -=2
    y +=2
    z--}
println(fooMutableData)// =&gt; MutableDataClassExample(x=5, y=6, z=8)
</code></pre>

<p>
	يمكننا إنشاء قائمة (لائحة) باستخدام الدالة <code>listOf</code>. ستكون القائمة غير قابلة للتغيير ولا يمكن إضافة عناصر أو إزالتها.
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">val fooList = listOf("a","b","c")
println(fooList.size)// =&gt; 3
println(fooList.first())// =&gt; a
println(fooList.last())// =&gt; c// index يمكن الوصول إلى عناصر القائمة من خلال فهرسها
println(fooList[1])// =&gt; b
</code></pre>

<p>
	يمكن إنشاء قائمة قابلة للتعديل باستخدام الدالة <code>mutableListOf</code>
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">val fooMutableList = mutableListOf("a","b","c")
fooMutableList.add("d")
println(fooMutableList.last())// =&gt; d
println(fooMutableList.size)// =&gt; 4
</code></pre>

<p>
	يمكن إنشاء تعيين set باستخدام الدّالة <code>setOf</code>
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">val fooSet = setOf("a","b","c")
println(fooSet.contains("a"))// =&gt; true
println(fooSet.contains("z"))// =&gt; false
</code></pre>

<p>
	يمكننا إنشاء خريطة map باستخدام الدّالة <code>mapOf</code>
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">val fooMap = mapOf("a" to 8,"b" to 7,"c" to 9)
</code></pre>

<p>
	يمكن الوصول لقيم الـ Map من خلال مفاتيحها
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">println(fooMap["a"])// =&gt; 8
</code></pre>

<p>
	تُمثل المتتالية Sequences مجموعات تقييمها مؤجل إلى حين الحاجة lazily-evaluated collections. ويمكننا إنشاء متتالية باستخدام الدّالة <code>generateSequence</code>.
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">val fooSequence = generateSequence(1,{ it +1})
val x = fooSequence.take(10).toList()
println(x)// =&gt; [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
</code></pre>

<p>
	مثال لاستخدام متتالية لتوليد أرقام فيبانوتشي <code>fibonacci</code>
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">fun fibonacciSequence():Sequence&lt;Long&gt;{
    var a =0L
    var b =1L

    fun next():Long{
        val result = a + b
        a = b
        b = result
        return a
    }return generateSequence(::next)}
val y = fibonacciSequence().take(10).toList()
println(y)// =&gt; [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
</code></pre>

<p>
	تزوّد Kotlin دوال عالية الرتبة للعمل مع المجموعات collections
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">val z =(1..9).map{it *3}.filter {it &lt;20}.groupBy {it %2==0}.mapKeys {if(it.key)"even"else"odd"}
println(z)// =&gt; {odd=[3, 9, 15], even=[6, 12, 18]}
</code></pre>

<p>
	يمكن استخدام حلقة <code>for</code> مع أي شيء يؤمن التكرار.
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">for(c in "hello"){
    println(c)}
</code></pre>

<p>
	تعمل حلقات <code>while</code> بشكل مشابه لعملها في اللغات الأخرى
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">var ctr =0while(ctr &lt;5){
    println(ctr)
    ctr++}do{
    println(ctr)
    ctr++}while(ctr &lt;10)
</code></pre>

<p>
	يمكن استخدام <code>if</code> كتعبير يرجع القيم. لهذا السبب ليس هناك حاجة لمعامل التشغيل <code>:?</code> في Kotlin.
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">val num =5
val message =if(num %2==0)"even"else"odd"
println("$num is $message")// =&gt; 5 is odd
</code></pre>

<p>
	يمكن استخدام <code>when</code> كبديل لسلاسل <code>if-else if</code>
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">val i =10
when {
    i &lt;7-&gt; println("first block")
    fooString.startsWith("hello")-&gt; println("second block")else-&gt; println("else block")}
</code></pre>

<p>
	يمكن استخدام <code>when</code> مع المعطيات.
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">when (i){0,21-&gt; println("0 or 21")
    in 1..20-&gt; println("in the range 1 to 20")else-&gt; println("none of the above")}
</code></pre>

<p>
	يمكن استخدام <code>when</code> كدالة ترجع القيم.
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">var result = when (i){0,21-&gt;"0 or 21"
    in 1..20-&gt;"in the range 1 to 20"else-&gt;"none of the above"}
println(result)
</code></pre>

<p>
	يمكننا التحقق فيما إذا كان الكائن object من نوع محدّد باستخدام معامل التشغيل <code>is</code>. إذا مرر الكائن فحص النوع type check عندها يمكن استخدام هذا النوع دون الموائمة بشكل صريح.
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">fun smartCastExample(x:Any):Boolean{if(x is Boolean){
</code></pre>

<p>
	X توائم أوتوماتيكيًا إلى <code>Boolean</code>
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">return x
   }elseif(x is Int){
</code></pre>

<p>
	X توائم أوتوماتيكيًا إلى <code>Int</code>
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">return x &gt;0}elseif(x is String){
</code></pre>

<p>
	X توائم أوتوماتيكيًا إلى <code>String</code>
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">return x.isNotEmpty()}else{returnfalse}}
println(smartCastExample("Hello, world!"))// =&gt; true
println(smartCastExample(""))// =&gt; false
println(smartCastExample(5))// =&gt; true
println(smartCastExample(0))// =&gt; false
println(smartCastExample(true))// =&gt; true
</code></pre>

<p>
	تعمل الموائمة الذكيّة <code>smartcast</code> أيضًا مع كتلة <code>when</code>
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">fun smartCastWhenExample(x:Any)= when (x){
    is Boolean-&gt; x
    is Int-&gt; x &gt;0
    is String-&gt; x.isNotEmpty()else-&gt;false}
</code></pre>

<p>
	الملحقات Extensions هي طريقة لإضافة وظائف جديدة للصنف <code>class</code>. وهي مشابهة لدوال ملحقات #C
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">fun String.remove(c:Char):String{returnthis.filter {it != c}}
println("Hello, world!".remove('l'))// =&gt; Hello, word!

println(EnumExample.A)// =&gt; A
println(ObjectExample.hello())// =&gt; hello
</code></pre>

<p>
	أصناف Enum مشابهة لأنواع <code>enum</code> في جافا.
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">enumclassEnumExample{
    A, B, C
}
</code></pre>

<p>
	يمكن استخدام الكلمة المفتاحية <code>object</code> لإنشاء كائنات وحيدة. لا يمكننا تمثيلها ولكن يمكن أن نشير لحالتها الفريدة من خلال اسمها. وهذا مشابه لكائنات Scala singleton
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4990_7" style="">
<code class="prism  language-ipscodeprettyprintcprettyprinted">object ObjectExample{
    fun hello():String{return"hello"}}

fun useObject(){ObjectExample.hello()
    val someRef:Any=ObjectExample//كماهي تمامًا objects نستخدم أسماء الكائنات  }
</code></pre>

<p>
	ترجمة -وبتصرّف- للمقال <a href="https://learnxinyminutes.com/docs/kotlin/" rel="external nofollow">Learn kotlin in Y Minutes</a>
</p>
]]></description><guid isPermaLink="false">603</guid><pubDate>Mon, 22 Jan 2018 17:02:00 +0000</pubDate></item></channel></rss>
