Multiline Arguments

标识符 默认开启 支持自动更正 类别 分析仪 最低swift编译版本
multiline_arguments style 3.0.0

实参需要写在同一行或者每个一行。

示例

非触发

  1. foo()
  2. foo(
  3. )
  4. foo { }
  5. foo {
  6. }
  7. foo(0)
  8. foo(0, 1)
  9. foo(0, 1) { }
  10. foo(0, param1: 1)
  11. foo(0, param1: 1) { }
  12. foo(param1: 1)
  13. foo(param1: 1) { }
  14. foo(param1: 1, param2: true) { }
  15. foo(param1: 1, param2: true, param3: [3]) { }
  16. foo(param1: 1, param2: true, param3: [3]) {
  17. bar()
  18. }
  19. foo(param1: 1,
  20. param2: true,
  21. param3: [3])
  22. foo(
  23. param1: 1, param2: true, param3: [3]
  24. )
  25. foo(
  26. param1: 1,
  27. param2: true,
  28. param3: [3]
  29. )

触发

  1. foo(0,
  2. param1: 1, param2: true, param3: [3])
  3. foo(0, param1: 1,
  4. param2: true, param3: [3])
  5. foo(0, param1: 1, param2: true,
  6. param3: [3])
  7. foo(
  8. 0, param1: 1,
  9. param2: true, param3: [3]
  10. )

补充

简单讲 arguments指实参 parameters指形参
parameters和arguments的区别


Mutiline Function Chains

标识符 默认开启 支持自动更正 类别 分析仪 最低swift编译版本
multiline_function_chains style 3.0.0

链式调用需要写在同一行或者每个一行。

示例

非触发

  1. let evenSquaresSum = [20, 17, 35, 4].filter { $0 % 2 == 0 }.map { $0 * $0 }.reduce(0, +)
  2. let evenSquaresSum = [20, 17, 35, 4]
  3. .filter { $0 % 2 == 0 }.map { $0 * $0 }.reduce(0, +)",
  4. let chain = a
  5. .b(1, 2, 3)
  6. .c { blah in
  7. print(blah)
  8. }
  9. .d()
  10. let chain = a.b(1, 2, 3)
  11. .c { blah in
  12. print(blah)
  13. }
  14. .d()
  15. let chain = a.b(1, 2, 3)
  16. .c { blah in print(blah) }
  17. .d()
  18. let chain = a.b(1, 2, 3)
  19. .c(.init(
  20. a: 1,
  21. b, 2,
  22. c, 3))
  23. .d()
  24. self.viewModel.outputs.postContextualNotification
  25. .observeForUI()
  26. .observeValues {
  27. NotificationCenter.default.post(
  28. Notification(
  29. name: .ksr_showNotificationsDialog,
  30. userInfo: [UserInfoKeys.context: PushNotificationDialog.Context.pledge,
  31. UserInfoKeys.viewController: self]
  32. )
  33. )
  34. }
  35. let remainingIDs = Array(Set(self.currentIDs).subtracting(Set(response.ids)))
  36. self.happeningNewsletterOn = self.updateCurrentUser
  37. .map { $0.newsletters.happening }.skipNil().skipRepeats()

触发

  1. let evenSquaresSum = [20, 17, 35, 4]
  2. .filter { $0 % 2 == 0 }↓.map { $0 * $0 }
  3. .reduce(0, +)
  4. let evenSquaresSum = a.b(1, 2, 3)
  5. .c { blah in
  6. print(blah)
  7. }↓.d()
  8. let evenSquaresSum = a.b(1, 2, 3)
  9. .c(2, 3, 4)↓.d()
  10. let evenSquaresSum = a.b(1, 2, 3)↓.c { blah in
  11. print(blah)
  12. }
  13. .d()
  14. a.b {
  15. // ““
  16. }↓.e()

Multiline Parameters

标识符 默认开启 支持自动更正 类别 分析仪 最低swift编译版本
multiline_parameters style 3.0.0

形参需要写在同一行或者每个一行。

示例

非触发

  1. func foo() { }
  2. func foo(param1: Int) { }
  3. func foo(param1: Int, param2: Bool) { }
  4. func foo(param1: Int, param2: Bool, param3: [String]) { }
  5. func foo(param1: Int,
  6. param2: Bool,
  7. param3: [String]) { }
  8. func foo(_ param1: Int, param2: Int, param3: Int) -> (Int) -> Int {
  9. return { x in x + param1 + param2 + param3 }
  10. }
  11. static func foo() { }
  12. static func foo(param1: Int) { }
  13. static func foo(param1: Int, param2: Bool) { }
  14. static func foo(param1: Int, param2: Bool, param3: [String]) { }
  15. static func foo(param1: Int,
  16. param2: Bool,
  17. param3: [String]) { }
  18. protocol Foo {
  19. func foo() { }
  20. }
  21. protocol Foo {
  22. func foo(param1: Int) { }
  23. }
  24. protocol Foo {
  25. func foo(param1: Int, param2: Bool) { }
  26. }
  27. protocol Foo {
  28. func foo(param1: Int, param2: Bool, param3: [String]) { }
  29. }
  30. protocol Foo {
  31. func foo(param1: Int,
  32. param2: Bool,
  33. param3: [String]) { }
  34. }
  35. protocol Foo {
  36. static func foo(param1: Int, param2: Bool, param3: [String]) { }
  37. }
  38. protocol Foo {
  39. static func foo(param1: Int,
  40. param2: Bool,
  41. param3: [String]) { }
  42. }
  43. protocol Foo {
  44. class func foo(param1: Int, param2: Bool, param3: [String]) { }
  45. }
  46. protocol Foo {
  47. class func foo(param1: Int,
  48. param2: Bool,
  49. param3: [String]) { }
  50. }
  51. enum Foo {
  52. func foo() { }
  53. }
  54. enum Foo {
  55. func foo(param1: Int) { }
  56. }
  57. enum Foo {
  58. func foo(param1: Int, param2: Bool) { }
  59. }
  60. enum Foo {
  61. func foo(param1: Int, param2: Bool, param3: [String]) { }
  62. }
  63. enum Foo {
  64. func foo(param1: Int,
  65. param2: Bool,
  66. param3: [String]) { }
  67. }
  68. enum Foo {
  69. static func foo(param1: Int, param2: Bool, param3: [String]) { }
  70. }
  71. enum Foo {
  72. static func foo(param1: Int,
  73. param2: Bool,
  74. param3: [String]) { }
  75. }
  76. struct Foo {
  77. func foo() { }
  78. }
  79. struct Foo {
  80. func foo(param1: Int) { }
  81. }
  82. struct Foo {
  83. func foo(param1: Int, param2: Bool) { }
  84. }
  85. struct Foo {
  86. func foo(param1: Int, param2: Bool, param3: [String]) { }
  87. }
  88. struct Foo {
  89. func foo(param1: Int,
  90. param2: Bool,
  91. param3: [String]) { }
  92. }
  93. struct Foo {
  94. static func foo(param1: Int, param2: Bool, param3: [String]) { }
  95. }
  96. struct Foo {
  97. static func foo(param1: Int,
  98. param2: Bool,
  99. param3: [String]) { }
  100. }
  101. class Foo {
  102. func foo() { }
  103. }
  104. class Foo {
  105. func foo(param1: Int) { }
  106. }
  107. class Foo {
  108. func foo(param1: Int, param2: Bool) { }
  109. }
  110. class Foo {
  111. func foo(param1: Int, param2: Bool, param3: [String]) { }
  112. }
  113. class Foo {
  114. func foo(param1: Int,
  115. param2: Bool,
  116. param3: [String]) { }
  117. }
  118. class Foo {
  119. class func foo(param1: Int, param2: Bool, param3: [String]) { }
  120. }
  121. class Foo {
  122. class func foo(param1: Int,
  123. param2: Bool,
  124. param3: [String]) { }
  125. }
  126. class Foo {
  127. class func foo(param1: Int,
  128. param2: Bool,
  129. param3: @escaping (Int, Int) -> Void = { _, _ in }) { }
  130. }
  131. class Foo {
  132. class func foo(param1: Int,
  133. param2: Bool,
  134. param3: @escaping (Int) -> Void = { _ in }) { }
  135. }
  136. class Foo {
  137. class func foo(param1: Int,
  138. param2: Bool,
  139. param3: @escaping ((Int) -> Void)? = nil) { }
  140. }
  141. class Foo {
  142. class func foo(param1: Int,
  143. param2: Bool,
  144. param3: @escaping ((Int) -> Void)? = { _ in }) { }
  145. }
  146. class Foo {
  147. class func foo(param1: Int,
  148. param2: @escaping ((Int) -> Void)? = { _ in },
  149. param3: Bool) { }
  150. }
  151. class Foo {
  152. class func foo(param1: Int,
  153. param2: @escaping ((Int) -> Void)? = { _ in },
  154. param3: @escaping (Int, Int) -> Void = { _, _ in }) { }
  155. }
  156. class Foo {
  157. class func foo(param1: Int,
  158. param2: Bool,
  159. param3: @escaping (Int) -> Void = { (x: Int) in }) { }
  160. }
  161. class Foo {
  162. class func foo(param1: Int,
  163. param2: Bool,
  164. param3: @escaping (Int, (Int) -> Void) -> Void = { (x: Int, f: (Int) -> Void) in }) { }
  165. }

触发

  1. func foo(_ param1: Int,
  2. param2: Int, param3: Int) -> (Int) -> Int {
  3. return { x in x + param1 + param2 + param3 }
  4. }
  5. protocol Foo {
  6. func foo(param1: Int,
  7. param2: Bool, param3: [String]) { }
  8. }
  9. protocol Foo {
  10. func foo(param1: Int, param2: Bool,
  11. param3: [String]) { }
  12. }
  13. protocol Foo {
  14. static func foo(param1: Int,
  15. param2: Bool, param3: [String]) { }
  16. }
  17. protocol Foo {
  18. static func foo(param1: Int, param2: Bool,
  19. param3: [String]) { }
  20. }
  21. protocol Foo {
  22. class func foo(param1: Int,
  23. param2: Bool, param3: [String]) { }
  24. }
  25. protocol Foo {
  26. class func foo(param1: Int, param2: Bool,
  27. param3: [String]) { }
  28. }
  29. enum Foo {
  30. func foo(param1: Int,
  31. param2: Bool, param3: [String]) { }
  32. }
  33. enum Foo {
  34. func foo(param1: Int, param2: Bool,
  35. param3: [String]) { }
  36. }
  37. enum Foo {
  38. static func foo(param1: Int,
  39. param2: Bool, param3: [String]) { }
  40. }
  41. enum Foo {
  42. static func foo(param1: Int, param2: Bool,
  43. param3: [String]) { }
  44. }
  45. struct Foo {
  46. func foo(param1: Int,
  47. param2: Bool, param3: [String]) { }
  48. }
  49. struct Foo {
  50. func foo(param1: Int, param2: Bool,
  51. param3: [String]) { }
  52. }
  53. struct Foo {
  54. static func foo(param1: Int,
  55. param2: Bool, param3: [String]) { }
  56. }
  57. struct Foo {
  58. static func foo(param1: Int, param2: Bool,
  59. param3: [String]) { }
  60. }
  61. class Foo {
  62. func foo(param1: Int,
  63. param2: Bool, param3: [String]) { }
  64. }
  65. class Foo {
  66. func foo(param1: Int, param2: Bool,
  67. param3: [String]) { }
  68. }
  69. class Foo {
  70. class func foo(param1: Int,
  71. param2: Bool, param3: [String]) { }
  72. }
  73. class Foo {
  74. class func foo(param1: Int, param2: Bool,
  75. param3: [String]) { }
  76. }
  77. class Foo {
  78. class func foo(param1: Int,
  79. param2: Bool, param3: @escaping (Int, Int) -> Void = { _, _ in }) { }
  80. }
  81. class Foo {
  82. class func foo(param1: Int,
  83. param2: Bool, param3: @escaping (Int) -> Void = { (x: Int) in }) { }
  84. }

Multiple Closures with Trailing Closure

标识符 默认开启 支持自动更正 类别 分析仪 最低swift编译版本
multiple_closures_with_trailing_closure style 3.0.0

有多个闭包作为参数的时候,不应该使用尾随闭包语法。

示例

非触发

  1. foo.map { $0 + 1 }
  2. foo.reduce(0) { $0 + $1 }
  3. if let foo = bar.map({ $0 + 1 }) {
  4. }
  5. foo.something(param1: { $0 }, param2: { $0 + 1 })
  6. UIView.animate(withDuration: 1.0) {
  7. someView.alpha = 0.0
  8. }

触发

  1. foo.something(param1: { $0 }) ↓{ $0 + 1 }
  2. UIView.animate(withDuration: 1.0, animations: {
  3. someView.alpha = 0.0
  4. }) ↓{ _ in
  5. someView.removeFromSuperview()
  6. }

补充

闭包
Swift闭包简单应用


Nesting

标识符 默认开启 支持自动更正 类别 分析仪 最低swift编译版本
nesting metrics 3.0.0

类型嵌套最多一级,语句嵌套最多五级。

示例

非触发

  1. class Class0 { class Class1 {} }
  2. func func0() {
  3. func func1() {
  4. func func2() {
  5. func func3() {
  6. func func4() { func func5() {
  7. }
  8. }
  9. }
  10. }
  11. }
  12. }
  13. struct Class0 { struct Class1 {} }
  14. func func0() {
  15. func func1() {
  16. func func2() {
  17. func func3() {
  18. func func4() { func func5() {
  19. }
  20. }
  21. }
  22. }
  23. }
  24. }
  25. enum Class0 { enum Class1 {} }
  26. func func0() {
  27. func func1() {
  28. func func2() {
  29. func func3() {
  30. func func4() { func func5() {
  31. }
  32. }
  33. }
  34. }
  35. }
  36. }
  37. enum Enum0 { enum Enum1 { case Case } }

触发

  1. class A { class B { class C {} } }
  2. struct A { struct B { struct C {} } }
  3. func func0() {
  4. func func1() {
  5. func func2() {
  6. func func3() {
  7. func func4() { func func5() {
  8. func func6() {
  9. }
  10. }
  11. }
  12. }
  13. }
  14. }
  15. }

Nimble Operator

标识符 默认开启 支持自动更正 类别 分析仪 最低swift编译版本
nimble_operator idiomatic 3.0.0

优先使用Nimble运算符而不是匹配函数

示例

非触发

  1. expect(seagull.squawk) != "Hi!"
  2. expect("Hi!") == "Hi!"
  3. expect(10) > 2
  4. expect(10) >= 10
  5. expect(10) < 11
  6. expect(10) <= 10
  7. expect(x) === x
  8. expect(10) == 10
  9. expect(object.asyncFunction()).toEventually(equal(1))
  10. expect(actual).to(haveCount(expected))

触发

  1. expect(seagull.squawk).toNot(equal("Hi"))
  2. expect(12).toNot(equal(10))
  3. expect(10).to(equal(10))
  4. expect(10).to(beGreaterThan(8))
  5. expect(10).to(beGreaterThanOrEqualTo(10))
  6. expect(10).to(beLessThan(11))
  7. expect(10).to(beLessThanOrEqualTo(10))
  8. expect(x).to(beIdenticalTo(x))
  9. expect(10) > 2
  10. expect(10).to(beGreaterThan(2))

补充

Swift 进阶开发指南:如何使用 Quick、Nimble 执行测试驱动开发(TDD)


No Extension Access Modifier

标识符 默认开启 支持自动更正 类别 分析仪 最低swift编译版本
no_extension_access_modifier idiomatic 3.0.0

不要对Extension使用权限控制符

示例

非触发

  1. extension String {}
  2. extension String {}

触发

  1. private extension String {}
  2. public
  3. extension String {}
  4. open extension String {}
  5. internal extension String {}
  6. fileprivate extension String {}

No Fallthrough Only

标识符 默认开启 支持自动更正 类别 分析仪 最低swift编译版本
no_fallthrough_only idiomatic 3.0.0

使用fallthroughcase语句至少要包含一句其他的语句

示例

非触发

  1. switch myvar {
  2. case 1:
  3. var a = 1
  4. fallthrough
  5. case 2:
  6. var a = 2
  7. }
  8. switch myvar {
  9. case "a":
  10. var one = 1
  11. var two = 2
  12. fallthrough
  13. case "b": /* comment */
  14. var three = 3
  15. }
  16. switch myvar {
  17. case 1:
  18. let one = 1
  19. case 2:
  20. // comment
  21. var two = 2
  22. }
  23. switch myvar {
  24. case MyFunc(x: [1, 2, YourFunc(a: 23)], y: 2):
  25. var three = 3
  26. fallthrough
  27. default:
  28. var three = 4
  29. }
  30. switch myvar {
  31. case .alpha:
  32. var one = 1
  33. case .beta:
  34. var three = 3
  35. fallthrough
  36. default:
  37. var four = 4
  38. }
  39. let aPoint = (1, -1)
  40. switch aPoint {
  41. case let (x, y) where x == y:
  42. let A = "A"
  43. case let (x, y) where x == -y:
  44. let B = "B"
  45. fallthrough
  46. default:
  47. let C = "C"
  48. }
  49. switch myvar {
  50. case MyFun(with: { $1 }):
  51. let one = 1
  52. fallthrough
  53. case "abc":
  54. let two = 2
  55. }

触发

  1. switch myvar {
  2. case 1:
  3. fallthrough
  4. case 2:
  5. var a = 1
  6. }
  7. switch myvar {
  8. case 1:
  9. var a = 2
  10. case 2:
  11. fallthrough
  12. case 3:
  13. var a = 3
  14. }
  15. switch myvar {
  16. case 1: // comment
  17. fallthrough
  18. }
  19. switch myvar {
  20. case 1: /* multi
  21. line
  22. comment */
  23. fallthrough
  24. case 2:
  25. var a = 2
  26. }
  27. switch myvar {
  28. case MyFunc(x: [1, 2, YourFunc(a: 23)], y: 2):
  29. fallthrough
  30. default:
  31. var three = 4
  32. }
  33. switch myvar {
  34. case .alpha:
  35. var one = 1
  36. case .beta:
  37. fallthrough
  38. case .gamma:
  39. var three = 3
  40. default:
  41. var four = 4
  42. }
  43. let aPoint = (1, -1)
  44. switch aPoint {
  45. case let (x, y) where x == y:
  46. let A = "A"
  47. case let (x, y) where x == -y:
  48. fallthrough
  49. default:
  50. let B = "B"
  51. }
  52. switch myvar {
  53. case MyFun(with: { $1 }):
  54. fallthrough
  55. case "abc":
  56. let two = 2
  57. }

补充

fallthrough在case中之后的语句不会执行,转而执行下一个case或者default语句 属于流程控制的一部分
这里是官方文档


No Grouping Extension

标识符 默认开启 支持自动更正 类别 分析仪 最低swift编译版本
no_grouping_extension idiomatic 3.0.0

不应该使用Extension来对同文件源码进行分组。

示例

非触发

  1. protocol Food {}
  2. extension Food {}
  3. class Apples {}
  4. extension Oranges {}

触发

  1. enum Fruit {}
  2. extension Fruit {}
  3. extension Tea: Error {}
  4. struct Tea {}
  5. class Ham { class Spam {}}
  6. extension Ham.Spam {}
  7. extension External { struct Gotcha {}}
  8. extension External.Gotcha {}

Notification Center Detachment

标识符 默认开启 支持自动更正 类别 分析仪 最低swift编译版本
notification_center_detachment lint 3.0.0

当一个对象作为观察者时,需要在deinit中移除

示例

非触发

  1. class Foo {
  2. deinit {
  3. NotificationCenter.default.removeObserver(self)
  4. }
  5. }
  6. class Foo {
  7. func bar() {
  8. NotificationCenter.default.removeObserver(otherObject)
  9. }
  10. }

触发

  1. class Foo {
  2. func bar() {
  3. NotificationCenter.default.removeObserver(self)
  4. }
  5. }

补充

deinitialization


Number Separator

标识符 默认开启 支持自动更正 类别 分析仪 最低swift编译版本
number_separator style 3.0.0

对于比较大的数字来讲,下划线分隔符应该作为千分位的分隔符

示例

非触发

  1. let foo = -100
  2. let foo = -1_000
  3. let foo = -1_000_000
  4. let foo = -1.000_1
  5. let foo = -1_000_000.000_000_1
  6. let binary = -0b10000
  7. let binary = -0b1000_0001
  8. let hex = -0xA
  9. let hex = -0xAA_BB
  10. let octal = -0o21
  11. let octal = -0o21_1
  12. let exp = -1_000_000.000_000e2
  13. let foo = +100
  14. let foo = +1_000
  15. let foo = +1_000_000
  16. let foo = +1.000_1
  17. let foo = +1_000_000.000_000_1
  18. let binary = +0b10000
  19. let binary = +0b1000_0001
  20. let hex = +0xA
  21. let hex = +0xAA_BB
  22. let octal = +0o21
  23. let octal = +0o21_1
  24. let exp = +1_000_000.000_000e2
  25. let foo = 100
  26. let foo = 1_000
  27. let foo = 1_000_000
  28. let foo = 1.000_1
  29. let foo = 1_000_000.000_000_1
  30. let binary = 0b10000
  31. let binary = 0b1000_0001
  32. let hex = 0xA
  33. let hex = 0xAA_BB
  34. let octal = 0o21
  35. let octal = 0o21_1
  36. let exp = 1_000_000.000_000e2

触发

  1. let foo = ↓-10_0
  2. let foo = ↓-1000
  3. let foo = ↓-1000e2
  4. let foo = ↓-1000E2
  5. let foo = ↓-1__000
  6. let foo = ↓-1.0001
  7. let foo = ↓-1_000_000.000000_1
  8. let foo = ↓-1000000.000000_1
  9. let foo = +↓10_0
  10. let foo = +↓1000
  11. let foo = +↓1000e2
  12. let foo = +↓1000E2
  13. let foo = +↓1__000
  14. let foo = +↓1.0001
  15. let foo = +↓1_000_000.000000_1
  16. let foo = +↓1000000.000000_1
  17. let foo = 10_0
  18. let foo = 1000
  19. let foo = 1000e2
  20. let foo = 1000E2
  21. let foo = 1__000
  22. let foo = 1.0001
  23. let foo = 1_000_000.000000_1
  24. let foo = 1000000.000000_1

Object Literal

标识符 默认开启 支持自动更正 类别 分析仪 最低swift编译版本
object_literal idiomatic 3.0.0

优先使用object literal来取代图像和颜色的初始化

示例

非触发

  1. let image = #imageLiteral(resourceName: "image.jpg")
  2. let color = #colorLiteral(red: 0.9607843161, green: 0.7058823705, blue: 0.200000003, alpha: 1)
  3. let image = UIImage(named: aVariable)
  4. let image = UIImage(named: "interpolated \(variable)")
  5. let color = UIColor(red: value, green: value, blue: value, alpha: 1)
  6. let image = NSImage(named: aVariable)
  7. let image = NSImage(named: "interpolated \(variable)")
  8. let color = NSColor(red: value, green: value, blue: value, alpha: 1)

触发

  1. let image = UIImage(named: "foo")
  2. let color = UIColor(red: 0.3, green: 0.3, blue: 0.3, alpha: 1)
  3. let color = UIColor(red: 100 / 255.0, green: 50 / 255.0, blue: 0, alpha: 1)
  4. let color = UIColor(white: 0.5, alpha: 1)
  5. let image = NSImage(named: "foo")
  6. let color = NSColor(red: 0.3, green: 0.3, blue: 0.3, alpha: 1)
  7. let color = NSColor(red: 100 / 255.0, green: 50 / 255.0, blue: 0, alpha: 1)
  8. let color = NSColor(white: 0.5, alpha: 1)
  9. let image = UIImage.init(named: "foo")
  10. let color = UIColor.init(red: 0.3, green: 0.3, blue: 0.3, alpha: 1)
  11. let color = UIColor.init(red: 100 / 255.0, green: 50 / 255.0, blue: 0, alpha: 1)
  12. let color = UIColor.init(white: 0.5, alpha: 1)
  13. let image = NSImage.init(named: "foo")
  14. let color = NSColor.init(red: 0.3, green: 0.3, blue: 0.3, alpha: 1)
  15. let color = NSColor.init(red: 100 / 255.0, green: 50 / 255.0, blue: 0, alpha: 1)
  16. let color = NSColor.init(white: 0.5, alpha: 1)

补充

Swift Literals
Be Literal


Opening Brace Spacing

标识符 默认开启 支持自动更正 类别 分析仪 最低swift编译版本
opening_brace style 3.0.0

开口大括号前必须又一个空格,并且应该与声明位于同一行

示例

非触发

  1. func abc() {
  2. }
  3. [].map() { $0 }
  4. [].map({ })
  5. if let a = b { }
  6. while a == b { }
  7. guard let a = b else { }
  8. if
  9. let a = b,
  10. let c = d
  11. where a == c
  12. { }
  13. while
  14. let a = b,
  15. let c = d
  16. where a == c
  17. { }
  18. guard
  19. let a = b,
  20. let c = d
  21. where a == c else
  22. { }
  23. struct Rule {}
  24. struct Parent {
  25. struct Child {
  26. let foo: Int
  27. }
  28. }

触发

  1. func abc()↓{
  2. }
  3. func abc()
  4. ↓{ }
  5. [].map()↓{ $0 }
  6. [].map( ↓{ } )
  7. if let a = b↓{ }
  8. while a == b↓{ }
  9. guard let a = b else↓{ }
  10. if
  11. let a = b,
  12. let c = d
  13. where a == c↓{ }
  14. while
  15. let a = b,
  16. let c = d
  17. where a == c↓{ }
  18. guard
  19. let a = b,
  20. let c = d
  21. where a == c else↓{ }
  22. struct Rule↓{}
  23. struct Rule
  24. ↓{
  25. }
  26. struct Rule
  27. ↓{
  28. }
  29. struct Parent {
  30. struct Child
  31. ↓{
  32. let foo: Int
  33. }
  34. }

Operator Usage Whitespace

标识符 默认开启 支持自动更正 类别 分析仪 最低swift编译版本
operator_usage_whitespace style 3.0.0

运算符前后应当被空格包裹

示例

非触发

  1. let foo = 1 + 2
  2. let foo = 1 > 2
  3. let foo = !false
  4. let foo: Int?
  5. let foo: Array<String>
  6. let model = CustomView<Container<Button>, NSAttributedString>()
  7. let foo: [String]
  8. let foo = 1 +
  9. 2
  10. let range = 1...3
  11. let range = 1 ... 3
  12. let range = 1..<3
  13. #if swift(>=3.0)
  14. foo()
  15. #endif
  16. array.removeAtIndex(-200)
  17. let name = "image-1"
  18. button.setImage(#imageLiteral(resourceName: "image-1"), for: .normal)
  19. let doubleValue = -9e-11
  20. let foo = GenericType<(UIViewController) -> Void>()
  21. let foo = Foo<Bar<T>, Baz>()
  22. let foo = SignalProducer<Signal<Value, Error>, Error>([ self.signal, next ]).flatten(.concat)

触发

  1. let foo = 1↓+2
  2. let foo = 1 + 2
  3. let foo = 1 + 2
  4. let foo = 1 + 2
  5. let foo↓=1↓+2
  6. let foo↓=1 + 2
  7. let foo↓=bar
  8. let range = 1 ..< 3
  9. let foo = bar ?? 0
  10. let foo = bar↓??0
  11. let foo = bar != 0
  12. let foo = bar !== bar2
  13. let v8 = Int8(1)↓ << 6
  14. let v8 = 1 << (6)
  15. let v8 = 1 << (6)
  16. let foo = 1 > 2

Operator Function Whitespace

标识符 默认开启 支持自动更正 类别 分析仪 最低swift编译版本
operator_whitespace style 3.0.0

自定义运算符的时候,前后需要用空格包围。

示例

非触发

  1. func <| (lhs: Int, rhs: Int) -> Int {}
  2. func <|< <A>(lhs: A, rhs: A) -> A {}
  3. func abc(lhs: Int, rhs: Int) -> Int {}

触发

  1. func <|(lhs: Int, rhs: Int) -> Int {}
  2. func <|<<A>(lhs: A, rhs: A) -> A {}
  3. func <| (lhs: Int, rhs: Int) -> Int {}
  4. func <|< <A>(lhs: A, rhs: A) -> A {}
  5. func <| (lhs: Int, rhs: Int) -> Int {}
  6. func <|< <A>(lhs: A, rhs: A) -> A {}

Overridden methods call super

标识符 默认开启 支持自动更正 类别 分析仪 最低swift编译版本
overridden_super_call lint 3.0.0

一些被覆写的方法应该总是调用父类

示例

非触发

  1. class VC: UIViewController {
  2. override func viewWillAppear(_ animated: Bool) {
  3. super.viewWillAppear(animated)
  4. }
  5. }
  6. class VC: UIViewController {
  7. override func viewWillAppear(_ animated: Bool) {
  8. self.method1()
  9. super.viewWillAppear(animated)
  10. self.method2()
  11. }
  12. }
  13. class VC: UIViewController {
  14. override func loadView() {
  15. }
  16. }
  17. class Some {
  18. func viewWillAppear(_ animated: Bool) {
  19. }
  20. }
  21. class VC: UIViewController {
  22. override func viewDidLoad() {
  23. defer {
  24. super.viewDidLoad()
  25. }
  26. }
  27. }

触发

  1. class VC: UIViewController {
  2. override func viewWillAppear(_ animated: Bool) {↓
  3. //Not calling to super
  4. self.method()
  5. }
  6. }
  7. class VC: UIViewController {
  8. override func viewWillAppear(_ animated: Bool) {↓
  9. super.viewWillAppear(animated)
  10. //Other code
  11. super.viewWillAppear(animated)
  12. }
  13. }
  14. class VC: UIViewController {
  15. override func didReceiveMemoryWarning() {↓
  16. }
  17. }

Override in Extension

标识符 默认开启 支持自动更正 类别 分析仪 最低swift编译版本
override_in_extension lint 3.0.0

扩展中不应该覆写方法

示例

非触发

  1. extension Person {
  2. var age: Int { return 42 }
  3. }
  4. extension Person {
  5. func celebrateBirthday() {}
  6. }
  7. class Employee: Person {
  8. override func celebrateBirthday() {}
  9. }
  10. class Foo: NSObject {}
  11. extension Foo {
  12. override var description: String { return "" }
  13. }
  14. struct Foo {
  15. class Bar: NSObject {}
  16. }
  17. extension Foo.Bar {
  18. override var description: String { return "" }
  19. }

触发

  1. extension Person {
  2. override var age: Int { return 42 }
  3. }
  4. extension Person {
  5. override func celebrateBirthday() {}
  6. }

Pattern Matching Keywords

标识符 默认开启 支持自动更正 类别 分析仪 最低swift编译版本
pattern_mactching_keywords idiomatic 3.0.0

通过将关键字移出元组来进行模式匹配

示例

非触发

  1. switch foo {
  2. default: break
  3. }
  4. switch foo {
  5. case 1: break
  6. }
  7. switch foo {
  8. case bar: break
  9. }
  10. switch foo {
  11. case let (x, y): break
  12. }
  13. switch foo {
  14. case .foo(let x): break
  15. }
  16. switch foo {
  17. case let .foo(x, y): break
  18. }
  19. switch foo {
  20. case .foo(let x), .bar(let x): break
  21. }
  22. switch foo {
  23. case .foo(let x, var y): break
  24. }
  25. switch foo {
  26. case var (x, y): break
  27. }
  28. switch foo {
  29. case .foo(var x): break
  30. }
  31. switch foo {
  32. case var .foo(x, y): break
  33. }

触发

  1. switch foo {
  2. case (↓let x, let y): break
  3. }
  4. switch foo {
  5. case .foo(↓let x, let y): break
  6. }
  7. switch foo {
  8. case (.yamlParsing(↓let x), .yamlParsing(↓let y)): break
  9. }
  10. switch foo {
  11. case (↓var x, var y): break
  12. }
  13. switch foo {
  14. case .foo(↓var x, var y): break
  15. }
  16. switch foo {
  17. case (.yamlParsing(↓var x), .yamlParsing(↓var y)): break
  18. }

Prefixed Top-Level Constant

标识符 默认开启 支持自动更正 类别 分析仪 最低swift编译版本
prefixed_toplevel_constant style 3.0.0

顶级的常量需要加k作为前缀

示例

非触发

  1. private let kFoo = 20.0
  2. public let kFoo = false
  3. internal let kFoo = "Foo"
  4. let kFoo = true
  5. struct Foo {
  6. let bar = 20.0
  7. }
  8. private var foo = 20.0
  9. public var foo = false
  10. internal var foo = "Foo"
  11. var foo = true
  12. var foo = true, bar = true
  13. var foo = true, let kFoo = true
  14. let
  15. kFoo = true
  16. var foo: Int {
  17. return a + b
  18. }
  19. let kFoo = {
  20. return a + b
  21. }()

触发

  1. private let Foo = 20.0
  2. public let Foo = false
  3. internal let Foo = "Foo"
  4. let Foo = true
  5. let foo = 2, bar = true
  6. var foo = true, let Foo = true
  7. let
  8. foo = true
  9. let foo = {
  10. return a + b
  11. }()

Private Actions

标识符 默认开启 支持自动更正 类别 分析仪 最低swift编译版本
private_action lint 3.0.0

IBAction 必须使用private修饰

示例

非触发

  1. class Foo {
  2. @IBAction private func barButtonTapped(_ sender: UIButton) {}
  3. }
  4. struct Foo {
  5. @IBAction private func barButtonTapped(_ sender: UIButton) {}
  6. }
  7. class Foo {
  8. @IBAction fileprivate func barButtonTapped(_ sender: UIButton) {}
  9. }
  10. struct Foo {
  11. @IBAction fileprivate func barButtonTapped(_ sender: UIButton) {}
  12. }
  13. private extension Foo {
  14. @IBAction func barButtonTapped(_ sender: UIButton) {}
  15. }
  16. fileprivate extension Foo {
  17. @IBAction func barButtonTapped(_ sender: UIButton) {}
  18. }

触发

  1. class Foo {
  2. @IBAction func barButtonTapped(_ sender: UIButton) {}
  3. }
  4. struct Foo {
  5. @IBAction func barButtonTapped(_ sender: UIButton) {}
  6. }
  7. class Foo {
  8. @IBAction public func barButtonTapped(_ sender: UIButton) {}
  9. }
  10. struct Foo {
  11. @IBAction public func barButtonTapped(_ sender: UIButton) {}
  12. }
  13. class Foo {
  14. @IBAction internal func barButtonTapped(_ sender: UIButton) {}
  15. }
  16. struct Foo {
  17. @IBAction internal func barButtonTapped(_ sender: UIButton) {}
  18. }
  19. extension Foo {
  20. @IBAction func barButtonTapped(_ sender: UIButton) {}
  21. }
  22. extension Foo {
  23. @IBAction public func barButtonTapped(_ sender: UIButton) {}
  24. }
  25. extension Foo {
  26. @IBAction internal func barButtonTapped(_ sender: UIButton) {}
  27. }
  28. public extension Foo {
  29. @IBAction func barButtonTapped(_ sender: UIButton) {}
  30. }
  31. internal extension Foo {
  32. @IBAction func barButtonTapped(_ sender: UIButton) {}
  33. }

Private Outlets

标识符 默认开启 支持自动更正 类别 分析仪 最低swift编译版本
private_outlet lint 3.0.0

OBOutlets 必须是使用private修饰来保证对UIKit的高层不可见

示例

非触发

  1. class Foo {
  2. @IBOutlet private var label: UILabel?
  3. }
  4. class Foo {
  5. @IBOutlet private var label: UILabel!
  6. }
  7. class Foo {
  8. var notAnOutlet: UILabel
  9. }
  10. class Foo {
  11. @IBOutlet weak private var label: UILabel?
  12. }
  13. class Foo {
  14. @IBOutlet private weak var label: UILabel?
  15. }

触发

  1. class Foo {
  2. @IBOutlet var label: UILabel?
  3. }
  4. class Foo {
  5. @IBOutlet var label: UILabel!
  6. }

补充

大部分场景下都比较讨厌storyboard、xib的方式,无他,习惯。


Private Over filePrivate

标识符 默认开启 支持自动更正 类别 分析仪 最低swift编译版本
private_over_fileprivate idiomatic 3.0.0

首选使用private而不是fileprivate

示例

非触发

  1. extension String {}
  2. private extension String {}
  3. public
  4. enum MyEnum {}
  5. open extension
  6. String {}
  7. internal extension String {}
  8. extension String {
  9. fileprivate func Something(){}
  10. }
  11. class MyClass {
  12. fileprivate let myInt = 4
  13. }
  14. class MyClass {
  15. fileprivate(set) var myInt = 4
  16. }
  17. struct Outter {
  18. struct Inter {
  19. fileprivate struct Inner {}
  20. }
  21. }

触发

  1. fileprivate enum MyEnum {}
  2. fileprivate class MyClass {
  3. fileprivate(set) var myInt = 4
  4. }

补充

swift4访问权限控制
Access Control


Private Unit Test

标识符 默认开启 支持自动更正 类别 分析仪 最低swift编译版本
private_unit_test lint 3.0.0

默认跳过标记为private的单元测试

示例

非触发

  1. class FooTest: XCTestCase { func test1() {}
  2. internal func test2() {}
  3. public func test3() {}
  4. }
  5. internal class FooTest: XCTestCase { func test1() {}
  6. internal func test2() {}
  7. public func test3() {}
  8. }
  9. public class FooTest: XCTestCase { func test1() {}
  10. internal func test2() {}
  11. public func test3() {}
  12. }
  13. private class Foo: NSObject { func test1() {}
  14. internal func test2() {}
  15. public func test3() {}
  16. }
  17. private class Foo { func test1() {}
  18. internal func test2() {}
  19. public func test3() {}
  20. }
  21. public class FooTest: XCTestCase { func test1(param: Int) {}
  22. }

触发

  1. private class FooTest: XCTestCase { func test1() {}
  2. internal func test2() {}
  3. public func test3() {}
  4. private func test4() {}
  5. }
  6. class FooTest: XCTestCase { func test1() {}
  7. internal func test2() {}
  8. public func test3() {}
  9. private func test4() {}
  10. }
  11. internal class FooTest: XCTestCase { func test1() {}
  12. internal func test2() {}
  13. public func test3() {}
  14. private func test4() {}
  15. }
  16. public class FooTest: XCTestCase { func test1() {}
  17. internal func test2() {}
  18. public func test3() {}
  19. private func test4() {}
  20. }

Prohibited Interface Builder

标识符 默认开启 支持自动更正 类别 分析仪 最低swift编译版本
prohibited_interface_builder lint 3.0.0

避免使用Interface Builder生成视图

示例

非触发

  1. class ViewController: UIViewController {
  2. var label: UILabel!
  3. }
  4. class ViewController: UIViewController {
  5. @objc func buttonTapped(_ sender: UIButton) {}
  6. }

触发

  1. class ViewController: UIViewController {
  2. @IBOutlet var label: UILabel!
  3. }
  4. class ViewController: UIViewController {
  5. @IBAction func buttonTapped(_ sender: UIButton) {}
  6. }

Prohibited calls to super

标识符 默认开启 支持自动更正 类别 分析仪 最低swift编译版本
prohibited_super_call lint 3.0.0

有一些方法应该避免直接调用父类

示例

非触发

  1. class VC: UIViewController {
  2. override func loadView() {
  3. }
  4. }
  5. class NSView {
  6. func updateLayer() {
  7. self.method1()
  8. }
  9. }
  10. public class FileProviderExtension: NSFileProviderExtension {
  11. override func providePlaceholder(at url: URL, completionHandler: @escaping (Error?) -> Void) {
  12. guard let identifier = persistentIdentifierForItem(at: url) else {
  13. completionHandler(NSFileProviderError(.noSuchItem))
  14. return
  15. }
  16. }
  17. }

触发

  1. class VC: UIViewController {
  2. override func loadView() {↓
  3. super.loadView()
  4. }
  5. }
  6. class VC: NSFileProviderExtension {
  7. override func providePlaceholder(at url: URL, completionHandler: @escaping (Error?) -> Void) {↓
  8. self.method1()
  9. super.providePlaceholder(at:url, completionHandler: completionHandler)
  10. }
  11. }
  12. class VC: NSView {
  13. override func updateLayer() {↓
  14. self.method1()
  15. super.updateLayer()
  16. self.method2()
  17. }
  18. }
  19. class VC: NSView {
  20. override func updateLayer() {↓
  21. defer {
  22. super.updateLayer()
  23. }
  24. }
  25. }