PowerShell的解析模式:参数(命令)模式与表达式模式 [英] PowerShell's parsing modes: argument (command) mode vs. expression mode

查看:92
本文介绍了PowerShell的解析模式:参数(命令)模式与表达式模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

谁能解释为什么从powershell函数返回$ false时,您无法使用比较运算符确定该函数是否已返回$ false,但是当您返回$ true时,比较结果为$ true吗?

Can anyone explain why when returning $false from a powershell function you are unable use a comparison operator to determine if the function has returned $false but when you return $true the comparison evaluates to $true?

function boolean {
    return $false
}

boolean -eq $false

function boolean {
    return $true
}

boolean -eq $true

>>>False
>>>True

您可以通过将函数调用设置为变量来解决此问题,但是我想知道是否有人可以解释这里发生了什么?

You can work around this by setting the function call to a variable, but I was wondering if anyone could explain what is happening here under the hood?

function boolean {
    return $false
}

$bool = boolean 
$bool -eq $false

function boolean {
    return $true
}

$bool = boolean
$bool -eq $true

>>>True
>>>True

推荐答案

PowerShell具有 两种基本解析模式:

PowerShell has two fundamental parsing modes:

  • 参数模式,其工作方式类似于传统的 shell

  • 在参数模式下,第一个标记被解释为命令名称 (例如,cmdlet名称,函数名称或可执行文件的文件名),参数 空格分隔的列表组成.
  • In argument mode, the first token is interpreted as a command name (such as cmdlet name, function name, or filename of an executable), followed by a whitespace-separated list of arguments.

表达式模式,其工作方式类似于传统的编程语言.

运行 Get-help about_Parsing 提供了这些模式的介绍;简而言之,第一个令牌确定应用哪种模式.
还要注意,给定的语句可能由以任何一种模式解析的部分组成.

Running Get-help about_Parsing provides an introduction to these modes; in short, it is the first token that determines which mode is applied.
Also note that a given statement may be composed of parts that are parsed in either mode.

boolean -eq $false argument 模式进行解析,因为它的 first令牌看起来像命令名称 (标识符,可以是程序名称,cmdlet名称,函数名称或别名.

boolean -eq $false is parsed in argument mode, because its first token looks like a command name (an identifier that could be a program name, cmdlet name, function name, or alias).

因此, -eq$false被解释为参数(参数值),以传递给函数boolean .

Therefore, -eq and $false are interpreted as arguments (parameter values) to pass to function boolean.

由于您的boolean函数以不强制仅将值传递给声明的参数的方式进行定义,因此实际上忽略了 参数,并且结果该语句是函数输出的任何内容($false$true).

Since your boolean functions are defined in a way that doesn't enforce passing values only to declared parameters, the arguments are effectively ignored, and the result of the statement is whatever the functions output ($false or $true).

Mike Shepard的回答所示,您可以使函数强制使用仅声明的参数(包括没有),并用装饰有[CmdletBinding()]属性的param()块,如果不经意间将参数传递给无参数的boolean函数,则至少会导致错误.

As demonstrated in Mike Shepard's answer, you can make a function enforce use of only declared parameters (including none) with a param() block decorated with the [CmdletBinding()] attribute, which would at least result in an error if you inadvertently passed arguments to the parameter-less boolean function.

您可以通过将函数调用设置为变量来解决此问题

You can work around this by setting the function call to a variable

$bool = boolean   # execute function and capture result in variable
$bool -eq $false  # use variable in the comparison 

之所以可行,是因为-eq语句$ 开头(在这种情况下为变量引用),这导致PowerShell在 expression 模式下进行解析,其中-eq被识别为 operator ,而$false被识别为其RHS.

The reason this works is that the -eq statement starts with $ - a variable reference in this case - which causes PowerShell to parse in expression mode, where -eq is recognized as an operator and $false as its RHS.

但是,不需要此中间步骤:

However, there is no need for this intermediate step:

强制将一段代码解释为表达式,请将其包含在(...) 中:

To force a piece of code to be interpreted as an expression, enclose it in (...):

(boolean) -eq $false # Calls function 'boolean' and uses result as LHS of -eq

(...)强制使用新的解析上下文(它本身以参数或表达式模式进行解析,再次取决于第一个标记),并且将结果作为处理表达式 .然后允许将其用作较大表达式的一部分,例如用作-eq运算符的操作数,或用作命令参数.

(...) forces a new parsing context (which in itself is parsed in either argument or expression mode, again depending on the 1st token) and treats the result as an expression. which then allows its use as part of a larger expression, such as as an operand of the -eq operator, or as a command argument.

这篇关于PowerShell的解析模式:参数(命令)模式与表达式模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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