Apakah PowerShell mendukung konstanta?

118

Saya ingin mendeklarasikan beberapa konstanta integer di PowerShell.

Apakah ada cara yang baik untuk melakukan itu?

Tom Hazel
sumber

Jawaban:

121

Menggunakan

Set-Variable test -option Constant -value 100

atau

Set-Variable test -option ReadOnly -value 100

Perbedaan antara "Constant" dan "ReadOnly" adalah variabel hanya-baca dapat dihapus (dan kemudian dibuat kembali) melalui

Remove-Variable test -Force

sedangkan variabel konstan tidak dapat dihapus (bahkan dengan -Force).

Lihat artikel TechNet ini untuk lebih jelasnya.

Motti Strom
sumber
4
Hmm, tapi bagaimana Anda memaksa tipe data saat menggunakan Set-Variable? Ketika berurusan dengan variabel, seseorang dapat menggunakan [string]$name = valuetetapi tampaknya tidak mungkin untuk konstanta?
masi
8
@masi hanya memaksakan nilainyaSet-Variable test -option Constant -value [string]100
Monso
7
@Monso Anda membutuhkan tanda kurung di sekitar nilai saat menentukan tipe seperti ([string]100). Lihat jawaban di bawah.
Polimorfik
15

Berikut adalah solusi untuk mendefinisikan konstanta seperti ini:

const myConst = 42

Solusi diambil dari 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
rampok
sumber
1
Sayangnya ini tidak berfungsi ketika Set-Constantada di dalam modul. Ini akan membuat konstanta dalam ruang lingkup modul, di mana Set-Constantterkandung. Sebagai solusinya, seseorang dapat mengirimkan parameter -Surround Global, tetapi itu tidak selalu diinginkan. Saya ingin membuat konstanta di modul lain atau secara lokal dalam suatu fungsi.
zett42
11

Gunakan -option Constantdengan Set-Variablecmdlet:

Set-Variable myvar -option Constant -value 100

Sekarang $myvarmemiliki nilai konstan 100 dan tidak dapat dimodifikasi.

Paolo Tedesco
sumber
1
Wow, itu kikuk. Anda harus menggunakan Set-Variable untuk melakukannya, ya?
Tom Hazel
Ya, tidak ada cara yang tidak biasa untuk melakukannya :)
Paolo Tedesco
1
Anda juga dapat memodifikasi dan variabel yang ada dengan baik set-variabel (alias sv) atau dengan menggunakan get-variable (gv) dan mengutak-atik properti Opsi.
x0n
Hmm, tapi bagaimana Anda memaksa tipe data saat menggunakan Set-Variable? Ketika berurusan dengan variabel, seseorang dapat menggunakan [string]$name = valuetetapi tampaknya tidak mungkin untuk konstanta?
masi
@masi - lihat jawaban Mike Shepard di tempat lain di halaman ini. Salin dan tempel dari sana, ini:set-variable -name test -value ([int64]100) -option Constant
Chris J
11

Untuk menggunakan jenis nilai tertentu, katakanlah Int64, Anda dapat secara eksplisit mentransmisikan nilai yang digunakan dalam variabel set.

Misalnya:

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

Untuk memeriksa,

$test | gm

Dan Anda akan melihat bahwa itu adalah Int64 (bukan Int32, yang akan menjadi normal untuk nilai 100).

Mike Shepard
sumber
5

Saya sangat suka gula sintaksis yang diberikan oleh jawaban rob :

const myConst = 42

Sayangnya solusinya tidak berfungsi seperti yang diharapkan saat Anda mendefinisikan Set-Constantfungsi dalam modul . Ketika dipanggil dari luar modul, itu akan membuat konstanta dalam lingkup modul, di mana Set-Constantditentukan, bukan lingkup pemanggil . Ini membuat konstanta tidak terlihat oleh pemanggil.

Fungsi modifikasi berikut memperbaiki masalah ini. Solusinya didasarkan pada jawaban atas pertanyaan "Apakah ada cara bagi modul PowerShell untuk menjangkau cakupan pemanggilnya?" .

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

Catatan:

  • Fungsi ini hanya berfungsi, jika dipanggil dari luar modul, di tempat yang ditentukan. Ini adalah kasus penggunaan yang dimaksudkan, tetapi saya ingin menambahkan tanda centang, apakah itu dipanggil dari modul yang sama (dalam hal ini Set-Variable -scope 1seharusnya berfungsi), ketika saya telah menemukan cara melakukannya.
  • Saya telah mengganti nama parameter -Meanmenjadi -Value, untuk konsistensi dengan Set-Variable.
  • Fungsi ini dapat diperpanjang untuk menyetel tanda Private, ReadOnlydan secara opsional AllScope. Cukup tambahkan nilai yang diinginkan ke argumen ke-3 dari PSVariablekonstruktor , yang dipanggil dalam skrip di atas melalui New-Object.
zett42
sumber
-4

PowerShell v5.0 seharusnya mengizinkan

[statis] [int] $ variabel = 42

[Statis] [DateTime] $ thisday

dan sejenisnya.

MarkH
sumber
2
tidak bekerja pada ps 5.1. Tidak dapat menemukan jenis [statis].
ThomasMX
5
Belum lagi, statis tidak sama dengan konstanta
Kolob Canyon