go 闭包case

你提到的代码片段是一个匿名函数,并且它在定义后立即执行(即 IIFE,立即执行函数表达式)。这个匿名函数内部对 z = x / y 的赋值操作能够影响到外部变量的原因在于 Go 语言的作用域规则和闭包机制。

解释

  1. 闭包机制

    • 匿名函数可以访问其定义时所在作用域中的变量。这种特性称为闭包。在你的例子中,匿名函数捕获了外部的 zxy 变量。
  2. 变量作用域

    • 如果 zxy 是在匿名函数外部声明的变量(例如在 main 函数中),那么这些变量是全局可见的,或者至少在匿名函数的作用域链中是可见的。
    • 当你在匿名函数内部修改这些变量时,实际上是在修改这些变量的原始内存位置,因此这些变化会反映到外部。
  3. 立即执行函数表达式 (IIFE)

    • 匿名函数定义后立即执行,这意味着它的副作用(如变量赋值)会立即生效。

示例代码分析

假设完整的代码如下:

package main

import "fmt"

func main() {
    var x, y, z int
    x = 10
    y = 2

    func() {
        defer func() {
            if r := recover(); r != nil {
                fmt.Println("recovered from ", r)
            }
        }()
        z = x / y
    }()

    fmt.Println("Result:", z) // 输出: Result: 5
}

在这个例子中:

  • xyz 是在 main 函数中声明的变量。
  • 匿名函数捕获了这些变量,并在其内部进行了 z = x / y 的计算。
  • 由于 z 是在 main 函数中声明的,因此匿名函数内部对 z 的修改会影响到 main 函数中的 z

关键点总结

  • 闭包:匿名函数可以访问并修改其定义时所在作用域中的变量。
  • 立即执行:匿名函数定义后立即执行,其副作用会立即生效。
  • 变量作用域:如果变量在外部作用域中声明,则匿名函数内部可以访问和修改这些变量。

注意事项

  • 确保 y 不为零,以避免除零错误。你可以添加检查逻辑来防止这种情况发生。
func main() {
    var x, y, z int
    x = 10
    y = 2

    func() {
        defer func() {
            if r := recover(); r != nil {
                fmt.Println("recovered from ", r)
            }
        }()
        if y == 0 {
            panic("division by zero")
        }
        z = x / y
    }()

    fmt.Println("Result:", z)
}

这样可以确保程序在 y 为零时不会崩溃,并且能够正确恢复。

posted @   仁义礼智信的  阅读(2)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
点击右上角即可分享
微信分享提示