Bagaimana saya bisa mengulang rentang di Rust dengan langkah selain 1? Saya berasal dari latar belakang C ++ jadi saya ingin melakukan sesuatu seperti
for(auto i = 0; i <= n; i+=2) {
//...
}
Di Rust saya perlu menggunakan range
fungsi, dan sepertinya tidak ada argumen ketiga yang tersedia untuk memiliki langkah kustom. Bagaimana saya bisa melakukannya?
Tampak bagi saya bahwa sampai
.step_by
metode dibuat stabil, seseorang dapat dengan mudah mencapai apa yang Anda inginkan denganIterator
(yang sebenarnya adalah apaRange
):struct SimpleStepRange(isize, isize, isize); // start, end, and step impl Iterator for SimpleStepRange { type Item = isize; #[inline] fn next(&mut self) -> Option<isize> { if self.0 < self.1 { let v = self.0; self.0 = v + self.2; Some(v) } else { None } } } fn main() { for i in SimpleStepRange(0, 10, 2) { println!("{}", i); } }
Jika seseorang perlu mengulang beberapa rentang dari tipe yang berbeda, kode dapat dibuat umum sebagai berikut:
use std::ops::Add; struct StepRange<T>(T, T, T) where for<'a> &'a T: Add<&'a T, Output = T>, T: PartialOrd, T: Clone; impl<T> Iterator for StepRange<T> where for<'a> &'a T: Add<&'a T, Output = T>, T: PartialOrd, T: Clone { type Item = T; #[inline] fn next(&mut self) -> Option<T> { if self.0 < self.1 { let v = self.0.clone(); self.0 = &v + &self.2; Some(v) } else { None } } } fn main() { for i in StepRange(0u64, 10u64, 2u64) { println!("{}", i); } }
Saya akan menyerahkan kepada Anda untuk menghilangkan pemeriksaan batas atas untuk membuat struktur ujung terbuka jika diperlukan loop tak terbatas ...
Keuntungan dari pendekatan ini adalah berfungsi dengan
for
sugaring dan akan terus berfungsi bahkan ketika fitur yang tidak stabil menjadi dapat digunakan; juga, tidak seperti pendekatan de-sugared yang menggunakan standarRange
, ia tidak kehilangan efisiensi dengan beberapa.next()
panggilan. Kekurangannya adalah dibutuhkan beberapa baris kode untuk mengatur iterator sehingga mungkin hanya sepadan untuk kode yang memiliki banyak loop.sumber
U
ke opsi kedua Anda bisa menggunakan tipe yang mendukung penambahan dengan tipe berbeda dan tetap menghasilkanT
. Misalnya waktu dan durasi muncul dalam pikiran.Gunakan num crate dengan range_step
sumber
Anda akan menulis kode C ++ Anda:
for (auto i = 0; i <= n; i += 2) { //... }
... di Rust seperti ini:
let mut i = 0; while i <= n { // ... i += 2; }
Saya rasa versi Rust juga lebih mudah dibaca.
sumber
continue
,, agar berfungsi dengan baik. Meski bisa dilakukan, desain ini mendorong bug.Jika Anda melangkah dengan sesuatu yang telah ditentukan sebelumnya, dan kecil seperti 2, Anda mungkin ingin menggunakan iterator untuk melangkah secara manual. misalnya:
let mut iter = 1..10; loop { match iter.next() { Some(x) => { println!("{}", x); }, None => break, } iter.next(); }
Anda bahkan dapat menggunakan ini untuk melangkah dengan jumlah yang berubah-ubah (meskipun ini pasti semakin lama dan sulit untuk dicerna):
let mut iter = 1..10; let step = 4; loop { match iter.next() { Some(x) => { println!("{}", x); }, None => break, } for _ in 0..step-1 { iter.next(); } }
sumber