¿PowerShell admite constantes?


118

Me gustaría declarar algunas constantes enteras en PowerShell.

¿Hay alguna buena forma de hacerlo?

Respuestas:


121

Utilizar

Set-Variable test -option Constant -value 100

o

Set-Variable test -option ReadOnly -value 100

La diferencia entre "Constante" y "Solo lectura" es que una variable de solo lectura se puede eliminar (y luego volver a crear) mediante

Remove-Variable test -Force

mientras que una variable constante no se puede eliminar (incluso con -Force).

Consulte este artículo de TechNet para obtener más detalles.


4
Hmm, pero ¿cómo fuerza el tipo de datos cuando lo usa Set-Variable? Cuando se trata de variables, se puede usar, [string]$name = valuepero eso parece no ser posible para las constantes.
masi

8
@masi solo fuerza el valorSet-Variable test -option Constant -value [string]100
Monso

7
@Monso Necesita paréntesis alrededor del valor al especificar el tipo como ([string]100). Vea las respuestas a continuación.
Polymorphix

15

Aquí hay una solución para definir una constante como esta:

const myConst = 42

Solución tomada 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

1
Desafortunadamente, esto no funciona cuando Set-Constantestá contenido en un módulo. Creará una constante en el alcance del módulo, donde Set-Constantestá contenido. Como solución alternativa, se podría pasar un parámetro -Surround Global, pero eso no siempre se desea. Me gustaría crear una constante en otro módulo o localmente en una función.
zett42

11

Usar -option Constantcon el Set-Variablecmdlet:

Set-Variable myvar -option Constant -value 100

Ahora $myvartiene un valor constante de 100 y no se puede modificar.


1
Vaya, eso es torpe. Tienes que usar Set-Variable para hacerlo, ¿eh?
Tom Hazel

Sí, no hay forma poco torpe de hacerlo :)
Paolo Tedesco

1
también puede modificar una variable existente con set-variable (alias a sv) o usando get-variable (gv) y jugando con su propiedad Options.
x0n

Hmm, pero ¿cómo fuerza el tipo de datos cuando lo usa Set-Variable? Cuando se trata de variables, se puede usar, [string]$name = valuepero eso parece no ser posible para las constantes.
masi

@masi: consulte la respuesta de Mike Shepard en otra parte de esta página. Copiar y pegar desde allí, es:set-variable -name test -value ([int64]100) -option Constant
Chris J

11

Para usar un tipo de valor específico, digamos Int64, puede convertir explícitamente el valor usado en set-variable.

Por ejemplo:

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

Verificar,

$test | gm

Y verá que es un Int64 (en lugar de Int32, que sería normal para el valor 100).


5

Realmente me gusta el azúcar sintáctico que proporciona la respuesta de Rob:

const myConst = 42

Desafortunadamente, su solución no funciona como se esperaba cuando define la Set-Constantfunción en un módulo . Cuando se llama desde fuera del módulo, creará una constante en el alcance del módulo, donde Set-Constantse define, en lugar del alcance del llamador . Esto hace que la constante sea invisible para la persona que llama.

La siguiente función modificada soluciona este problema. La solución se basa en esta respuesta a la pregunta "¿Hay alguna forma de que un módulo de PowerShell llegue al alcance de su llamador?" .

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:

  • La función solo funciona cuando se llama desde fuera del módulo, donde está definida. Este es el caso de uso previsto, pero me gustaría agregar una verificación, si se llama desde el mismo módulo (en cuyo caso Set-Variable -scope 1debería funcionar), cuando descubra cómo hacerlo.
  • Cambié el nombre del parámetro -Meana -Value, por coherencia con Set-Variable.
  • La función podría ampliarse para configurar opcionalmente los indicadores Private, ReadOnlyy AllScope. Simplemente agregue los valores deseados al tercer argumento del PSVariableconstructor , al que se llama en el script anterior New-Object.

-4

PowerShell v5.0 debería permitir

[estática] [int] $ variable = 42

[estática] [DateTime] $ este día

y similares.


2
no funciona en ps 5.1. No se pudo encontrar el tipo [estático].
ThomasMX

5
Sin mencionar que la estática no es lo mismo que una constante
Kolob Canyon
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.