PowerShell函数中Ref的工作原理及未传参变量被修改的疑问
为什么未传入函数的$b会被add-two修改?
先看你的代码:
$a = 1 $b = 2 function add-one{ param( [ref]$var ) $var.value += 1 } function add-two{ param( [ref]$var ) $donothing = $var.Value #How is $b visible inside this function? add-one -var ([ref]$b) add-one -var ([ref]$b) } add-two -var ([ref]$a) $a $b
实际输出:
1 4
核心原因:PowerShell的作用域继承与[ref]的本质
函数默认能访问父作用域变量
PowerShell的作用域规则是:默认情况下,函数可以访问**父作用域(这里是全局作用域)**中定义的变量,不需要显式传入。你在全局定义的$b,在add-two函数内部是直接可见的,所以[ref]$b能直接指向全局的$b变量,不会报错。[ref]是对原变量的直接引用
[ref]类型的本质是创建一个指向原变量的引用指针。当你在add-two里执行add-one -var ([ref]$b)时,你是把全局$b的引用传给了add-one函数。add-one里修改$var.Value,就是直接修改原变量$b的值,和$b在哪个作用域被定义无关——只要引用指向它,就能修改。代码执行流程拆解
- 全局作用域初始化
$a=1、$b=2 - 调用
add-two -var ([ref]$a):此时add-two的参数$var是$a的引用,但函数内部并没有操作这个引用,而是直接调用add-one传入[ref]$b - 两次调用
add-one:每次都会把$b的值加1,所以$b从2变成了4 - 全局作用域输出
$a(未被修改,还是1)和$b(已被修改为4)
简单说:不是$b被传入了add-two,而是add-two能直接看到全局的$b,再通过[ref]把它的引用传给add-one,最终导致$b被修改。
内容的提问来源于stack exchange,提问作者Tominik
相关产品推荐
相关产品推荐

