Нарушение цикломатической сложности: функция должна иметь сложность 10 или меньше: в настоящее время сложность равна 13 (cyclomatic_complexity)

У меня есть следующий код в swift3, и я использую swift lint для кодирования кода. Код дается следующим образом:

    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
    }
  }

Swiftlint генерирует предупреждение, известное как цикломатическая сложность. Почему возникает это предупреждение и как его решить?

введите описание изображения здесь

4 ответа

Решение

Предупреждение возникает из-за того, что ваша функция слишком сложна, как определено метрикой, которая, по сути, подсчитывает количество решений, которые необходимо принять.

Простой способ избежать этого в данном конкретном случае был бы с помощью простой математики:

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

Метод слишком сложный. Но вместо того, чтобы переписать код, вы можете исключить switch от cyclomatic_complexity расчет, так как они отлично читаются, как это:

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) {

Если вы не хотите менять логику, следуйте ниже. Добавьте свойство "cyclomatic_complexity:" и установите значение предупреждения в файле.swiftlint.yml.

cyclomatic_complexity: предупреждение: 25

Примечание. Здесь настройка значения предупреждения означает увеличение количества линейно независимых путей. Вы можете установить свои собственные значения.

Вы можете уменьшить свою сложность, устраняя повторяющиеся 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)
    }
  }
Другие вопросы по тегам