Rumah > pembangunan bahagian belakang > Golang > Apakah pernyataan pelaksanaan tertunda dalam bahasa Go

Apakah pernyataan pelaksanaan tertunda dalam bahasa Go

青灯夜游
Lepaskan: 2023-01-11 18:28:57
asal
1413 orang telah melayarinya

Dalam bahasa Go, penyataan pelaksanaan tertunda ialah penyataan tangguh dan sintaksnya ialah "tunda sebarang penyataan". Pernyataan penangguhan akan menangguhkan pemprosesan penyata yang mengikutinya Apabila fungsi yang menjadi milik penangguhan akan kembali, penyata tertunda akan dilaksanakan dalam susunan terbalik penangguhan, iaitu penyata yang ditangguhkan dahulu dilaksanakan terakhir, dan pernyataan yang ditangguhkan terakhir akan dilaksanakan terlebih dahulu.

Apakah pernyataan pelaksanaan tertunda dalam bahasa Go

Persekitaran pengendalian tutorial ini: sistem Windows 7, GO versi 1.18, komputer Dell G3.

Pernyataan pelaksanaan tertunda (penyataan tangguh) dalam bahasa Go

Terdapat penyataan pelaksanaan tertunda dalam bahasa Go, yang dikawal oleh penangguhan logo kata kunci. Kata kunci

tunda akan menangguhkan pemprosesan penyata yang mengikutinya Apabila fungsi yang menjadi milik penangguhan akan kembali, penyata pemprosesan yang tertunda akan dilaksanakan dalam susunan terbalik penangguhan, iaitu, pernyataan yang. ialah tangguh dahulu Penyataan yang dilaksanakan terakhir dan penyataan penangguhan terakhir dilaksanakan dahulu.

Formatnya adalah seperti berikut:

defer 任意语句
Salin selepas log masuk

Pernyataan selepas penangguhan tidak akan dilaksanakan serta-merta Apabila fungsi yang menjadi milik penangguhan akan kembali, semua penyata tangguh dalam badan fungsi akan dalam susunan penampilan dilaksanakan dalam susunan terbalik, iaitu, pernyataan penangguhan terakhir dalam badan fungsi dilaksanakan terlebih dahulu.

package main

import "fmt"

func main(){
	fmt.Println("start now")
	defer fmt.Println("这是第一句defer语句")
	defer fmt.Println("这是第二句defer语句")
	defer fmt.Println("这是第三句defer语句")
	fmt.Println("end")
}
Salin selepas log masuk

Hasil pelaksanaan adalah seperti berikut:

start now
end
这是第三句defer语句
这是第二句defer语句
这是第一句defer语句
Salin selepas log masuk

Memandangkan pernyataan penangguhan dipanggil apabila fungsi semasa akan kembali, penangguhan sering digunakan untuk melepaskan sumber.

Tertib pemprosesan berbilang penyata pelaksanaan tertunda

Apabila beberapa gelagat penangguhan didaftarkan, ia akan dilaksanakan dalam susunan terbalik (serupa dengan timbunan, iaitu, terakhir di keluar dahulu), kod berikut menangguhkan pemprosesan siri penyata cetakan berangka mengikut tertib, seperti ditunjukkan di bawah:

package main
import (
    "fmt"
)
func main() {
    fmt.Println("defer begin")
    // 将defer放入延迟调用栈
    defer fmt.Println(1)
    defer fmt.Println(2)
    // 最后一个放入, 位于栈顶, 最先调用
    defer fmt.Println(3)
    fmt.Println("defer end")
}
Salin selepas log masuk

Output kod adalah seperti berikut:

defer begin
defer end
3
2
1
Salin selepas log masuk

analisis keputusan adalah seperti berikut:

  • Tertib kelewatan kod diterbalikkan daripada perintah pelaksanaan akhir.

  • Panggilan tertunda dilakukan apabila fungsi di mana penangguhan terletak tamat apabila fungsi itu kembali normal atau apabila masa henti berlaku.

Gunakan penyataan pelaksanaan tertunda untuk melepaskan sumber apabila fungsi keluar

Menyusahkan untuk berurusan dengan operasi berpasangan dalam perniagaan atau logik Perkara seperti pembukaan dan menutup fail, menerima dan membalas permintaan, mengunci dan membuka kunci, dsb. Antara operasi ini, yang paling mudah diabaikan ialah pelepasan dan penutupan sumber yang betul pada setiap keluar fungsi.

Pernyataan penangguhan ialah kenyataan yang dilaksanakan apabila fungsi keluar, jadi menggunakan penangguhan boleh menangani isu keluaran sumber dengan sangat mudah.

1) Gunakan buka kunci serentak tertunda

Dalam contoh berikut, peta akan digunakan secara serentak dalam fungsi Untuk mengelakkan keadaan perlumbaan, penyegerakan.Mutex digunakan untuk mengunci.

var (
    // 一个演示用的映射
    valueByKey      = make(map[string]int)
    // 保证使用映射时的并发安全的互斥锁
    valueByKeyGuard sync.Mutex
)
// 根据键读取值
func readValue(key string) int {
    // 对共享资源加锁
    valueByKeyGuard.Lock()
    // 取值
    v := valueByKey[key]
    // 对共享资源解锁
    valueByKeyGuard.Unlock()
    // 返回值
    return v
}
Salin selepas log masuk

Perihalan kod adalah seperti berikut:

  • Baris 3, nyatakan peta, kuncinya ialah jenis rentetan dan nilainya adalah int.

  • Baris 5, peta tidak selamat serentak secara lalai, sediakan penyegerakan.Mutex mutex untuk melindungi akses peta.

  • Baris 9, fungsi readValue() memberikan kunci dan mengembalikan nilai selepas mendapat nilai daripada peta Fungsi ini akan digunakan dalam persekitaran serentak dan perlu memastikan keselamatan serentak .

  • Baris 11, gunakan mutex untuk mengunci.

  • Baris 13, dapatkan nilai daripada peta.

  • Barisan 15, buka kunci menggunakan mutex.

  • Barisan 17, mengembalikan nilai peta yang diperolehi.

Gunakan pernyataan tangguh untuk memudahkan pernyataan di atas, rujuk kod di bawah.

func readValue(key string) int {
    valueByKeyGuard.Lock()
   
    // defer后面的语句不会马上调用, 而是延迟到函数结束时调用
    defer valueByKeyGuard.Unlock()
    return valueByKey[key]
}
Salin selepas log masuk

Baris ke-6 hingga ke-8 dalam kod di atas adalah pengubahsuaian dan penambahan pada kod sebelumnya Penerangan kod adalah seperti berikut:

  • Barisan 6 adalah antara. Selepas eksklusif dikunci, gunakan pernyataan tangguh untuk menambah buka kunci Penyataan ini tidak akan dilaksanakan dengan serta-merta, tetapi akan dilaksanakan apabila fungsi readValue() kembali.

  • Baris 8, proses menanyakan nilai dari peta dan mengembalikannya, adalah sama seperti cara menulis tanpa menggunakan mutex Berbanding dengan kod di atas, cara penulisan ini adalah lebih ringkas.

2) Menggunakan keluaran tertangguh pemegang fail

Operasi fail memerlukan beberapa proses: membuka fail, mendapatkan dan mengendalikan sumber fail dan menutup sumber Jika selepas operasi selesai, Jika sumber fail tidak ditutup, proses tidak akan dapat mengeluarkan sumber fail Dalam contoh berikut, fungsi untuk mendapatkan saiz fail berdasarkan nama fail akan dilaksanakan membuka fail, mendapatkan saiz fail dan menutup fail Memandangkan setiap langkah operasi sistem memerlukan pengendalian ralat diperlukan, dan setiap langkah pemprosesan akan menyebabkan kemungkinan keluar, jadi sumber perlu dikeluarkan apabila keluar, dan kami memerlukannya. untuk memberi perhatian yang teliti untuk melepaskan sumber fail dengan betul di pintu keluar fungsi, rujuk kod berikut:

// 根据文件名查询其大小
func fileSize(filename string) int64 {
    // 根据文件名打开文件, 返回文件句柄和错误
    f, err := os.Open(filename)
    // 如果打开时发生错误, 返回文件大小为0
    if err != nil {
        return 0
    }
    // 取文件状态信息
    info, err := f.Stat()
   
    // 如果获取信息时发生错误, 关闭文件并返回文件大小为0
    if err != nil {
        f.Close()
        return 0
    }
    // 取文件大小
    size := info.Size()
    // 关闭文件
    f.Close()
   
    // 返回文件大小
    return size
}
Salin selepas log masuk

Penerangan kod adalah seperti berikut:

  • Baris 2 mentakrifkan fungsi untuk mendapatkan saiz fail, dan nilai pulangan ialah nilai saiz fail 64-bit.

  • Baris 5, gunakan fungsi Open() yang disediakan oleh pakej os untuk membuka fail berdasarkan nama fail yang diberikan, dan kembalikan pemegang yang digunakan untuk mengendalikan fail dan ralat operasi .

  • Barisan 8, jika ralat berlaku semasa proses pembukaan, seperti fail tidak dijumpai, fail telah diduduki, dsb., saiz fail akan dikembalikan sebagai 0.

  • 第 13 行,此时文件句柄 f 可以正常使用,使用 f 的方法 Stat() 来获取文件的信息,获取信息时,可能也会发生错误。

  • 第 16~19 行对错误进行处理,此时文件是正常打开的,为了释放资源,必须要调用 f 的 Close() 方法来关闭文件,否则会发生资源泄露。

  • 第 22 行,获取文件大小。

  • 第 25 行,关闭文件、释放资源。

  • 第 28 行,返回获取到的文件大小。

在上面的例子中,第 25 行是对文件的关闭操作,下面使用 defer 对代码进行简化,代码如下:

func fileSize(filename string) int64 {
    f, err := os.Open(filename)
    if err != nil {
        return 0
    }
    // 延迟调用Close, 此时Close不会被调用
    defer f.Close()
    info, err := f.Stat()
    if err != nil {
        // defer机制触发, 调用Close关闭文件
        return 0
    }
    size := info.Size()
    // defer机制触发, 调用Close关闭文件
    return size
}
Salin selepas log masuk

代码中加粗部分为对比前面代码而修改的部分,代码说明如下:

  • 第 10 行,在文件正常打开后,使用 defer,将 f.Close() 延迟调用,注意,不能将这一句代码放在第 4 行空行处,一旦文件打开错误,f 将为空,在延迟语句触发时,将触发宕机错误。

  • 第 16 行和第 22 行,defer 后的语句(f.Close())将会在函数返回前被调用,自动释放资源。

【相关推荐:Go视频教程编程教学

Atas ialah kandungan terperinci Apakah pernyataan pelaksanaan tertunda dalam bahasa Go. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:php.cn
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
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan