【问题标题】:Pass strings by reference in Powershell?在Powershell中通过引用传递字符串?
【发布时间】:2018-12-07 23:38:47
【问题描述】:

如何通过引用父作用域来传递字符串?

这不起作用,因为字符串不是可接受的“值”。

function Submit([ref]$firstName){ 
    $firstName.value =  $txtFirstName.Text 
}

$firstName = $null
Submit([ref]$firstName)
$firstName

错误:“在此对象上找不到属性‘值’;请确保它存在且可设置”

这样做不会产生错误,但也不会改变变量:

$firstName = "nothing"

function Submit([ref]$firstName){ 
    $firstName =  $txtFirstName.Text 
} 

Submit([ref]$firstName)
$firstName

编辑:

自己做第一个代码块是可行的。但是,当尝试在我的脚本中执行此操作时,它会再次返回错误。我修复了它足以分配变量并做我想做的事,但它仍然抛出一个错误,我想知道如何解决这个问题。我认为这是因为它不喜欢变量;在运行会话期间发生变化。这是我的脚本的链接

https://github.com/InconspicuousIntern/Form/blob/master/Form.ps1

【问题讨论】:

  • 我在下面发布了一个“答案”。我将通过 cmets 与您合作。
  • 为什么需要通过引用传递字符串?一个函数可以输出一个字符串。
  • 您的第一个 sn-p 在概念上是正确的,应该按原样工作(在 v5.1 中验证,但我不希望 v3 有不同的行为,除非有错误)。预计第二个 sn-p 不起作用,因为通过直接分配给 $firstName,您正在创建一个 new [ref] 实例。
  • 我有多个字符串。欢迎使用更好的方法。自己做第一个代码块是可行的。但是,在我的代码中执行此操作会再次返回错误。我修复了它足以分配变量并做我想做的事,但它仍然抛出一个错误,我想知道如何解决这个问题。这是我的整个脚本github.com/InconspicuousIntern/Form/blob/master/Form.ps1

标签: function powershell parameter-passing pass-by-reference powershell-3.0


【解决方案1】:

请尝试一下,看看是否得到相同的结果?它对我有用,我真的没有太大变化。

$txtFirstName = [PSCustomObject]@{
    Text = "Something"
}

function Submit([ref]$var){ 
    $var.value =  $txtFirstName.Text 
}



$firstName = $null
Submit([ref]$firstName)
$firstName

【讨论】:

  • 您的回答应该是一条评论:OP 的原始代码(第一个 sn-p)应该 工作,并且他描述的症状与代码不匹配。我建议在 cmets 中进行对话,直到问题不再属于“无法再重现的问题或简单的印刷错误”关闭类别。
  • 感谢您的评论。 . .我更喜欢代码格式的答案。
【解决方案2】:

您的第一个 sn-p 在概念上是正确的并且按预期工作 - 它本身不会产生“在此对象上找不到属性'值'”错误.

由于以下行,您看到的错误只是您链接到的完整脚本的一部分:

$btnSubmit.Add_Click({ Submit })

这一行会导致您的Submit 函数在不带参数的情况下被调用,这反过来又导致$firstName 参数值为$null,这反过来又会导致上面引用的错误当您分配给$firstName.Value

相比之下,Submit 的以下调用(如在您的第一个 sn-p 中)是正确的:

Submit ([ref] $firstName)  # Note the recommended space after 'Submit' - see below.

[ref] $firstName 创建对调用者$firstName 变量 的(瞬态)引用,其中Submit 绑定到(本地)参数变量 $firstName(两者可以,但不必,最好不要同名),然后可以使用$firstName.Value 修改调用者的$firstName 变量。


语法说明:我特意在Submit([ref] $firstName) 之间放置了一个空格,以使一件事更清楚:

这里的(...)(括号)没有将整个参数list括起来,就像在方法调用中那样,它们将单个参数 [ref] $firstName - 必须的,因为否则该 表达式 不会被识别。

PowerShell 中的函数调用以所谓的 参数模式 进行解析,其语法更像是调用控制台应用程序的语法:参数以 空格 分隔,并且通常仅如果它们包含特殊字符,则需要引用。

例如,如果您还想将字符串'foo' 作为第二个位置参数传递给Submit

Submit ([ref] $firstName) foo

注意两个参数是如何用空格分隔的,foo 是如何不需要被引用的。


至于替代方法

[ref] 的主要目的是启用具有 ref / out 参数的 .NET 方法调用,并且如上所示,使用 [ref] 并非易事。

对于 PowerShell 函数的调用,通常有更简单的解决方案。

例如,您可以将 自定义对象 传递给您的函数,并让函数使用您想要返回的值更新其属性,这自然允许 多个 值被“归还”;例如:

function Submit($outObj){ 
    $outObj.firstName = 'a first name'
}

# Initialize the custom object that will receive values inside
# the Submit function.
$obj = [pscustomobject] @{ firstName = $null }

# Pass the custom object to Submit.
# Since a custom object is a reference type, a *reference* to it
# is bound to the $outObj parameter variable.
Submit $obj

$obj.firstName # -> 'a first name'

或者,您可以让Submit 自己构造自定义对象,然后简单地输出它:

function Submit { 
    # Construct and (implicitly) output a custom
    # object with all values of interest.
    [pscustomobject] @{ 
        firstName = 'a first name' 
    } 
}

$obj = Submit

$obj.firstName # -> 'a first name'

【讨论】:

    猜你喜欢
    • 2010-11-21
    • 2010-12-24
    • 2010-11-19
    • 2014-08-11
    • 2017-07-25
    • 2016-07-05
    • 2013-04-07
    • 2016-04-09
    • 2018-09-01
    相关资源
    最近更新 更多