【问题标题】:Powershell, OOP, Why return $false does not exit Class MethodPowershell,OOP,为什么返回 $false 不退出类方法
【发布时间】:2022-01-12 09:10:12
【问题描述】:

在 Powershell 5 中

不明白,在调试这段代码的时候,为什么当匹配到主字符串末尾的字符串“of”时,方法不执行退出Class Method,继续迭代。

对我来说似乎违反直觉。

我必须使用辅助变量和结合break命令的标签吗?

类似这里:

:JUMPASFOX foreach ($i in (1..10)) {
...{break JUMPASFOX}

我认为 return $false 任何地方都会导致退出。 我无法协调我的代码不起作用。

Class EndFinder {
    [string[]]$Exclusions_End_Text=@(" of", " of the", " of a", "for a", "for the", " in", " the")
    EndFinder(){}

    [boolean]Contains_Exclusion_At_The_End ([string]$ClipText) {
       #$found=$false
       $this.Exclusions_End_Text |foreach { 
            $exclusion_length=$_.Length
            $clip_length=$ClipText.Length
            if ($exclusion_length -lt $clip_length) {
               $tailing=$ClipText.Substring($clip_length-$exclusion_length,$exclusion_length)
               if ($tailing -eq $_) {
                    #$found=$true
                    return $true
               }
            }
       }
       return $false
       #return $found
    }
}

$kb=[EndFinder]::New()
$kb.Contains_Exclusion_At_The_End("big problem of the")

【问题讨论】:

  • 发生这种情况是因为您使用 ... |foreach {}(解析为 ... |ForEach-Object {})而不是真正的循环 - return 将控制从脚本块返回给 ForEach-Object 命令,然后调用下一次迭代,忘记了你所期待的“直觉”行为。

标签: powershell


【解决方案1】:

正如Mathias R. Jessen 在他的评论中指出的那样,return 关键字在 ForEach-Object 等 cmdlet 的范围内使用时将进入下一次迭代,类似于 continue 如果它是循环(forforeachwhile 等)。

  • 满足条件时进入下一次迭代:
0..4 | ForEach-Object {
    if($_ % 2) {
        return 'Odd'
    }
    'Even'
}

Even
Odd
Even
Odd
Even

# Same behavior with script block:

0..4 | & {
    process
    {
        if($_ % 2) {
            return 'Odd'
        }
        'Even'
    }
}
  • 停止迭代:
foreach($i in 0..4) {
    if($i % 2) {
        return 'Odd'
    }
    'Even'
}

Even
Odd

我假设您正在尝试查看提供给您的方法的字符串是否您的类属性中的任何$Exclusions_End_Text 字符串结尾。如果是这样的话,应该这样做:

Class EndFinder {
    hidden [string[]]$Exclusions_End_Text = @(
        " of", " of the", " of a", "for a", "for the", " in", " the"
    )

    # EndFinder(){} => Constructor is not needed here, PS does this by default.

    [boolean] Contains_Exclusion_At_The_End ([string]$ClipText)
    {
        foreach($i in $this.Exclusions_End_Text)
        {
            if($ClipText.EndsWith($i))
            {
                return $true
            }
        }
        return $false
    }
}

$kb = [EndFinder]::New()
$kb.Contains_Exclusion_At_The_End('big problem of the') # => True
$kb.Contains_Exclusion_At_The_End('not ending with any $Exclusions_End_Text') # => False

在这种情况下,我个人会使用static 方法,我相信它更适合您要完成的工作:

Class EndFinder {
    static [boolean] Contains_Exclusion_At_The_End ([string]$ClipText)
    {
        $Exclusions_End_Text = @(
            " of", " of the", " of a", "for a", "for the", " in", " the"
        )

        foreach($i in $Exclusions_End_Text)
        {
            if($ClipText.EndsWith($i))
            {
                return $true
            }
        }
        return $false
    }
}

[EndFinder]::Contains_Exclusion_At_The_End('big problem of the')
[EndFinder]::Contains_Exclusion_At_The_End('not ending with any $Exclusions_End_Text')

【讨论】:

  • 哇,EndsWith 我什至没有意识到它的存在。谢谢
  • @John 很乐意提供帮助。如果它有用并解决了您的疑问,请考虑接受答案
猜你喜欢
  • 2019-08-14
  • 2017-12-09
  • 1970-01-01
  • 2016-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-27
  • 1970-01-01
相关资源
最近更新 更多