PowerShell prend-il en charge les constantes?

118

Je voudrais déclarer des constantes entières dans PowerShell.

Y a-t-il un bon moyen de faire cela?

Tom Hazel
la source

Réponses:

121

Utilisation

Set-Variable test -option Constant -value 100

ou

Set-Variable test -option ReadOnly -value 100

La différence entre "Constant" et "ReadOnly" est qu'une variable en lecture seule peut être supprimée (puis recréée) via

Remove-Variable test -Force

alors qu'une variable constante ne peut pas être supprimée (même avec -Force).

Consultez cet article TechNet pour plus de détails.

Motti Strom
la source
4
Hmm, mais comment forcer le type de données lors de l'utilisation Set-Variable? Quand on traite des variables, on peut utiliser [string]$name = valuemais cela ne semble pas possible pour les constantes?
masi
8
@masi vient de forcer la valeurSet-Variable test -option Constant -value [string]100
Monso
7
@Monso Vous avez besoin de parenthèses autour de la valeur lorsque vous spécifiez un type comme ([string]100). Voir les réponses ci-dessous.
Polymorphix
15

Voici une solution pour définir une constante comme celle-ci:

const myConst = 42

Solution tirée 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
Rob
la source
1
Malheureusement, cela ne fonctionne pas lorsqu'il Set-Constantest contenu dans un module. Cela créera une constante dans la portée du module, où Set-Constantest contenue. Comme solution de contournement, on peut passer un paramètre -Surround Global, mais ce n'est pas toujours souhaité. Je souhaite créer une constante dans un autre module ou localement dans une fonction.
zett42
11

Utiliser -option Constantavec l' Set-Variableapplet de commande:

Set-Variable myvar -option Constant -value 100

A maintenant $myvarune valeur constante de 100 et ne peut pas être modifiée.

Paolo Tedesco
la source
1
Wow, c'est maladroit. Vous devez utiliser Set-Variable pour le faire, hein?
Tom Hazel
Oui, il n'y a pas de moyen simple de le faire :)
Paolo Tedesco
1
vous pouvez également modifier une variable existante avec set-variable (alias sv) ou en utilisant get-variable (gv) et en bricolant sa propriété Options.
x0n
Hmm, mais comment forcer le type de données lors de l'utilisation Set-Variable? Quand on traite des variables, on peut utiliser [string]$name = valuemais cela ne semble pas possible pour les constantes?
masi
@masi - voir la réponse de Mike Shepard ailleurs dans cette page. Copier et coller à partir de là, c'est:set-variable -name test -value ([int64]100) -option Constant
Chris J
11

Pour utiliser un type spécifique de valeur, par exemple Int64, vous pouvez convertir explicitement la valeur utilisée dans set-variable.

Par exemple:

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

Vérifier,

$test | gm

Et vous verrez qu'il s'agit d'un Int64 (plutôt que d'un Int32, ce qui serait normal pour la valeur 100).

Mike Shepard
la source
5

J'aime vraiment le sucre syntaxique fourni par la réponse de rob :

const myConst = 42

Malheureusement, sa solution ne fonctionne pas comme prévu lorsque vous définissez la Set-Constantfonction dans un module . Lorsqu'il est appelé depuis l'extérieur du module, il crée une constante dans la portée du module, où Set-Constantest définie, au lieu de la portée de l' appelant . Cela rend la constante invisible pour l'appelant.

La fonction modifiée suivante résout ce problème. La solution est basée sur cette réponse à la question "Y a-t-il un moyen pour un module PowerShell d'atteindre la portée de son appelant?" .

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

Remarques:

  • La fonction ne fonctionne que lorsqu'elle est appelée depuis l' extérieur du module, là où elle est définie. C'est le cas d'utilisation prévu, mais je voudrais ajouter une vérification, si elle est appelée à partir du même module (dans ce cas Set-Variable -scope 1devrait fonctionner), lorsque j'ai trouvé comment faire.
  • J'ai renommé le paramètre -Meanen -Value, par souci de cohérence avec Set-Variable.
  • La fonction peut être étendue pour définir éventuellement les indicateurs Private, ReadOnlyet AllScope. Ajoutez simplement les valeurs souhaitées au 3ème argument du PSVariableconstructeur , qui est appelé dans le script ci-dessus via New-Object.
zett42
la source
-4

PowerShell v5.0 devrait permettre

[statique] [int] $ variable = 42

[statique] [DateTime] $ thisday

etc.

MarkH
la source
2
ne fonctionne pas sur ps 5.1. Impossible de trouver le type [statique].
ThomasMX
5
Sans oublier, la statique n'est pas la même chose qu'une constante
Kolob Canyon