صدأ 1.30 الإصدار

يسر فريق تطوير Rust أن يعلن عن إصدار نسخة جديدة من Rust: 1.30.0. Rust هي لغة برمجة نظام تهدف إلى الأمان والسرعة وتنفيذ التعليمات البرمجية المتوازية.


إذا كان لديك إصدار سابق من Rust مثبتًا باستخدام rustup ، فإن ترقية Rust إلى الإصدار 1.30.0 تحتاج فقط إلى:


 $ rustup update stable 

إذا لم تكن قد قمت بالفعل بتثبيت rustup ، فيمكنك تثبيته من الصفحة المقابلة على موقعنا. تتوفر ملاحظات الإصدار التفصيلية لـ Rust 1.30.0 على GitHub.


ما هو مدرج في الإصدار المستقر 1.30.0


الصدأ 1.30 هو إصدار متميز مع عدد من الابتكارات الهامة. ولكن يوم الاثنين ، سيتم نشر المدونة الرسمية طلبًا للتحقق من الإصدار التجريبي من Rust 1.31 ، والذي سيكون الإصدار الأول من "Rust 2018". ستجد المزيد من المعلومات حول هذا في منشورنا السابق "What is Rust 2018" .


وحدات الماكرو الإجرائية


مرة أخرى في Rust 1.15 ، أضفنا القدرة على تحديد "اشتقاق وحدات الماكرو المخصصة". على سبيل المثال ، باستخدام serde_derive ، يمكنك أن تعلن:


 #[derive(Serialize, Deserialize, Debug)] struct Pet { name: String, } 

وتحويل Pet إلى JSON والعودة إلى الهيكل باستخدام serde_json . هذا ممكن بفضل الاستدلال التلقائي Deserialize Serialize و Deserialize باستخدام وحدات الماكرو الإجرائية في serde_derive .


يعمل الصدأ 1.30 على توسيع وظائف وحدات الماكرو الإجرائية من خلال إضافة القدرة على تحديد نوعين آخرين من وحدات الماكرو: "وحدات الماكرو الإجرائية السمة" و "وحدات الماكرو الإجرائية الوظيفية".


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


 #[route(GET, "/")] fn index() { 

سيتم تعريف هذه السمة #[route] في الإطار نفسه على أنها ماكرو إجرائي. سيبدو توقيعه كما يلي:


 #[proc_macro_attribute] pub fn route(attr: TokenStream, item: TokenStream) -> TokenStream { 

هنا لدينا TokenStream من نوع الإدخال TokenStream : الأول لمحتوى السمة نفسها ، أي هذه هي معلمات GET, "/" . والثاني هو جسم الكائن الذي يتم تطبيق السمة عليه. في حالتنا ، هذا هو fn index() {} وبقية نص الدالة.


تحدد وحدات الماكرو الوظيفية وحدات الماكرو التي يشبه استخدامها استدعاء دالة. على سبيل المثال ، sql! :


 let sql = sql!(SELECT * FROM posts WHERE id=1); 

سيقوم هذا الماكرو الموجود بداخله بتحليل تعبيرات SQL والتحقق من صحتها النحوية. يجب التصريح عن ماكرو مماثل على النحو التالي:


 #[proc_macro] pub fn sql(input: TokenStream) -> TokenStream { 

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


وحدات الماكرو use


يمكنك الآن استيراد وحدات الماكرو إلى النطاق باستخدام الكلمة الأساسية استخدام . على سبيل المثال ، لاستخدام الماكرو serde-json حزمة serde-json ، كان الإدخال هو:


 #[macro_use] extern crate serde_json; let john = json!({ "name": "John Doe", "age": 43, "phones": [ "+44 1234567", "+44 2345678" ] }); 

والآن عليك أن تكتب:


 extern crate serde_json; use serde_json::json; let john = json!({ "name": "John Doe", "age": 43, "phones": [ "+44 1234567", "+44 2345678" ] }); 

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


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


 #[derive(Serialize)] struct Demo { ok: String, bad: std::thread::Thread, } 

أدى إلى هذا الخطأ:


 error[E0277]: the trait bound `std::thread::Thread: _IMPL_SERIALIZE_FOR_Demo::_serde::Serialize` is not satisfied --> src/main.rs:3:10 | 3 | #[derive(Serialize)] | ^^^^^^^^^ the trait `_IMPL_SERIALIZE_FOR_Demo::_serde::Serialize` is not implemented for `std::thread::Thread` 

الآن سيتم إصداره:


 error[E0277]: the trait bound `std::thread::Thread: serde::Serialize` is not satisfied --> src/main.rs:7:5 | 7 | bad: std::thread::Thread, | ^^^ the trait `serde::Serialize` is not implemented for `std::thread::Thread` 

تحسين نظام الوحدة


لطالما كان نظام الوحدة بقعة مؤلمة للمبتدئين في الصدأ ؛ كانت بعض قواعده غير ملائمة في الممارسة. هذه التغييرات هي الخطوة الأولى التي نتخذها لتبسيط نظام الوحدة.


بالإضافة إلى التغيير أعلاه لوحدات الماكرو ، هناك تحسينان جديدان use . أولاً ، تتم إضافة الحزم الخارجية إلى المقدمة ، وهي:


 //  let json = ::serde_json::from_str("..."); //  let json = serde_json::from_str("..."); 

الصيد هو أن النمط القديم لم يكن مطلوبًا دائمًا بسبب ميزات نظام وحدة الصدأ:


 extern crate serde_json; fn main() { //   ;     ,  `serde_json` //     let json = serde_json::from_str("..."); } mod foo { fn bar() { //   ;     `foo`,  `serde_json` //    let json = serde_json::from_str("..."); } //   -        `use` use serde_json; fn baz() { //   -   `::serde_json`,   //  ,   let json = ::serde_json::from_str("..."); } } 

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


أخيرًا ، بدأ الاستخدام لدعم استيراد العناصر إلى النطاق الحالي بمسارات تبدأ في الصندوق :


 mod foo { pub fn bar() { // ... } } //  use ::foo::bar; //  use foo::bar; //  use crate::foo::bar; 

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


 mod foo { pub fn bar() { // ... } } mod baz { pub fn qux() { //  ::foo::bar(); //  ,    `use`: // foo::bar(); //  crate::foo::bar(); } } 

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


تبسط كل هذه التغييرات معًا فهم كيفية حل المسارات. أينما ترى المسار a::b::c ، باستثناء بيان use ، يمكنك أن تسأل:


  • هل اسم الحزمة؟ ثم تحتاج إلى البحث عن b::c بداخله.
  • هو crate الكلمات الرئيسية؟ ثم تحتاج إلى البحث عن b::c من جذر الحزمة الحالية.
  • خلاف ذلك ، تحتاج إلى البحث عن a::b::c من الموضع الحالي في التسلسل الهرمي للوحدة النمطية.

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


المعرفات الأولية


يمكنك الآن استخدام الكلمات الرئيسية كمعرفات باستخدام بناء الجملة الجديد التالي:


 //      `for` let r#for = true; //     `for` fn r#for() { // ... } //    r#for(); 

حتى الآن ، لا توجد حالات كثيرة عندما يكون هذا مفيدًا لك. ولكن في يوم من الأيام ستحاول استخدام الحزمة لـ Rust 2015 في مشروع لـ Rust 2018 أو العكس ، وستختلف مجموعة كلماتها الرئيسية. سنتحدث أكثر عن هذا في الإعلان القادم عن Rust 2018.


تطبيقات بدون مكتبة قياسية


بالعودة إلى الصدأ 1.6 ، أعلنا تثبيت "no_std" و libcore لإنشاء مشاريع بدون مكتبة قياسية. ومع ذلك ، مع توضيح واحد: كان من الممكن إنشاء مكتبات فقط ، وليس تطبيقات.


في Rust 1.30 ، يمكنك استخدام السمة #[panic_handler] لتنفيذ الذعر بشكل مستقل. هذا يعني أنه يمكنك الآن إنشاء تطبيقات ، وليس فقط المكتبات التي لا تستخدم المكتبة القياسية.


أخرى


شيء أخير: في وحدات الماكرو ، يمكنك الآن تعيين معدِّلات النطاق ، مثل pub ، باستخدام مؤهل vis . بالإضافة إلى ذلك ، يتم الآن تثبيت "سمات الأداة" ، مثل #[rustfmt::skip] . صحيح للاستخدام مع أدوات التحليل الثابتة ، مثل #[allow(clippy::something)] ، فهي ليست مستقرة بعد.


انظر ملاحظات الإصدار لمزيد من التفاصيل.


استقرار المكتبة القياسية


تم تثبيت واجهات برمجة التطبيقات التالية في هذا الإصدار:


  • Ipv4Addr::{BROADCAST, LOCALHOST, UNSPECIFIED}
  • Ipv6Addr::{BROADCAST, LOCALHOST, UNSPECIFIED}
  • Iterator::find_map

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


  • trim_left -> trim_start
  • trim_right -> trim_end
  • trim_left_matches -> trim_start_matches
  • trim_right_matches -> trim_end_matches

نخطط لإعلان أن الأسماء القديمة قديمة (لكن ليس حذفها بالطبع) في Rust 1.33.


انظر ملاحظات الإصدار لمزيد من التفاصيل.


تحسينات البضائع


أكبر تحسن في Cargo في هذا الإصدار هو أن لدينا الآن شريط تقدم!


تجريبي gif


انظر ملاحظات الإصدار لمزيد من التفاصيل.


المطورين 1.30.0


أنشأ الكثير من الأشخاص معًا الصدأ 1.30. لم نتمكن من إكمال العمل بدون كل واحد منكم. شكرا لك!


من مترجم: أعرب عن امتناني الخاص لأعضاء مجتمع Rustycrate وشخصي vitvakatu و Virtuos86 لمساعدتهم في الترجمة والتدقيق اللغوي.

Source: https://habr.com/ru/post/ar428073/


All Articles