22

I have the following code in swift3 and i am using swift lint for linting the code. The code is given as follows:

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

The swift lint generates a "Cyclomatic Complexity Violation" warning. Why did this warning occur and how does one resolve it?

enter image description here

4

5 回答 5

48

The method is too complex. But instead of rewriting the code, you could exclude switches from the cyclomatic_complexity calculation (since they are perfectly readable) like this:

cyclomatic_complexity:
  ignores_case_statements: true
于 2018-07-07T09:56:23.307 回答
22

The warning occurs because your function is too complex as defined by the metric which essentially counts the number of decisions that need to be made.

A simple way to avoid it in this particular case would be with some simple math:

func selectedMenuInLoggedOutState(sender: UIButton) {
    guard let menu = LeftGuestMenu(rawValue: sender.tag - 1) else { return }
    self.changeGuestViewController(menu)
}
于 2017-08-25T23:48:12.230 回答
13

You can disable swiftlint warnings in code like this:

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

or, if you want to explicitly just disable the next swiftlint warning:

// swiftlint:disable:next cyclomatic_complexity
func selectedMenuInLoggedOutState(sender: UIButton) {
于 2019-05-01T09:48:11.297 回答
2

You can reduce your complexity by eliminating the repeated if let statements:

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)
    }
  }
于 2017-08-25T23:55:31.580 回答
2

In case if you don't want to change your logic, follow below. Add "cyclomatic_complexity:" property and set warning value in .swiftlint.yml file.

cyclomatic_complexity: warning: 25

Note: Here setting warning value means, increasing the number of linearly independent paths. You can set your own value.

于 2017-09-01T10:58:25.670 回答