You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift全局变量与函数异常行为:代码结果不符求解

为什么输出是0 0 16?

我们一步步拆解代码的执行逻辑:

  1. 全局元素加载阶段:程序启动后,所有全局变量(a、b)和函数被注册,但都未执行初始化逻辑。注意代码顺序:a的声明在b之前,myFunc的定义在b之后。

  2. 触发a的初始化:当print语句执行时,按从左到右顺序计算第一个参数changeBAndGetA()。进入函数后执行return a——这是第一次访问a,因此触发a的初始化:

    • 调用myFunc(),函数返回b。此时b的显式初始化器=19还未执行,但b作为全局值类型变量,Swift会自动赋予它默认初始值0(全局变量无需显式初始化,会被默认赋值)。
    • a被赋值为myFunc()返回的0,且a是常量,后续无法修改。
  3. 修改b的值:回到changeBAndGetA()函数,继续执行b = 16——此时b已经被默认初始化为0,这里的赋值是普通变量赋值,将b改为16。注意:b的显式初始化器=19永远不会执行,因为全局变量只能被初始化一次,b已经通过默认值完成了初始化。

  4. 计算print剩余参数:

    • 第二个参数a已初始化完成,值为0。
    • 第三个参数b当前值为16。
  5. 输出结果:最终打印出0 0 16。

为什么你预期的16 16 16不对?

你误解了全局变量延迟初始化的规则:

  • 全局变量的延迟初始化是指第一次被访问时才执行其显式初始化器,但如果在显式初始化器执行前,变量被其他代码读取(触发默认初始化),那么显式初始化器就会被跳过。
  • 这个例子中,a的初始化提前读取了b,导致b被默认初始化为0,b=19的显式初始化逻辑永远不会运行,自然无法得到预期的19或16。

补充:即使把b作为参数传入myFunc,结果一致的原因

如果修改代码让b作为参数传入myFunc,比如:

let a = myFunc(b: b)
var b = 19

func myFunc(b: Int) -> Int {
    b
}

此时a的初始化需要传入b,同样会在b的显式初始化器执行前读取它,b被默认初始化为0,a的值还是0,后续b被改为16,输出结果仍然是0 0 16。

内容的提问来源于stack exchange,提问作者Krishna murthy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 21:30:57