考虑一下:
SWITCH ($mode)
{
MODE1
{
}
MODE2
{
}
MODE3
{
}
}
我可以直接调用 MODE1、MODE2 或 MODE3 下的代码而不执行整个 SWITCH 语句吗?
我遇到的情况是,MODE3 只能在 MODE2 完成时运行,而 MODE2 只能在 MODE1 完成时运行。我已将每个 MODE 的所有代码移动到一个单独的函数中。但是,用于确定以前的模式是否已完成的逻辑正在增加大小、重复代码并且令人困惑。
例如:
SWITCH ($mode)
{
MODE1
{
DoMode1
if (!Mode1Complete) { Exit }
}
MODE2
{
if (!Mode1Complete) { DoMode1 }
if (!Mode1Complete) { Exit }
DoMode2
}
MODE3
{
if (!Mode2Complete)
{
if (!Mode1Complete)
{
DoMode1
if (!Mode1Complete) { Exit }
DoMode2
if (!Mode2Complete) { Exit }
}
else
{
DoMode2
if (!Mode2Complete) { Exit }
}
}
DoMode3
}
}
你可以看到这将如何变得复杂!
我想做的是:
SWITCH ($mode)
{
MODE1
{
DoMode1
If (!Mode1Complete) { Exit }
}
MODE2
{
if (!Mode1Complete)
{
#Call MODE1
}
if (!Mode1Complete) { Exit }
DoMode2
}
MODE3
{
if (!Mode2Complete)
{
#Call MODE2
}
if (!Mode2Complete) { Exit }
DoMode3
}
}
请注意,"MODEx"只是一个示例。实际情况不会像这样按数字顺序排列。它们将是不同的词。
任何想法如何实现这一目标?
使用 GetNewClosure 将状态存储在脚本块中。如果代码需要脚本块中的外部变量,请考虑将它们作为参数传递给相应的脚本块。
例:
# Setup scriptblocks for switch statement and dependencies.
# Use 'GetNewClosure' to capture variables (e.g.: $ModeComplete)
$Alpha = {
if (!$ModeComplete) {
'Alpha'
$ModeComplete = $true
}
}.GetNewClosure()
$Beta = {
. $Alpha
if (!$ModeComplete) {
'Beta'
$ModeComplete = $true
}
}.GetNewClosure()
$Gamma = {
. $Beta
if (!$ModeComplete) {
'Gamma'
$ModeComplete = $true
}
}.GetNewClosure()
# Helper scriptblock, will execute scriptblock
# from varible named as current switch condition
$ExecuteCurrentMode = {
. (Get-Variable -Name $_ -ValueOnly)
}
# Mode
$Mode = 'Gamma'
# Switch
switch ($Mode) {
'Alpha' {
. $ExecuteCurrentMode $_
}
'Beta' {
. $ExecuteCurrentMode $_
}
'Gamma' {
. $ExecuteCurrentMode $_
}
}
结果
Alpha
Beta
Gamma