为什么 Trap 块内的变量赋值在其外部不可见? [英] Why are variable assignments within a Trap block not visible outside it?

查看:47
本文介绍了为什么 Trap 块内的变量赋值在其外部不可见?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Why are the variable assignments that I make inside the Trap block not visible outside it?

$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 块内部和外部的结果是相同的,但这些是我看到的结果.

I would have expected the results from within and outside the Trap block to be identical but these are the results that I am seeing.

Integer Variable Inside:  1
String Variable Inside:  1
StringBuilder Variable Inside:  1
Integer Variable Outside:  0
String Variable Outside:
StringBuilder Variable Outside:  1

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

Notice that it is only the StringBuilder that retains its value.

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

I am guessing that this has something to do with the difference between value and reference types but can't quite pin it down.

推荐答案

With 上面提供的信息和通过一些进一步的实验,我现在明白这里发生了什么.

With info that slipsec provided above and through some further experimentation, I now understand what is happening here.

Joel 解释了陷阱范围的工作原理如下.

Joel explains how the Trap scope works as follows.

即使在我们的错误处理程序中能够访问的价值$Result 并看到它是 True ......并且即使我们将其设置为 $False,并且把它打印出来,这样你就可以看到它是设置……该函数仍然返回 True,因为陷阱范围不会修改外部范围,除非你显式设置 a 的范围多变的.注意:如果您使用过$script:result 而不是 $result (在$result 出现的每个实例在那个脚本中),你会得到字符串/注释导致的输出你期待.

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 范围内的代码能够读取变量设置的引用并修改它指向的对象 - 变量本身不需要更改.

So variables from outside the Trap scope can be read but not set because they are copies of the originals (thanks Jason). This is the reason why the Integer variable did not retain its value. The StringBuilder however, is a reference object and the variable is only a pointer to that object. The code within the Trap scope was able to read the reference that the variable was set to and modify the object to which it was pointing - the variable itself required no change.

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

Note that Joel's tip about specifying the scope of the variable allowed me to set the value of the Integer variable from within the Trap scope.

$script:整数 = 0;$string = [String]::Empty;$stringBuilder = new-object 'System.Text.StringBuilder';

$script: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

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

Note that the string variable does not retain its value because although it is a reference type, it is also immutable.

这篇关于为什么 Trap 块内的变量赋值在其外部不可见?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆