Rust 1.35.0 Rilis: Implementasi Karakter Fungsional dan Inovasi Lainnya

Saya sajikan kepada Anda terjemahan publikasi pada versi baru dari bahasa pemrograman favorit semua orang.


Pendahuluan


Tim bahasa pemrograman Rust dengan bangga mengumumkan versi baru, 1.35.0. Rust adalah bahasa pemrograman yang memungkinkan setiap orang untuk mengembangkan perangkat lunak yang andal dan cepat.


Jika Anda menginstal versi Rust sebelumnya menggunakan rustup , mendapatkan versi saat ini tidak akan sulit:


 $ rustup update stable 

Jika Anda masih belum memiliki rustup , Anda bisa mendapatkannya dari halaman yang sesuai di situs web kami. Ulasan terperinci dari rilis ini tersedia di GitHub.


Apa yang termasuk dalam versi stabil?


Inovasi utama dari rilis ini mencakup implementasi FnOnce, FnMut dan Fn pada masing-masing Box<dyn FnOnce> , Box<dyn FnMut> dan Box<dyn Fn> , secara Box<dyn FnMut> .


Serta fungsi inline (penutupan) dapat dikonversi ke pointer fungsi tidak aman. Makro dbg! diperkenalkan di Rust 1.32.0 sekarang bisa dipanggil tanpa menentukan argumen.


Selain itu, rilis ini memperkenalkan banyak stabilisasi perpustakaan standar. Di bawah ini adalah yang paling signifikan, tetapi analisis rinci dari beberapa di antaranya tersedia.


Karakter Fn* diimplementasikan pada Box<dyn Fn*>


Di Rust 1.35.0, karakter FnOnce , FnMut dan Fn diimplementasikan pada Box<dyn FnOnce> , Box<dyn FnMut> dan Box<dyn Fn> Box<dyn FnMut> .


Di masa lalu, jika Anda ingin memanggil fungsi yang dienkapsulasi dalam Box<T> , Anda harus menggunakan FnBox , karena objek Box<dyn FnOnce> dan sejenisnya tidak mengimplementasikan sifat-sifat Fn* sesuai. Itu juga mengganggu transfer fungsi yang dikemas dalam Box<T> ke kode yang sedang menunggu pelaksana sifat Fn (diusulkan untuk membuat fungsi built-in sementara).


Ini disebabkan oleh ketidakmampuan kompiler untuk mendeteksi implementasi tersebut. Kelemahan ini telah diperbaiki dengan diperkenalkannya unsized_locals .


Namun, sekarang Anda dapat menggunakan fungsi yang dienkapsulasi dalam Box<T> bahkan di tempat-tempat yang mengharapkan sifat fungsional untuk diimplementasikan. Misalnya, kode di bawah ini mengkompilasi tanpa kesalahan:


 fn foo(x: Box<dyn Fn(u8) -> u8>) -> Vec<u8> { vec![1, 2, 3, 4].into_iter().map(x).collect() } 

Box<dyn FnOnce> dapat dipanggil tanpa Box<dyn FnOnce> keributan:


 fn foo(x: Box<dyn FnOnce()>) { x() } 

Mengubah ke pointer yang tidak aman


Sejak zaman Rust 1.19.0, menjadi mungkin untuk mengubah fungsi-fungsi yang disematkan yang tidak menangkap lingkungan menjadi pointer fungsi. Misalnya, Anda dapat menulis:


 fn twice(x: u8, f: fn(u8) -> u8) -> u8 { f(f(x)) } fn main() { assert_eq!(42, twice(0, |x| x + 21)); } 

Namun sayangnya, fitur ini belum diperluas ke pointer fungsi yang tidak aman. Rilis ini memperkenalkan perubahan yang dijelaskan di atas:


 ///  ,   `unsafe fn`. unsafe fn call_unsafe_fn_ptr(f: unsafe fn()) { f() } fn main() { // :     //       //  unsafe { call_unsafe_fn_ptr(|| { dbg!(); }); } } 

Panggil dbg!() Tanpa argumen


Karena banyaknya panggilan println! sebagai dbg! pertanian kolektif, makro dbg! diperkenalkan di Rust 1.32.0 dbg! . Ingatlah bahwa makro ini memungkinkan Anda untuk dengan cepat menangkap hasil ekspresi tertentu dengan konteks:


 fn main() { let mut x = 0; if dbg!(x == 1) { x += 1; } dbg!(x); } 

Baris kode di atas akan mencetak ke terminal hasil dari ekspresi x == 1 dan x masing-masing:


 [src/main.rs:4] x == 1 = false [src/main.rs:8] x = 0 

Seperti disebutkan di bagian sebelumnya, di mana fungsi call_unsafe_fn_ptr dapat dipanggil, dbg!() Juga dipanggil tanpa menentukan argumen. Ini bisa sangat berguna untuk menemukan cabang program yang dipilih:


 fn main() { let condition = true; if condition { dbg!(); // [src/main.rs:5] } } 

Stabilisasi perpustakaan standar


Di Rust 1.35.0, banyak komponen perpustakaan standar telah distabilkan. Selain itu, beberapa implementasi telah diperkenalkan, yang dapat Anda baca di sini .


Salin tanda nomor floating-point ke nomor lain


Dengan rilis ini, metode copysign baru telah ditambahkan ke primitif floating point (lebih khusus, f32 dan f64 ):



Seperti nama metode yang disarankan, Anda dapat menggunakannya untuk menyalin tanda dari satu nomor ke yang lain:


 fn main() { assert_eq!(3.5_f32.copysign(-0.42), -3.5); } 

Memeriksa apakah Range berisi nilai tertentu


Rust 1.35.0 memperoleh beberapa metode baru pada struktur Range* :



Dengan menggunakan metode ini, Anda dapat dengan mudah memeriksa apakah nilai tertentu dalam rentang. Misalnya, Anda dapat menulis:


 fn main() { if (0..=10).contains(&5) { println!("5    [0; 10]."); } } 

Terjemahkan (peta) dan pisahkan RefCell dipinjam


Dengan munculnya Rust 1.35.0, Anda dapat menerjemahkan dan membagi nilai RefCell dipinjam ke dalam serangkaian nilai yang dipinjam menjadi komponen berbeda dari data yang dipinjam:



RefCell nilai RefCell melalui fungsi sebaris


Rilis ini memperkenalkan metode replace_with mudah digunakan yang dinyatakan pada struktur RefCell :



Hash pointer atau tautan ke


Rilis ini memperkenalkan fungsi ptr::hash , yang membutuhkan pointer mentah untuk hashing. Menggunakan ptr::hash dapat mencegah hash dari nilai yang ditentukan atau direferensikan alih-alih alamat itu sendiri.


Salin Option<&T> Konten Option<&T>


Dengan awal Rust 1.0.0, Option::cloned metode Option::cloned pada Option<&T> dan Option<&mut T> memungkinkan untuk mengkloning konten jika ada ( Some(_) ). Namun, kloning kadang-kadang bisa menjadi operasi yang mahal, dan metode opt.cloned() tidak menjelaskan petunjuk apa pun.


Rilis ini berkontribusi:



Fungsionalitas opt.copied() sama dengan opt.cloned() . Namun, metode yang dijelaskan di atas meminta kondisi T: Copy , kegagalan yang akan menyebabkan kesalahan kompilasi.


Perubahan Clippy


Clippy, alat yang menangkap ketidaksempurnaan umum untuk meningkatkan kualitas kode, telah memperoleh drop_bounds . Ini bekerja ketika fungsi umum meminta pemenuhan kondisi T: Drop :


 fn foo<T: Drop>(x: T) {} 

Ini sering merupakan kesalahan karena primitif tidak menerapkan Drop . Selain itu, T: Drop tidak mencakup tipe seperti String , yang tidak memiliki perilaku destruktif, melainkan hasil dari tipe inline (seperti Vec<u8> ).


Selain drop_bounds , rilis ini membagi redundant_closure menjadi redundant_closure dan redundant_closure_for_method_calls .


Baca rilis lengkap Clippy di sini .


Perubahan Cargo


Penjelasan rinci tentang perubahan Cargo tersedia di sini .


Anggota 1.35.0


Banyak orang datang bersama untuk membuat Rust 1.35.0. Kami tidak bisa melakukan ini tanpa kalian semua, terima kasih !


Dari penerjemah


Dengan pertanyaan tentang bahasa Rust, mereka akan dapat membantu Anda dalam obrolan Telegram berbahasa Rusia atau dalam obrolan serupa untuk pendatang baru .

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


All Articles