Memahami terator Go

Aug 18, 2024 am 06:32 AM

Understanding Go terators

Ramai orang nampaknya keliru dengan iterator yang baru ditambah dalam Go, itulah sebabnya saya memutuskan untuk menulis satu lagi artikel cuba menerangkannya dengan cara yang semudah mungkin.

Bagaimana mereka dipanggil oleh Go?

Pertama, saya fikir adalah penting untuk memahami cara iterator dipanggil dan digunakan oleh Go, dan ia sebenarnya agak mudah, mari kita gunakan kepingan.Semua iterator sebagai contoh. Berikut ialah cara anda biasanya menggunakan iterator ini:

package main

import (
    "fmt"
    "slices"
)

func main() {
    slice := []string{
        "Element 1",
        "Element 2",
        "Element 3",
        "Element 4",
    }

    for index, element := range slices.All(slice) {
        if index >= 2 {
            break
        }
        fmt.Println(index, element)
    }

    // Output:
    // 0 Element 1
    // 1 Element 2
}

Dan inilah rupa sebenarnya:

package main

import (
    "fmt"
    "slices"
)

func main() {
    slice := []string{
        "Element 1",
        "Element 2",
        "Element 3",
        "Element 4",
    }

    slices.All(slice)(func (index int, element string) bool {
        if index >= 2 {
            return false // break
        }
        fmt.Println(index, element)

        return true // continue loop as normal
    })

    // Output:
    // 0 Element 1
    // 1 Element 2
}

Apa yang berlaku ialah badan gelung sedang "digerakkan" untuk menghasilkan fungsi yang dihantar kepada lelaran, manakala continue dan break masing-masing diubah untuk mengembalikan true dan return false. return true juga ditambahkan pada penghujung gelung untuk menandakan bahawa kami ingin mendapatkan elemen seterusnya, jika tiada keputusan lain yang dibuat sebelum ini.

Ini bukan pendedahan yang tepat tentang apa yang dilakukan pengkompil dan saya belum menyemak pelaksanaan Go untuk menyemak ini, tetapi mereka menghasilkan hasil yang setara daripada pemerhatian saya.

Bagaimana untuk mencipta iterator anda sendiri dan pelaksanaannya

Sekarang, setelah anda memahami cara mereka dipanggil dan menyedari betapa mudahnya ia sebenarnya, lebih mudah untuk memahami cara mencipta iterator anda sendiri dan pelaksanaannya.

Mari kita buat iterator nyahpepijat yang akan mencetak mesej nyahpepijat untuk setiap langkah pelaksanaan iterator yang akan meninjau semua elemen dalam kepingan (slices.Semua fungsi).

Pertama, saya akan mencipta fungsi pembantu kecil untuk log keluar mesej dengan masa pelaksanaan semasa.

import (
    "fmt"
    "time"
)

var START time.Time = time.Now()

func logt(message string) {
    fmt.Println(time.Since(START), message)
}

Kembali kepada iterator:

import (
    "iter"
)

func DebugIter[E any](slice []E) iter.Seq2[int, E] {
    logt("DebugIter called")

    // the same way iter.All returned function
    // we called in order to iterate over slice
    // here we are returning a function to
    // iterate over all slice elements too
    return func(yield func(int, E) bool) {
        logt("Seq2 return function called, starting loop")
        for index, element := range slice {
            logt("in loop, calling yield")
            shouldContinue := yield(index, element)
            if !shouldContinue {
                logt("in loop, yield returned false")
                return
            }
            logt("in loop, yield returned true")
        }
    }
}

Saya telah menambah beberapa kenyataan cetakan nyahpepijat supaya kita dapat melihat dengan lebih baik susunan pelaksanaan iterator dan cara ia bertindak balas terhadap kata kunci yang berbeza seperti putus dan teruskan.

Akhir sekali, mari gunakan iterator yang dilaksanakan:

func main() {
    slice := []string{
        "Element 1",
        "Element 2",
        "Element 3",
        "Element 4",
    }

    for index, element := range DebugIter(slice) {
        message := "got element in range of iter: " + element
        logt(message)
        if index >= 2 {
            break
        }
        if index > 0 {
            continue
        }
        time.Sleep(2 * time.Second)
        logt("ended sleep in range of iter")
    }
}

Akan memberikan kami output:

11.125µs DebugIter called
39.292µs Seq2 return function called, starting loop
42.459µs in loop, calling yield
44.292µs got element in range of iter: Element 1
2.001194292s ended sleep in range of iter
2.001280459s in loop, yield returned true
2.001283917s in loop, calling yield
2.001287042s got element in range of iter: Element 2
2.001291084s in loop, yield returned true
2.001293125s in loop, calling yield
2.0012955s got element in range of iter: Element 3
2.001297542s in loop, yield returned false

Contoh ini menunjukkan dengan baik cara iterator berfungsi dan dilaksanakan. Apabila menggunakan iterator dalam gelung julat semua arahan dalam blok gelung adalah jenis "dipindahkan" ke fungsi yang dipanggil hasil. Apabila kita memanggil hasil, kita pada asasnya meminta go runtime untuk melaksanakan apa sahaja yang terdapat dalam blok gelung dengan nilai berikut untuk lelaran ini, itulah juga sebabnya hasil akan disekat, jika badan gelung akan disekat. Sekiranya masa jalanan menentukan bahawa lelaran gelung ini sepatutnya berhenti, hasil akan kembali palsu, ia boleh berlaku apabila kata kunci pemecahan dipenuhi semasa pelaksanaan blok gelung, kita tidak seharusnya memanggil hasil lagi jika itu berlaku. Jika tidak, kita harus terus memanggil hasil.

Kod penuh:

package main

import (
    "fmt"
    "time"
    "iter"
)

var START time.Time = time.Now()

func logt(message string) {
    fmt.Println(time.Since(START), message)
}

func DebugIter[E any](slice []E) iter.Seq2[int, E] {
    logt("DebugIter called")

    // the same way iter.All returned function
    // we called in order to iterate over slice
    // here we are returning a function to
    // iterate over all slice elements too
    return func(yield func(int, E) bool) {
        logt("Seq2 return function called, starting loop")
        for index, element := range slice {
            logt("in loop, calling yield for")
            shouldContinue := yield(index, element)
            if !shouldContinue {
                logt("in loop, yield returned false")
                return
            }
            logt("in loop, yield returned true")
        }
    }
}

func main() {
    slice := []string{
        "Element 1",
        "Element 2",
        "Element 3",
        "Element 4",
    }

    for index, element := range DebugIter(slice) {
        message := "got element in range of iter: " + element
        logt(message)
        if index >= 2 {
            break
        }
        if index > 0 {
            continue
        }
        time.Sleep(2 * time.Second)
        logt("ended sleep in range of iter")
    }

    // unfold compiler magic
    //  DebugIter(slice)(func (index int, element string) bool {
    //    message := "got element in range of iter: " + element
    //    logt(message)
    //    if index >= 2 {
    //      return false
    //    }
    //    if index > 0 {
    //      return true
    //    }
    //    time.Sleep(2 * time.Second)
    //    logt("ended sleep in range of iter")
    //
    //    return true
    //  })
}

Atas ialah kandungan terperinci Memahami terator Go. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

Video Face Swap

Video Face Swap

Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Artikel Panas

Skop pembolehubah PHP dijelaskan
4 minggu yang lalu By 百草
Petua untuk menulis komen php
4 minggu yang lalu By 百草
Mengulas kod dalam php
4 minggu yang lalu By 百草

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas

Tutorial PHP
1510
276
Pergi untuk pemprosesan audio/video Pergi untuk pemprosesan audio/video Jul 20, 2025 am 04:14 AM

Inti pemprosesan audio dan video terletak pada pemahaman proses asas dan kaedah pengoptimuman. 1. Proses asas termasuk pengambilalihan, pengekodan, penghantaran, penyahkodan dan main balik, dan setiap pautan mempunyai kesukaran teknikal; 2. Masalah biasa seperti penyimpangan audio dan video, kelewatan lag, bunyi bunyi, gambar kabur, dan lain -lain boleh diselesaikan melalui pelarasan segerak, pengoptimuman pengekodan, modul pengurangan hingar, pelarasan parameter, dan sebagainya; 3. Adalah disyorkan untuk menggunakan FFMPEG, OpenCV, WebRTC, GSTREAMER dan alat lain untuk mencapai fungsi; 4. Dari segi pengurusan prestasi, kita harus memberi perhatian kepada pecutan perkakasan, penetapan kadar bingkai resolusi yang munasabah, masalah konvensyen dan masalah kebocoran memori. Menguasai perkara utama ini akan membantu meningkatkan kecekapan pembangunan dan pengalaman pengguna.

Membangunkan pengendali Kubernet di mana sahaja Membangunkan pengendali Kubernet di mana sahaja Jul 25, 2025 am 02:38 AM

Cara yang paling berkesan untuk menulis Kubernetesoperator adalah untuk menggunakan Go untuk menggabungkan Kubebuilder dan pengawal-runtime. 1. Memahami corak pengendali: Tentukan sumber tersuai melalui CRD, tulis pengawal untuk mendengar perubahan sumber dan lakukan gelung perdamaian untuk mengekalkan keadaan yang diharapkan. 2. Gunakan Kubebuilder untuk memulakan projek dan membuat API untuk menghasilkan CRD, pengawal dan konfigurasi secara automatik. 3. Tentukan spec dan struktur status CRD dalam API/V1/MYAPP_TYPES.GO, dan menjalankan makeManifests untuk menjana cRDYAML. 4. Daftar masuk dalam pengawal

Teknik Pengoptimuman Permintaan Pergi untuk PostgreSQL/MySQL Teknik Pengoptimuman Permintaan Pergi untuk PostgreSQL/MySQL Jul 19, 2025 am 03:56 AM

TooptimizegoapplicationsInteractingWithPostgreSqlormysql, focusonindexing, selectivequeries, connectionhandling, caching, andormefficiency.1) useproperIndexing-identifyfrequeriedcolumns, addIndExessely, andusecompositeindexesformultifulty-columnuerformultiulti

Pergi OAuth2 Pelaksanaan Pelanggan dan Pelayan Pergi OAuth2 Pelaksanaan Pelanggan dan Pelayan Jul 16, 2025 am 02:57 AM

Pelaksanaan OAuth2 dibahagikan kepada klien dan pelayan. Pelanggan menggunakan pakej Golang.org/OAuth2. Langkah -langkahnya ialah: 1. Memperkenalkan pakej; 2. Konfigurasikan maklumat klien dan bina objek konfigurasi; 3. Menjana pautan kebenaran; 4. Proses panggilan balik untuk mendapatkan token; 5. Membina pelanggan HTTP dengan kebenaran. Pelayan mengambil Go-OAuth2/OAuth2 sebagai contoh, dan prosesnya termasuk: 1. Inisialisasi penyimpanan; 2. Tetapkan maklumat pelanggan; 3. Buat contoh perkhidmatan OAuth2; 4. Tulis kebenaran pemprosesan laluan dan permintaan token. Nota termasuk: isu silang domain, pengesahan status, HTTPS didayakan, pengurusan kesahihan token, dan granulariti kawalan skop.

Membaca dari Stdin dalam Contoh Membaca dari Stdin dalam Contoh Jul 27, 2025 am 04:15 AM

Gunakan fmt.scanf untuk membaca input diformat, sesuai untuk data berstruktur yang mudah, tetapi rentetan dipotong ketika menghadapi ruang; 2. Adalah disyorkan untuk menggunakan bufio.scanner untuk membaca garis demi baris, menyokong input berbilang baris, pengesanan EOF dan input saluran paip, dan boleh mengendalikan kesilapan pengimbasan; 3. Gunakan io.readall (os.stdin) untuk membaca semua input sekaligus, sesuai untuk memproses data blok besar atau aliran fail; 4. Sambutan utama masa nyata memerlukan perpustakaan pihak ketiga seperti golang.org/x/term, dan Bufio mencukupi untuk senario konvensional; Cadangan Praktikal: Gunakan fmt.scan untuk input mudah interaktif, gunakan bufio.scanner untuk input baris atau saluran paip, gunakan io.readall untuk data blok besar, dan sentiasa mengendalikan

Peruntukan timbunan vs timbunan dengan petunjuk di Go Peruntukan timbunan vs timbunan dengan petunjuk di Go Jul 23, 2025 am 04:14 AM

Peruntukan Stack sesuai untuk pembolehubah tempatan kecil dengan kitaran hayat yang jelas, dan diuruskan secara automatik, dengan kelajuan yang cepat tetapi banyak sekatan; Peruntukan timbunan digunakan untuk data dengan kitaran hayat yang panjang atau tidak pasti, dan fleksibel tetapi mempunyai kos prestasi. Pengkompil GO secara automatik menentukan kedudukan peruntukan pembolehubah melalui analisis melarikan diri. Jika pembolehubah boleh melarikan diri dari skop fungsi semasa, ia akan diperuntukkan kepada timbunan. Situasi biasa yang menyebabkan melarikan diri termasuk: mengembalikan penunjuk pembolehubah tempatan, memberikan nilai kepada jenis antara muka, dan lulus dalam goroutine. Hasil analisis melarikan diri dapat dilihat melalui -gcflags = " -m". Apabila menggunakan petunjuk, anda harus memberi perhatian kepada kitaran hidup yang berubah -ubah untuk mengelakkan pelarian yang tidak perlu.

Pergi untuk pengkomputeran saintifik dan analisis berangka Pergi untuk pengkomputeran saintifik dan analisis berangka Jul 23, 2025 am 01:53 AM

GO Language boleh digunakan untuk pengiraan saintifik dan analisis berangka, tetapi perlu difahami. Kelebihannya terletak pada sokongan dan prestasi konkurensi, yang sesuai untuk algoritma selari seperti penyelesaian yang diedarkan, simulasi Monte Carlo, dan sebagainya; Perpustakaan komuniti seperti gonum dan MAT64 menyediakan fungsi pengiraan numerik asas; Pengaturcaraan hibrid boleh digunakan untuk memanggil C/C dan Python melalui CGO atau antara muka untuk meningkatkan kepraktisan. Batasannya adalah bahawa ekosistem tidak matang seperti python, visualisasi dan alat lanjutan lebih lemah, dan beberapa dokumen perpustakaan tidak lengkap. Adalah disyorkan untuk memilih senario yang sesuai berdasarkan ciri GO dan merujuk kepada contoh kod sumber untuk menggunakannya secara mendalam.

Pergi untuk perpustakaan manipulasi imej Pergi untuk perpustakaan manipulasi imej Jul 21, 2025 am 12:23 AM

Perpustakaan pemprosesan imej yang biasa termasuk pakej imej perpustakaan standard dan perpustakaan pihak ketiga, seperti pengimejan, bimg, dan imagick. 1. Pakej imej sesuai untuk operasi asas; 2. Pencitraan mempunyai fungsi lengkap dan API mudah, yang sesuai untuk kebanyakan keperluan; 3. BIMG didasarkan pada libvips, mempunyai prestasi yang kuat, yang sesuai untuk imej besar atau kesesuaian yang tinggi; 4. Imagick mengikat Imagemagick, yang berkuasa tetapi mempunyai ketergantungan yang berat. Cepat melaksanakan skala imej dan penanaman. Anda boleh menggunakan perpustakaan pengimejan untuk menyelesaikannya melalui beberapa baris kod dalam saiz semula dan fungsi cropanchor, dan menyokong konfigurasi parameter berganda. Menambah penapis atau nada penyesuaian dapat dicapai melalui fungsi transformasi warna yang disediakan oleh imaginasi, seperti graysc

See all articles