PowerShell supporta le costanti?


118

Vorrei dichiarare alcune costanti intere in PowerShell.

C'è un buon modo per farlo?

Risposte:


121

Uso

Set-Variable test -option Constant -value 100

o

Set-Variable test -option ReadOnly -value 100

La differenza tra "Constant" e "ReadOnly" è che una variabile di sola lettura può essere rimossa (e quindi ricreata) tramite

Remove-Variable test -Force

mentre una variabile costante non può essere rimossa (anche con -Force).

Per ulteriori dettagli, vedere questo articolo di TechNet .


4
Hmm, ma come si forza il tipo di dati quando si utilizza Set-Variable? Quando si tratta di variabili si può usare [string]$name = valuema sembra non essere possibile per le costanti?
masi

8
@masi forza solo il valoreSet-Variable test -option Constant -value [string]100
Monso

7
@Monso Hai bisogno di parentesi attorno al valore quando specifichi il tipo come ([string]100). Vedi le risposte di seguito.
Polymorphix

15

Ecco una soluzione per definire una costante come questa:

const myConst = 42

Soluzione tratta da 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
Sfortunatamente questo non funziona quando Set-Constantè contenuto in un modulo. Creerà una costante nell'ambito del modulo, dove Set-Constantè contenuto. Come soluzione alternativa si potrebbe passare un parametro -Surround Global, ma non è sempre voluto. Vorrei creare una costante in un altro modulo o localmente in una funzione.
zett42

11

Utilizzare -option Constantcon il Set-Variablecmdlet:

Set-Variable myvar -option Constant -value 100

Ora $myvarha un valore costante di 100 e non può essere modificato.


1
Wow, è goffo. Devi usare Set-Variable per farlo, eh?
Tom Hazel

Sì, non c'è un modo strano per farlo :)
Paolo Tedesco

1
puoi anche modificare una variabile esistente con set-variable (con alias a sv) o usando get-variable (gv) e armeggiando con la sua proprietà Options.
x0n

Hmm, ma come si forza il tipo di dati quando si utilizza Set-Variable? Quando si tratta di variabili si può usare [string]$name = valuema sembra non essere possibile per le costanti?
masi

@masi - vedi la risposta di Mike Shepard altrove in questa pagina. Copia e incolla da lì, è:set-variable -name test -value ([int64]100) -option Constant
Chris J

11

Per utilizzare un tipo specifico di valore, ad esempio Int64, è possibile eseguire il cast esplicito del valore utilizzato in set-variable.

Per esempio:

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

Controllare,

$test | gm

E vedrai che è un Int64 (anziché Int32, che sarebbe normale per il valore 100).


5

Mi piace molto lo zucchero sintattico fornito dalla risposta di rob :

const myConst = 42

Sfortunatamente la sua soluzione non funziona come previsto quando si definisce la Set-Constantfunzione in un modulo . Quando viene chiamato dall'esterno del modulo, creerà una costante nell'ambito del modulo, dove Set-Constantè definito, invece dell'ambito del chiamante . Ciò rende la costante invisibile al chiamante.

La seguente funzione modificata risolve questo problema. La soluzione si basa su questa risposta alla domanda "Esiste un modo per un modulo PowerShell di entrare nell'ambito del suo chiamante?" .

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

Appunti:

  • La funzione funziona solo se chiamata dall'esterno del modulo, dove è definita. Questo è il caso d'uso previsto, ma vorrei aggiungere un controllo, se viene chiamato dallo stesso modulo (nel qual caso Set-Variable -scope 1dovrebbe funzionare), quando ho scoperto come farlo.
  • Ho rinominato il parametro -Meanin -Value, per coerenza con Set-Variable.
  • La funzione potrebbe essere estesa per impostare facoltativamente i flag Private, ReadOnlye AllScope. Aggiungi semplicemente i valori desiderati al terzo argomento del PSVariablecostruttore , che viene chiamato nello script sopra New-Object.

-4

PowerShell v5.0 dovrebbe consentire

[statico] [int] $ variabile = 42

[statico] [DateTime] $ thisday

e simili.


2
non funziona su ps 5.1. Impossibile trovare il tipo [statico].
ThomasMX

5
Per non parlare del fatto che l'elettricità statica non è la stessa di una costante
Kolob Canyon il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.