O PowerShell oferece suporte a constantes?

118

Eu gostaria de declarar algumas constantes inteiras no PowerShell.

Existe alguma boa maneira de fazer isso?

Tom Hazel
fonte

Respostas:

121

Usar

Set-Variable test -option Constant -value 100

ou

Set-Variable test -option ReadOnly -value 100

A diferença entre "Constant" e "ReadOnly" é que uma variável somente leitura pode ser removida (e depois recriada) por meio de

Remove-Variable test -Force

enquanto uma variável constante não pode ser removida (mesmo com -Force).

Consulte este artigo da TechNet para obter mais detalhes.

Motti Strom
fonte
4
Hmm, mas como você força o tipo de dados ao usar Set-Variable? Ao lidar com variáveis, pode-se usar, [string]$name = valuemas isso parece não ser possível para constantes?
Masi
8
@masi apenas forçou o valorSet-Variable test -option Constant -value [string]100
Monso,
7
@Monso Você precisa de parênteses ao redor do valor ao especificar o tipo como ([string]100). Veja as respostas abaixo.
Polimórfixo de
15

Aqui está uma solução para definir uma constante como esta:

const myConst = 42

Solução retirada de 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
roubar
fonte
1
Infelizmente, isso não funciona quando Set-Constantestá contido em um módulo. Ele criará uma constante no escopo do módulo, onde Set-Constantestá contido. Como alternativa, pode-se passar um parâmetro -Surround Global, mas isso nem sempre é desejado. Gostaria de criar uma constante em outro módulo ou localmente em uma função.
zett42 de
11

Use -option Constantcom o Set-Variablecmdlet:

Set-Variable myvar -option Constant -value 100

Agora $myvartem um valor constante de 100 e não pode ser modificado.

Paolo Tedesco
fonte
1
Uau, isso é desajeitado. Você tem que usar Set-Variable para fazer isso, hein?
Tom Hazel,
Sim, não há maneira desajeitada de fazer isso :)
Paolo Tedesco,
1
você também pode modificar uma variável existente com set-variable (alias para sv) ou usando get-variable (gv) e mexendo em sua propriedade Options.
x0 em
Hmm, mas como você força o tipo de dados ao usar Set-Variable? Ao lidar com variáveis, pode-se usar, [string]$name = valuemas isso parece não ser possível para constantes?
masi
@masi - veja a resposta de Mike Shepard em outra parte desta página. Copie e cole a partir daí:set-variable -name test -value ([int64]100) -option Constant
Chris J
11

Para usar um tipo específico de valor, digamos Int64, você pode converter explicitamente o valor usado em set-variable.

Por exemplo:

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

Checar,

$test | gm

E você verá que é um Int64 (em vez de Int32, o que seria normal para o valor 100).

Mike Shepard
fonte
5

Eu realmente gosto do açúcar sintático que a resposta de rob fornece:

const myConst = 42

Infelizmente, sua solução não funciona conforme o esperado quando você define a Set-Constantfunção em um módulo . Quando chamado de fora do módulo, ele criará uma constante no escopo do módulo, onde Set-Constanté definido, em vez do escopo do chamador . Isso torna a constante invisível para o chamador.

A função modificada a seguir corrige esse problema. A solução é baseada nesta resposta à pergunta "Existe alguma maneira de um módulo PowerShell chegar ao escopo de seu chamador?" .

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()] $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

Notas:

  • A função funciona, quando chamada de fora do módulo, onde está definida. Este é o caso de uso pretendido, mas eu gostaria de adicionar uma verificação, se ele é chamado do mesmo módulo (nesse casoSet-Variable -scope 1 deve funcionar), quando eu descobrir como fazer isso.
  • Renomei o parâmetro -Meanpara -Value, para consistência com Set-Variable.
  • A função pode ser estendida para definir opcionalmente os sinalizadores Private, ReadOnlye AllScope. Basta adicionar os valores desejados ao terceiro argumento do PSVariableconstrutor , que é chamado no script acima New-Object.
zett42
fonte
-4

PowerShell v5.0 deve permitir

[estático] [int] $ variável = 42

[estático] [DateTime] $ thisday

e similar.

MarkH
fonte
2
não funciona no ps 5.1. Incapaz de encontrar o tipo [estático].
ThomasMX,
5
Sem mencionar que estática não é a mesma coisa que constante
Kolob Canyon