ir llamadas de función diferir perezosamente

contenido

1. Orden de ejecución de aplazamiento

2. Orden de ejecución retrasada

1. Usar desbloqueo simultáneo retrasado

2. Utilice la liberación retrasada de identificadores de archivos


        Cuando la función a la que pertenece defer está a punto de regresar, las instrucciones procesadas deferred se ejecutan en el orden inverso al defer, es decir, la primera instrucción defer se ejecuta en último lugar y la última instrucción defer se ejecuta primero. Las declaraciones que no son diferidas aún se ejecutan en el orden en que se ejecutaron.

1. Orden de ejecución de aplazamiento

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")
}

代码输出如下:
defer begin
defer end
3
2
1

2. Orden de ejecución retrasada

La instrucción defer es exactamente la instrucción que se ejecuta cuando la función sale, por lo que el uso de defer puede ser muy conveniente para tratar el problema de la liberación de recursos.

1. Usar desbloqueo simultáneo retrasado

En el siguiente ejemplo, el mapa se usará simultáneamente en la función. Para evitar condiciones de carrera, sync.Mutex se usa para bloquear, consulte el siguiente código:

var (
    // 一个演示用的映射
    valueByKey      = make(map[string]int)
    // 保证使用映射时的并发安全的互斥锁
    valueByKeyGuard sync.Mutex
)

// 根据键读取值
func readValue(key string) int {
    // 对共享资源加锁
    valueByKeyGuard.Lock()
    // 取值
    v := valueByKey[key]
    // 对共享资源解锁
    valueByKeyGuard.Unlock()
    // 返回值
    return v
}

Use la instrucción defer para simplificar la declaración anterior, consulte el siguiente código.

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

2. Utilice la liberación retrasada de identificadores de archivos

La operación de un archivo debe pasar por varios procesos de apertura del archivo, adquisición y operación del recurso del archivo y cierre del recurso. Si el recurso del archivo no se cierra después de la operación, el proceso nunca podrá liberar el recurso del archivo. .

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

En el ejemplo anterior, la parte en negrita es la operación de cierre del archivo. Los siguientes usos difieren para simplificar el código, el código es el siguiente:

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
}

Supongo que te gusta

Origin blog.csdn.net/demored/article/details/124197261
Recomendado
Clasificación