为什么从另一个函数内部可以成功访问本地定义的变量? [英] Why is a variable defined locally successfully accessible from within another function?
问题描述
请参见下面的代码.将两个文件放在同一目录中,然后从PS ISE运行Form1.ps1
See code below. Put both files in the same directory and run Form1.ps1
from the PS ISE
如您所见,(局部)变量$localVar
是在事件处理程序$button2_Click
中定义的.因此,我假设$localVar
在$button2_Click
的范围之外不会存在,也不会存在,而范围由定义事件处理程序的花括号定义.
As you can see, the (local) variable $localVar
is defined in the event handler $button2_Click
. As such, I assumed $localVar
would not/could not exist outside the scope of $button2_Click
with scope defined by the braces that define the event handler.
但是,正如您所看到的,我使用$localVar
的内容将$textbox2.Text
加载到函数fA
中.当您单击Test
按钮时,两个文本框都显示$localVar
However, as you can see, I use the contents of $localVar
to load $textbox2.Text
in the function fA
. When you click the Test
button, both textboxes display the contents of $localVar
这是怎么回事?为什么从fA
内部可以访问$button2_Click
的$localVar
?
What's going on? Why is $button2_Click
's $localVar
accessible from within fA
?
Form1.ps1
function fA
{
$textbox2.Text = $localVar
}
$button2_Click =
{
$localVar = "set in `$button2_Click"
$textbox1.Text = $localVar
fA
}
. (Join-Path $PSScriptRoot 'Form1.designer.ps1')
$textbox1.Text = ""
$Form1.ShowDialog()
Form1.designer.ps1
[void][System.Reflection.Assembly]::Load('System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a')
[void][System.Reflection.Assembly]::Load('System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089')
$Form1 = New-Object -TypeName System.Windows.Forms.Form
[System.Windows.Forms.Button]$button2 = $null
[System.Windows.Forms.TextBox]$textBox1 = $null
[System.Windows.Forms.TextBox]$textBox2 = $null
[System.Windows.Forms.Label]$label1 = $null
[System.Windows.Forms.Label]$label2 = $null
[System.Windows.Forms.Button]$button1 = $null
function InitializeComponent
{
$button2 = (New-Object -TypeName System.Windows.Forms.Button)
$textBox1 = (New-Object -TypeName System.Windows.Forms.TextBox)
$textBox2 = (New-Object -TypeName System.Windows.Forms.TextBox)
$label1 = (New-Object -TypeName System.Windows.Forms.Label)
$label2 = (New-Object -TypeName System.Windows.Forms.Label)
$Form1.SuspendLayout()
#
#button2
#
$button2.Location = (New-Object -TypeName System.Drawing.Point -ArgumentList @([System.Int32]148,[System.Int32]12))
$button2.Name = [System.String]'button2'
$button2.Size = (New-Object -TypeName System.Drawing.Size -ArgumentList @([System.Int32]77,[System.Int32]36))
$button2.TabIndex = [System.Int32]0
$button2.Text = [System.String]'Test'
$button2.UseVisualStyleBackColor = $true
$button2.add_Click($button2_Click)
#
#textBox1
#
$textBox1.Location = (New-Object -TypeName System.Drawing.Point -ArgumentList @([System.Int32]67,[System.Int32]69))
$textBox1.Name = [System.String]'textBox1'
$textBox1.Size = (New-Object -TypeName System.Drawing.Size -ArgumentList @([System.Int32]106,[System.Int32]20))
$textBox1.TabIndex = [System.Int32]1
#
#textBox2
#
$textBox2.Location = (New-Object -TypeName System.Drawing.Point -ArgumentList @([System.Int32]247,[System.Int32]69))
$textBox2.Name = [System.String]'textBox2'
$textBox2.Size = (New-Object -TypeName System.Drawing.Size -ArgumentList @([System.Int32]106,[System.Int32]20))
$textBox2.TabIndex = [System.Int32]2
#
#label1
#
$label1.AutoSize = $true
$label1.Location = (New-Object -TypeName System.Drawing.Point -ArgumentList @([System.Int32]12,[System.Int32]72))
$label1.Name = [System.String]'label1'
$label1.Size = (New-Object -TypeName System.Drawing.Size -ArgumentList @([System.Int32]47,[System.Int32]13))
$label1.TabIndex = [System.Int32]3
$label1.Text = [System.String]'textbox1'
#
#label2
#
$label2.AutoSize = $true
$label2.Location = (New-Object -TypeName System.Drawing.Point -ArgumentList @([System.Int32]194,[System.Int32]72))
$label2.Name = [System.String]'label2'
$label2.Size = (New-Object -TypeName System.Drawing.Size -ArgumentList @([System.Int32]47,[System.Int32]13))
$label2.TabIndex = [System.Int32]4
$label2.Text = [System.String]'textbox2'
#
#Form1
#
$Form1.ClientSize = (New-Object -TypeName System.Drawing.Size -ArgumentList @([System.Int32]374,[System.Int32]110))
$Form1.Controls.Add($label2)
$Form1.Controls.Add($label1)
$Form1.Controls.Add($textBox2)
$Form1.Controls.Add($textBox1)
$Form1.Controls.Add($button2)
$Form1.Name = [System.String]'Form1'
$Form1.ResumeLayout($false)
$Form1.PerformLayout()
Add-Member -InputObject $Form1 -Name base -Value $base -MemberType NoteProperty
Add-Member -InputObject $Form1 -Name button2 -Value $button2 -MemberType NoteProperty
Add-Member -InputObject $Form1 -Name textBox1 -Value $textBox1 -MemberType NoteProperty
Add-Member -InputObject $Form1 -Name textBox2 -Value $textBox2 -MemberType NoteProperty
Add-Member -InputObject $Form1 -Name label1 -Value $label1 -MemberType NoteProperty
Add-Member -InputObject $Form1 -Name label2 -Value $label2 -MemberType NoteProperty
Add-Member -InputObject $Form1 -Name button1 -Value $button1 -MemberType NoteProperty
}
. InitializeComponent
推荐答案
函数fA
会看到您的变量,因为它在创建$localVar
的脚本块的 child 范围内运行-这是PowerShell的常规行为,并非特定于ISE.
Function fA
sees your variable, because it runs in a child scope of the script block in which $localVar
was created - this is general PowerShell behavior, and not specific to the ISE.
当使用$localVar = ...
创建 变量时,它在以下意义上是 local :
When you create a variable with $localVar = ...
, it is local in the following sense:
-
在相同范围内可见且可直接修改,但在任何 parent 范围内均不可见.
visible and directly modifiable in the same scope, but not in any parent scopes.
可见,但不能在此处直接修改.
visible in all child scopes, but not directly modifiable there.
- 您可以使用
$private:
作用域修饰符来防止子作用域看到变量. - 如果您分配一个最初在 parent 范围(例如
$localVar = ...
)中创建的变量(仅按名称),则将创建一个 new em>,局部变量,在 current 范围内,它遮盖了原始变量. - 可以 修改父范围的变量,但是您需要使用
Set-Variable -Scope
或范围修饰符(例如$script:
)(请参见下面的链接).
- You can use the
$private:
scope modifier to prevent child scopes from seeing a variable. - If you assign to a variable (by name only) that was originally created in a parent scope, (e.g.,
$localVar = ...
), you'll instead create a new, local variable, in the current scope, which shadows the original variable. - It is possible to modify a parent scope's variables, but you need to use either
Set-Variable -Scope
or a scope modifier such as$script:
(see links below).
有关更多信息,请参见:
For more information, see:
此答案的最后一部分,其中提供了简要摘要.
the last section of this answer, which provides a concise summary.
这篇关于为什么从另一个函数内部可以成功访问本地定义的变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!