Rentang Go dapat beralih di atas peta dan irisan, tetapi saya bertanya-tanya apakah ada cara untuk beralih ke rentang angka, seperti ini:
for i := range [1..10] {
fmt.Println(i)
}
Atau adakah cara untuk merepresentasikan rentang bilangan bulat di Go seperti yang dilakukan Ruby dengan Range kelas ?
Berikut adalah program untuk membandingkan dua cara yang disarankan sejauh ini
Kompilasi seperti ini untuk menghasilkan pembongkaran
Ini jelas (saya telah menghapus instruksi dari daftar)
mempersiapkan
lingkaran
Dan di sini adalah with_iter
mempersiapkan
lingkaran
Jadi, Anda dapat melihat bahwa solusi iter jauh lebih mahal meskipun sepenuhnya inline pada fase setup. Pada fase loop ada instruksi tambahan di loop, tetapi itu tidak terlalu buruk.
Saya akan menggunakan sederhana untuk loop.
sumber
runtime.makeslice
dan yang lainnya tidak - Saya tidak perlu tolok ukur untuk mengetahui bahwa ini akan menjadi jauh lebih lambat!runtime.makeslice
cukup pintar untuk tidak mengalokasikan memori apa pun jika Anda meminta alokasi ukuran nol. Namun hal di atas masih menyebutnya, dan menurut tolok ukur Anda membutuhkan waktu 10nS lebih lama pada mesin saya.Disarankan oleh Mark Mishyn untuk menggunakan slice tetapi tidak ada alasan untuk membuat array dengan
make
dan digunakan dalamfor
slice yang dikembalikan ketika array yang dibuat melalui literal dapat digunakan dan itu lebih pendeksumber
for range [5]int{} {
5
ini adalah literal dan tidak dapat ditentukan pada saat run-time.iter adalah paket yang sangat kecil yang hanya menyediakan cara yang berbeda secara sintetik untuk beralih lebih dari bilangan bulat.
Rob Pike (penulis Go) mengkritiknya :
sumber
iter
versi ini sebenarnya menggunakan penekanan tombol yang lebih sedikit karenarange
daniter
akan melengkapi otomatis.for
loop bukan warga negara kelas satu Unix seperti sedang dalam perjalanan. Selain itu, tidak sepertifor
,seq
streaming ke output standar urutan angka. Apakah atau tidak untuk mengulangi mereka terserah konsumen. Meskipunfor i in $(seq 1 10); do ... done
umum di Shell, itu hanya satu cara untuk melakukan loop, yang dengan sendirinya hanya satu cara untuk mengkonsumsi outputseq
, meskipun sangat umum.i in range(10)
persis sepertii := 0; i < 10; i++
.Berikut ini adalah tolok ukur untuk membandingkan
for
pernyataan Go dengan ForClause danrange
pernyataan Go menggunakaniter
paket.iter_test.go
Keluaran:
sumber
Sementara saya bersimpati dengan kekhawatiran Anda tentang kekurangan fitur bahasa ini, Anda mungkin hanya ingin menggunakan
for
loop normal . Dan Anda mungkin akan lebih oke dengan itu daripada yang Anda pikirkan saat Anda menulis lebih banyak kode Go.Saya menulis paket iter ini - yang didukung oleh
for
loop idiomatik sederhana yang mengembalikan nilai lebih darichan int
- dalam upaya untuk memperbaiki desain yang ditemukan di https://github.com/bradfitz/iter , yang telah ditunjukkan memiliki caching dan masalah kinerja, serta implementasi yang cerdas, aneh, dan tidak intuitif. Versi saya sendiri beroperasi dengan cara yang sama:Namun, pembandingan menunjukkan bahwa penggunaan saluran adalah pilihan yang sangat mahal. Perbandingan 3 metode, yang dapat dijalankan dari
iter_test.go
dalam paket saya menggunakanmengukur seberapa buruk kinerjanya
Dalam prosesnya, tolok ukur ini juga menunjukkan bagaimana
bradfitz
solusi berkinerja buruk dibandingkan denganfor
klausa bawaan untuk ukuran loop10
.Singkatnya, sejauh ini tidak ada cara yang ditemukan untuk menduplikasi kinerja
for
klausa built-in sambil memberikan sintaksis sederhana untuk[0,n)
seperti yang ditemukan di Python dan Ruby.Yang memalukan karena mungkin akan mudah bagi tim Go untuk menambahkan aturan sederhana ke kompiler untuk mengubah garis seperti
ke kode mesin yang sama dengan
for i := 0; i < 10; i++
.Namun, agar adil, setelah menulis sendiri
iter.N
(tetapi sebelum membuat tolok ukur), saya kembali melalui program yang baru ditulis untuk melihat semua tempat yang bisa saya gunakan. Sebenarnya tidak banyak. Hanya ada satu tempat, di bagian non-vital dari kode saya, di mana saya bisa bertahan tanpafor
klausa default yang lebih lengkap .Jadi walaupun mungkin terlihat seperti ini adalah kekecewaan besar untuk bahasa pada prinsipnya, Anda mungkin menemukan - seperti saya - bahwa Anda sebenarnya tidak benar-benar membutuhkannya dalam praktik. Seperti yang diketahui oleh Rob Pike sebagai generik, Anda mungkin tidak benar-benar melewatkan fitur ini sebanyak yang Anda kira akan terjadi.
sumber
Jika Anda ingin hanya mengulangi rentang tanpa menggunakan dan indeks atau apa pun, contoh kode ini berfungsi dengan baik untuk saya. Tidak perlu deklarasi tambahan, tidak
_
. Belum memeriksa kinerjanya.PS Hari pertama di GoLang. Tolong, lakukan kritik jika itu pendekatan yang salah.
sumber
non-constant array bound
ke arahku.Anda juga dapat melihat github.com/wushilin/stream
Ini adalah aliran malas seperti konsep java.util.stream.
Semoga ini membantu
sumber
sumber
Saya telah menulis sebuah paket di Golang yang meniru fungsi jangkauan Python:
Paket https://github.com/thedevsaddam/iter
sumber