循环复杂度违规:函数的复杂度应为 10 或更小:当前复杂度等于 13 (cyclomatic_complexity)

Cyclomatic Complexity Violation: Function should have complexity 10 or less: currently complexity equals 13 (cyclomatic_complexity)

我在 swift3 中有以下代码,我正在使用 swift lint 对代码进行 linting。给出代码如下:

    func selectedMenuInLoggedOutState(sender: UIButton) {
    switch sender.tag {
    case 1:
      if let menu = LeftGuestMenu(rawValue: 0) {
        self.changeGuestViewController(menu)
      }
    case 2:
      if let menu = LeftGuestMenu(rawValue: 1) {
        self.changeGuestViewController(menu)
      }
    case 3:
      if let menu = LeftGuestMenu(rawValue: 2) {
        self.changeGuestViewController(menu)
      }
    case 4:
      if let menu = LeftGuestMenu(rawValue: 3) {
        self.changeGuestViewController(menu)
      }
    case 5:
      if let menu = LeftGuestMenu(rawValue: 4) {
        self.changeGuestViewController(menu)
      }
    case 6:
      if let menu = LeftGuestMenu(rawValue: 5) {
        self.changeGuestViewController(menu)
      }
    default:
      break
    }
  }

swift lint 生成 "Cyclomatic Complexity Violation" 警告。为什么会出现此警告,如何解决?

出现警告是因为您的函数过于复杂,正如 metric 所定义的那样,它本质上计算了需要做出的决定的数量。

在这种特殊情况下避免它的一个简单方法是使用一些简单的数学:

func selectedMenuInLoggedOutState(sender: UIButton) {
    guard let menu = LeftGuestMenu(rawValue: sender.tag - 1) else { return }
    self.changeGuestViewController(menu)
}

您可以通过消除重复的 if let 语句来降低复杂性:

func selectedMenuInLoggedOutState(sender: UIButton) {

    let menu: MenuType?

    switch sender.tag {
    case 1:
     menu = LeftGuestMenu(rawValue: 0)
    case 2:
     menu = LeftGuestMenu(rawValue: 1) 
    case 3:
     menu = LeftGuestMenu(rawValue: 2) 
    case 4:
      menu = LeftGuestMenu(rawValue: 3) 
    case 5:
      menu = LeftGuestMenu(rawValue: 4)   
    case 6:
      menu = LeftGuestMenu(rawValue: 5) 
    default:
      menu=nil
    }

    if let menu = menu {
       self.changeGuestViewController(menu)
    }
  }

如果您不想更改您的逻辑,请按照以下操作。 添加 "cyclomatic_complexity:" 属性 并在 .swiftlint.yml 文件中设置警告值。

cyclomatic_complexity: 警告:25

注意:这里设置警告值的意思是,增加线性独立路径的数量。您可以设置自己的值。

方法太复杂。但不是重写代码,您可以从 cyclomatic_complexity 计算中排除 switches (因为它们完全可读),如下所示:

cyclomatic_complexity:
  ignores_case_statements: true

您可以在如下代码中禁用 swiftlint 警告:

// swiftlint:disable cyclomatic_complexity
func selectedMenuInLoggedOutState(sender: UIButton) {
    ...
}
// swiftlint:enable cyclomatic_complexity

或者,如果您想明确禁用下一个 swiftlint 警告:

// swiftlint:disable:next cyclomatic_complexity
func selectedMenuInLoggedOutState(sender: UIButton) {