Swift全局变量与函数异常行为:代码结果不符求解
为什么输出是0 0 16?
我们一步步拆解代码的执行逻辑:
全局元素加载阶段:程序启动后,所有全局变量(
a、b)和函数被注册,但都未执行初始化逻辑。注意代码顺序:a的声明在b之前,myFunc的定义在b之后。触发
a的初始化:当print语句执行时,按从左到右顺序计算第一个参数changeBAndGetA()。进入函数后执行return a——这是第一次访问a,因此触发a的初始化:- 调用
myFunc(),函数返回b。此时b的显式初始化器=19还未执行,但b作为全局值类型变量,Swift会自动赋予它默认初始值0(全局变量无需显式初始化,会被默认赋值)。 a被赋值为myFunc()返回的0,且a是常量,后续无法修改。
- 调用
修改
b的值:回到changeBAndGetA()函数,继续执行b = 16——此时b已经被默认初始化为0,这里的赋值是普通变量赋值,将b改为16。注意:b的显式初始化器=19永远不会执行,因为全局变量只能被初始化一次,b已经通过默认值完成了初始化。计算
print剩余参数:- 第二个参数
a已初始化完成,值为0。 - 第三个参数
b当前值为16。
- 第二个参数
输出结果:最终打印出
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
相关产品推荐
相关产品推荐

