【问题标题】:Does PowerShell support constants?PowerShell 是否支持常量?
【发布时间】:2011-02-06 04:25:04
【问题描述】:

我想在 PowerShell 中声明一些整数常量。

有什么好的方法吗?

【问题讨论】:

    标签: powershell constants


    【解决方案1】:

    使用

    Set-Variable test -Option Constant -Value 100
    

    Set-Variable test -Option ReadOnly -Value 100
    

    “Constant”和“ReadOnly”的区别在于可以通过以下方式删除(然后重新创建)只读变量

    Remove-Variable test -Force
    

    而不能删除常量变量(即使使用 -Force)。

    更多详情请见this TechNet article

    【讨论】:

    • 嗯,但是当使用Set-Variable如何强制数据类型?在处理变量时,可以使用[string]$name = value,但这似乎不适用于常量?
    • @masi 只是强制值Set-Variable test -option Constant -value [string]100
    • @Monso 在指定([string]100) 之类的类型时,您需要在值周围加上括号。请参阅下面的答案。
    • 这不会创建一个常量。因为该变量不能在验证集中使用。 [ValidateSet($RunTypeStandard ,"Debug" ,"DebugWithEnvironment" )] 我仍然收到“属性参数需要是常量”的错误
    【解决方案2】:

    下面是定义这样一个常量的解决方案:

    const myConst = 42
    

    解决方案取自http://poshcode.org/4063

        function Set-Constant {
      <#
        .SYNOPSIS
            Creates constants.
        .DESCRIPTION
            This function can help you to create constants so easy as it possible.
            It works as keyword 'const' as such as in C#.
        .EXAMPLE
            PS C:\> Set-Constant a = 10
            PS C:\> $a += 13
    
            There is a integer constant declaration, so the second line return
            error.
        .EXAMPLE
            PS C:\> const str = "this is a constant string"
    
            You also can use word 'const' for constant declaration. There is a
            string constant named '$str' in this example.
        .LINK
            Set-Variable
            About_Functions_Advanced_Parameters
      #>
      [CmdletBinding()]
      param(
        [Parameter(Mandatory=$true, Position=0)]
        [string][ValidateNotNullOrEmpty()]$Name,
    
        [Parameter(Mandatory=$true, Position=1)]
        [char][ValidateSet("=")]$Link,
    
        [Parameter(Mandatory=$true, Position=2)]
        [object][ValidateNotNullOrEmpty()]$Mean,
    
        [Parameter(Mandatory=$false)]
        [string]$Surround = "script"
      )
    
      Set-Variable -n $name -val $mean -opt Constant -s $surround
    }
    
    Set-Alias const Set-Constant
    

    【讨论】:

    • 不幸的是,当Set-Constant 包含在模块中时,这不起作用。它将在模块范围内创建一个常量,其中包含Set-Constant。作为一种解决方法,可以传递参数-Surround Global,但这并不总是需要的。我想在另一个模块中或在函数中本地创建一个常量。
    【解决方案3】:

    要使用特定类型的值,比如 Int64,您可以显式转换 set-variable 中使用的值。

    例如:

    set-variable -name test -value ([int64]100) -option Constant
    

    检查,

    $test | gm
    

    您会看到它是一个 Int64(而不是 Int32,这对于值 100 来说是正常的)。

    【讨论】:

    • 这可以缩短为:set -o const test ([int64]100)。这是少数情况之一,我宁愿在脚本中使用别名而不是完整的命令名,以便让我的大脑更快地“扫描”源代码。
    • 我不同意。 set -o 对我来说有点太神秘了,无法在脚本中使用。
    【解决方案4】:

    -option ConstantSet-Variable cmdlet 一起使用:

    Set-Variable myvar -option Constant -value 100
    

    现在$myvar 有一个常数值 100,不能修改。

    【讨论】:

    • 哇,太笨重了。你必须使用 Set-Variable 来做到这一点,对吧?
    • 是的,没有笨拙的方法:)
    • 您还可以使用 set-variable(别名为 sv)或使用 get-variable (gv) 并修改其 Options 属性来修改现有变量。
    • 嗯,但是在使用Set-Variable 时如何强制数据类型?在处理变量时,可以使用[string]$name = value,但这似乎不适用于常量?
    • @masi - 请参阅本页其他地方的 Mike Shepard 的回答。从那里复制和粘贴,它是:set-variable -name test -value ([int64]100) -option Constant
    【解决方案5】:

    我真的很喜欢rob's answer 提供的语法糖:

    const myConst = 42
    

    不幸的是,当您在 模块 中定义 Set-Constant 函数时,他的解决方案无法正常工作。当从模块外部调用时,它将在模块范围内创建一个常量,其中定义了Set-Constant,而不是调用者的范围。这使得调用者看不到常量。

    以下修改后的功能解决了这个问题。解决方法是基于this answer到问题"Is there any way for a powershell module to get at its caller's scope?"

    function Set-Constant {
        <#
        .SYNOPSIS
            Creates constants.
        .DESCRIPTION
            This function can help you to create constants so easy as it possible.
            It works as keyword 'const' as such as in C#.
        .EXAMPLE
            PS C:\> Set-Constant a = 10
            PS C:\> $a += 13
    
            There is a integer constant declaration, so the second line return
            error.
        .EXAMPLE
            PS C:\> const str = "this is a constant string"
    
            You also can use word 'const' for constant declaration. There is a
            string constant named '$str' in this example.
        .LINK
            Set-Variable
            About_Functions_Advanced_Parameters
        #>
        [CmdletBinding()]
        param(
            [Parameter(Mandatory=$true, Position=0)] [string] $Name,
            [Parameter(Mandatory=$true, Position=1)] [char] [ValidateSet("=")] $Link,
            [Parameter(Mandatory=$true, Position=2)] [object] $Value
        )
    
        $var = New-Object System.Management.Automation.PSVariable -ArgumentList @(
            $Name, $Value, [System.Management.Automation.ScopedItemOptions]::Constant
        )
        
        $PSCmdlet.SessionState.PSVariable.Set( $var )
    }
    
    Set-Alias const Set-Constant
    

    注意事项:

    • only 函数在从定义它的模块外部 调用时起作用。这是预期的用例,但我想添加一个检查,检查它是否是从同一个模块调用的(在这种情况下 Set-Variable -scope 1 应该工作),当我发现如何这样做时。
    • 为了与Set-Variable 保持一致,我已将参数-Mean 重命名为-Value
    • 该功能可以扩展为可选地设置PrivateReadOnlyAllScope 标志。只需将所需的值添加到 PSVariable constructor 的第三个参数,在上述脚本中通过 New-Object 调用。

    【讨论】:

    • 您可以检查调用堆栈以找出分配发生的位置:if ((Get-PSCallStack)[1].Command -eq 'your-module-file-name.psm1') { &lt;# inside module #&gt; } else { &lt;# outside #&gt; }
    【解决方案6】:

    PowerShell v5.0 应该允许

    [静态] [int] $variable = 42

    [静态] [日期时间] $thisday

    等等。

    【讨论】:

    • 不适用于 ps 5.1。找不到类型 [静态]。
    • 别说,静态不等于常量
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-22
    • 2011-05-06
    • 1970-01-01
    • 2014-02-04
    • 2015-08-08
    相关资源
    最近更新 更多