gpt4 book ai didi

powershell - 解释从 PowerShell 闭包调用的函数的作用域

转载 作者:行者123 更新时间:2023-12-04 00:56:34 26 4
gpt4 key购买 nike

以下 PowerShell 代码显示了从闭包调用的函数的意外作用域行为。你能解释这是“设计”还是缺陷?

function runblock($block) {
$x = 4
& $block
}

function printx() {
" in printx: x=" + $x
}

"PSVersion $($PSVersionTable.PSVersion)"

$x = 1
$b = {"In block x=" + $x ; $x = 3 ; printx}
$x = 2
runblock $b

$x = 1
$b = {"In closure x=" + $x ; $x = 3 ; printx}.GetNewClosure()
$x = 2
runblock $b

上面的输出是

PSVersion 3.0
In block x=4
in printx: x=3
In closure x=1
in printx: x=4

大多数输出​​对我来说很有意义:

脚本 block 输出 In block x=4因为它的父作用域是 runblock功能。 printx函数输出 x=3因为它的父范围是脚本 block 范围。

关闭输出 In closure x=1由于 $x 的值被 GetNewClosure 捕获称呼。一切如预期。

但:
调用 printx来自闭包输出 in printx: x=4 .所以 printx的范围executes within 不受 $x = 3 的闭包范围的影响。 .

我觉得奇怪的是,从普通脚本 block 调用的函数确实看到了脚本 block 范围内的变量,但从闭包调用的函数却看不到闭包中的变量。

最佳答案

考虑以下代码:

function Run {
param($ScriptBlock)
$a = 3
# Picture 4
& $ScriptBlock
}
function Print {
# Picture 6
"Print `$a=$a"
"Print `$b=$b"
}
$a = 1
$b = 1
# Picture 1
$SB = {
# Picture 5
"Closure `$a=$a"
"Closure `$b=$b"
Print
}.GetNewClosure()
# Picture 2
$a = 2
$b = 2
# Picture 3
Run $SB

它打印:

Closure $a=1
Closure $b=1
Print $a=3
Print $b=2

图一:您从全局范围开始,在其中定义一些变量。
Picture 1
图二: GetNewClosure()创建新模块并将变量复制到它。 (红色箭头显示父范围关系)
Picture 2
图三:你改变变量的值。模块范围不受影响。
Picture 3
图四:功能 Run叫。它创建局部变量 $a . (蓝色箭头显示调用方向)
Picture 4
图五: $SB调用的脚本 block 。脚本 block 绑定(bind)到模块 session 状态,所以你过渡到它。
Picture 5
图六:功能 Print叫。函数绑定(bind)到全局 session 状态,所以你返回到它。
Picture 6

关于powershell - 解释从 PowerShell 闭包调用的函数的作用域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35010317/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com