Skip to main content
 首页 » 编程设计

powershell之为什么 Trap block 内的变量赋值在其外部不可见

2025年01月19日21softidea

为什么我在 Trap 块内部进行的变量分配在它外部不可见?

$integer = 0; 
$string = [String]::Empty; 
$stringBuilder = new-object 'System.Text.StringBuilder'; 
 
trap 
{ 
    $integer = 1; 
    $string = '1'; 
    $stringBuilder.Append('1'); 
 
    write-host "Integer Variable Inside: " $integer; 
    write-host "String Variable Inside: " $string; 
    write-host "StringBuilder Variable Inside: " $stringBuilder; 
 
    continue; 
} 
$dummy = 1/$zero; 
 
write-host "Integer Variable Outside: " $integer; 
write-host "String Variable Outside: " $string; 
write-host "StringBuilder Variable Outside: " $stringBuilder; 

我原以为 Trap 块内部和外部的结果是相同的,但这些是我看到的结果。
Integer Variable Inside:  1 
String Variable Inside:  1 
StringBuilder Variable Inside:  1 
Integer Variable Outside:  0 
String Variable Outside: 
StringBuilder Variable Outside:  1 

请注意,只有 StringBuilder 保留其值。

我猜这与值和引用类型之间的差异有关,但不能完全确定。

请您参考如下方法:

info that slipsec provided以上并通过一些进一步的实验,我现在明白这里发生了什么。

乔尔 explains Trap 范围的工作原理如下。

Even though in our error handler we were able to access the value of $Result and see that it was True … and even though we set it to $False, and printed it out so you could see it was set … the function still returns True, because the trap scope doesn’t modify the external scope unless you explicitly set the scope of a variable. NOTE: If you had used $script:result instead of $result (in every instance where $result appears in that script), you would get the output which the string/comments led you to expect.



所以来自 Trap 范围之外的变量可以被读取但不能设置,因为它们是原始的副本(感谢 Jason)。这就是 Integer 变量没有保留其值的原因。然而,StringBuilder 是一个引用对象,而变量只是一个指向该对象的指针。 Trap 范围内的代码能够读取变量设置的引用并修改它指向的对象 - 变量本身不需要更改。

请注意,Joel 关于指定变量范围的提示允许我从 Trap 范围内设置 Integer 变量的值。

$脚本:整数= 0;
$string = [String]::Empty;
$stringBuilder = new-object 'System.Text.StringBuilder';
trap 
{ 
    $script:integer = 1; 
    $string = '1'; 
    $stringBuilder.Append('1'); 
 
    write-host "Integer Variable Inside: " $script:integer; 
    write-host "String Variable Inside: " $string; 
    write-host "StringBuilder Variable Inside: " $stringBuilder; 
    continue; 
} 
$dummy = 1/$zero; 
 
write-host "Integer Variable Outside: " $script:integer; 
write-host "String Variable Outside: " $string; 
write-host "StringBuilder Variable Outside: " $stringBuilder; 

……这就是结果。
Integer Variable Inside:  1 
String Variable Inside:  1 
StringBuilder Variable Inside:  1 
Integer Variable Outside:  1 
String Variable Outside: 
StringBuilder Variable Outside:  1 

请注意,字符串变量不会保留其值,因为尽管它是引用类型,但它也是不可变的。