Поддерживает ли PowerShell константы?


118

Я хотел бы объявить некоторые целочисленные константы в PowerShell.

Есть ли хороший способ сделать это?

Ответы:


121

использование

Set-Variable test -option Constant -value 100

или

Set-Variable test -option ReadOnly -value 100

Разница между "Constant" и "ReadOnly" в том, что переменную только для чтения можно удалить (а затем воссоздать) с помощью

Remove-Variable test -Force

тогда как постоянная переменная не может быть удалена (даже с -Force).

См. Эту статью TechNet для получения дополнительных сведений.


4
Хм, а как заставить тип данных при использовании Set-Variable? При работе с переменными можно использовать, [string]$name = valueно, похоже, это невозможно для констант?
Masi

8
@masi просто форсирует значениеSet-Variable test -option Constant -value [string]100
Monso

7
@Monso Вам нужны круглые скобки вокруг значения при указании типа, например ([string]100). См. Ответы ниже.
Polymorphix

15

Вот решение для определения такой константы:

const myConst = 42

Решение взято из 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
К сожалению, это не работает, когда Set-Constantон содержится в модуле. Он создаст константу в области видимости модуля, где Set-Constantсодержится. В качестве обходного пути можно передать параметр -Surround Global, но это не всегда нужно. Я хочу создать константу в другом модуле или локально в функции.
zett42

11

Используйте -option Constantс Set-Variableкомандлетом:

Set-Variable myvar -option Constant -value 100

Теперь $myvarимеет постоянное значение 100 и не может быть изменено.


1
Вау, это неуклюже. Вы должны использовать Set-Variable для этого, а?
Том Хейзел

Да, неуклюжий способ сделать это :)
Паоло Тедеско,

1
вы также можете изменить существующую переменную либо с помощью set-variable (с псевдонимом sv), либо с помощью get-variable (gv) и поработать со свойством Options.
x0n

Хм, а как заставить тип данных при использовании Set-Variable? При работе с переменными можно использовать, [string]$name = valueно, похоже, это невозможно для констант?
Masi

@masi - см. ответ Майка Шепарда в другом месте на этой странице. Скопируйте и вставьте оттуда:set-variable -name test -value ([int64]100) -option Constant
Крис Дж

11

Чтобы использовать определенный тип значения, скажем Int64, вы можете явно привести значение, используемое в set-variable.

Например:

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

Проверять,

$test | gm

И вы увидите, что это Int64 (а не Int32, что было бы нормально для значения 100).


5

Мне очень нравится синтаксический сахар, который дает ответ Роба:

const myConst = 42

К сожалению, его решение работает не так, как ожидалось, когда вы определяете Set-Constantфункцию в модуле . При вызове извне модуля он создает константу в области видимости модуля, где Set-Constantопределено, вместо области действия вызывающего . Это делает константу невидимой для вызывающей стороны.

Следующая модифицированная функция устраняет эту проблему. Решение основано на этом ответе на вопрос «Есть ли способ для модуля PowerShell попасть в область действия вызывающего объекта?» ,

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

Ноты:

  • Функция работает только при вызове извне модуля, в котором она определена. Это предполагаемый вариант использования, но я хотел бы добавить проверку, вызывается ли он из того же модуля (в этом случаеSet-Variable -scope 1 должен работать), когда я узнаю, как это сделать.
  • Я переименовал этот параметр -Meanв -Value, для согласования сSet-Variable .
  • Функцию можно расширить, чтобы дополнительно установить флаги Private, ReadOnlyи AllScope. Просто добавьте желаемые значения к третьему аргументу PSVariableконструктора , который вызывается в приведенном выше скрипте через New-Object.

-4

PowerShell v5.0 должен позволять

[static] [int] $ variable = 42

[статические] [DateTime] $ thisday

и тому подобное.


2
не работает на пс 5.1. Не удалось найти тип [статический].
ThomasMX 02

5
Не говоря уже о том, что статика - это не то же самое, что константа
Каньон Колоб
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.