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

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]的本质

  1. 函数默认能访问父作用域变量
    PowerShell的作用域规则是:默认情况下,函数可以访问**父作用域(这里是全局作用域)**中定义的变量,不需要显式传入。你在全局定义的$b,在add-two函数内部是直接可见的,所以[ref]$b能直接指向全局的$b变量,不会报错。

  2. [ref]是对原变量的直接引用
    [ref]类型的本质是创建一个指向原变量的引用指针。当你在add-two里执行add-one -var ([ref]$b)时,你是把全局$b的引用传给了add-one函数。add-one里修改$var.Value,就是直接修改原变量$b的值,和$b在哪个作用域被定义无关——只要引用指向它,就能修改。

  3. 代码执行流程拆解

  • 全局作用域初始化$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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 17:45:17