Multiline Arguments
| 标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
multiline_arguments |
否 |
否 |
style |
否 |
3.0.0 |
实参需要写在同一行或者每个一行。
示例
非触发
foo()foo()foo { }foo {}foo(0)foo(0, 1)foo(0, 1) { }foo(0, param1: 1)foo(0, param1: 1) { }foo(param1: 1)foo(param1: 1) { }foo(param1: 1, param2: true) { }foo(param1: 1, param2: true, param3: [3]) { }foo(param1: 1, param2: true, param3: [3]) { bar()}foo(param1: 1, param2: true, param3: [3])foo( param1: 1, param2: true, param3: [3])foo( param1: 1, param2: true, param3: [3])
触发
foo(0, param1: 1, ↓param2: true, ↓param3: [3])foo(0, ↓param1: 1, param2: true, ↓param3: [3])foo(0, ↓param1: 1, ↓param2: true, param3: [3])foo( 0, ↓param1: 1, param2: true, ↓param3: [3])
补充
简单讲 arguments指实参 parameters指形参
parameters和arguments的区别
Mutiline Function Chains
| 标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
multiline_function_chains |
否 |
否 |
style |
否 |
3.0.0 |
链式调用需要写在同一行或者每个一行。
示例
非触发
let evenSquaresSum = [20, 17, 35, 4].filter { $0 % 2 == 0 }.map { $0 * $0 }.reduce(0, +)let evenSquaresSum = [20, 17, 35, 4] .filter { $0 % 2 == 0 }.map { $0 * $0 }.reduce(0, +)",let chain = a .b(1, 2, 3) .c { blah in print(blah) } .d()let chain = a.b(1, 2, 3) .c { blah in print(blah) } .d()let chain = a.b(1, 2, 3) .c { blah in print(blah) } .d()let chain = a.b(1, 2, 3) .c(.init( a: 1, b, 2, c, 3)) .d()self.viewModel.outputs.postContextualNotification .observeForUI() .observeValues { NotificationCenter.default.post( Notification( name: .ksr_showNotificationsDialog, userInfo: [UserInfoKeys.context: PushNotificationDialog.Context.pledge, UserInfoKeys.viewController: self] ) ) }let remainingIDs = Array(Set(self.currentIDs).subtracting(Set(response.ids)))self.happeningNewsletterOn = self.updateCurrentUser .map { $0.newsletters.happening }.skipNil().skipRepeats()
触发
let evenSquaresSum = [20, 17, 35, 4] .filter { $0 % 2 == 0 }↓.map { $0 * $0 } .reduce(0, +)let evenSquaresSum = a.b(1, 2, 3) .c { blah in print(blah) }↓.d()let evenSquaresSum = a.b(1, 2, 3) .c(2, 3, 4)↓.d()let evenSquaresSum = a.b(1, 2, 3)↓.c { blah in print(blah) } .d()a.b {// ““}↓.e()
Multiline Parameters
| 标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
| multiline_parameters |
否 |
否 |
style |
否 |
3.0.0 |
形参需要写在同一行或者每个一行。
示例
非触发
func foo() { }func foo(param1: Int) { }func foo(param1: Int, param2: Bool) { }func foo(param1: Int, param2: Bool, param3: [String]) { }func foo(param1: Int, param2: Bool, param3: [String]) { }func foo(_ param1: Int, param2: Int, param3: Int) -> (Int) -> Int { return { x in x + param1 + param2 + param3 }}static func foo() { }static func foo(param1: Int) { }static func foo(param1: Int, param2: Bool) { }static func foo(param1: Int, param2: Bool, param3: [String]) { }static func foo(param1: Int, param2: Bool, param3: [String]) { }protocol Foo { func foo() { }}protocol Foo { func foo(param1: Int) { }}protocol Foo { func foo(param1: Int, param2: Bool) { }}protocol Foo { func foo(param1: Int, param2: Bool, param3: [String]) { }}protocol Foo { func foo(param1: Int, param2: Bool, param3: [String]) { }}protocol Foo { static func foo(param1: Int, param2: Bool, param3: [String]) { }}protocol Foo { static func foo(param1: Int, param2: Bool, param3: [String]) { }}protocol Foo { class func foo(param1: Int, param2: Bool, param3: [String]) { }}protocol Foo { class func foo(param1: Int, param2: Bool, param3: [String]) { }}enum Foo { func foo() { }}enum Foo { func foo(param1: Int) { }}enum Foo { func foo(param1: Int, param2: Bool) { }}enum Foo { func foo(param1: Int, param2: Bool, param3: [String]) { }}enum Foo { func foo(param1: Int, param2: Bool, param3: [String]) { }}enum Foo { static func foo(param1: Int, param2: Bool, param3: [String]) { }}enum Foo { static func foo(param1: Int, param2: Bool, param3: [String]) { }}struct Foo { func foo() { }}struct Foo { func foo(param1: Int) { }}struct Foo { func foo(param1: Int, param2: Bool) { }}struct Foo { func foo(param1: Int, param2: Bool, param3: [String]) { }}struct Foo { func foo(param1: Int, param2: Bool, param3: [String]) { }}struct Foo { static func foo(param1: Int, param2: Bool, param3: [String]) { }}struct Foo { static func foo(param1: Int, param2: Bool, param3: [String]) { }}class Foo { func foo() { }}class Foo { func foo(param1: Int) { }}class Foo { func foo(param1: Int, param2: Bool) { }}class Foo { func foo(param1: Int, param2: Bool, param3: [String]) { } }class Foo { func foo(param1: Int, param2: Bool, param3: [String]) { }}class Foo { class func foo(param1: Int, param2: Bool, param3: [String]) { }}class Foo { class func foo(param1: Int, param2: Bool, param3: [String]) { }}class Foo { class func foo(param1: Int, param2: Bool, param3: @escaping (Int, Int) -> Void = { _, _ in }) { }}class Foo { class func foo(param1: Int, param2: Bool, param3: @escaping (Int) -> Void = { _ in }) { }}class Foo { class func foo(param1: Int, param2: Bool, param3: @escaping ((Int) -> Void)? = nil) { }}class Foo { class func foo(param1: Int, param2: Bool, param3: @escaping ((Int) -> Void)? = { _ in }) { }}class Foo { class func foo(param1: Int, param2: @escaping ((Int) -> Void)? = { _ in }, param3: Bool) { }}class Foo { class func foo(param1: Int, param2: @escaping ((Int) -> Void)? = { _ in }, param3: @escaping (Int, Int) -> Void = { _, _ in }) { }}class Foo { class func foo(param1: Int, param2: Bool, param3: @escaping (Int) -> Void = { (x: Int) in }) { }}class Foo { class func foo(param1: Int, param2: Bool, param3: @escaping (Int, (Int) -> Void) -> Void = { (x: Int, f: (Int) -> Void) in }) { }}
触发
func ↓foo(_ param1: Int, param2: Int, param3: Int) -> (Int) -> Int { return { x in x + param1 + param2 + param3 }}protocol Foo { func ↓foo(param1: Int, param2: Bool, param3: [String]) { }}protocol Foo { func ↓foo(param1: Int, param2: Bool, param3: [String]) { }}protocol Foo { static func ↓foo(param1: Int, param2: Bool, param3: [String]) { }}protocol Foo { static func ↓foo(param1: Int, param2: Bool, param3: [String]) { }}protocol Foo { class func ↓foo(param1: Int, param2: Bool, param3: [String]) { }}protocol Foo { class func ↓foo(param1: Int, param2: Bool, param3: [String]) { }}enum Foo { func ↓foo(param1: Int, param2: Bool, param3: [String]) { }}enum Foo { func ↓foo(param1: Int, param2: Bool, param3: [String]) { }}enum Foo { static func ↓foo(param1: Int, param2: Bool, param3: [String]) { }}enum Foo { static func ↓foo(param1: Int, param2: Bool, param3: [String]) { }}struct Foo { func ↓foo(param1: Int, param2: Bool, param3: [String]) { }}struct Foo { func ↓foo(param1: Int, param2: Bool, param3: [String]) { }}struct Foo { static func ↓foo(param1: Int, param2: Bool, param3: [String]) { }}struct Foo { static func ↓foo(param1: Int, param2: Bool, param3: [String]) { }}class Foo { func ↓foo(param1: Int, param2: Bool, param3: [String]) { }}class Foo { func ↓foo(param1: Int, param2: Bool, param3: [String]) { }}class Foo { class func ↓foo(param1: Int, param2: Bool, param3: [String]) { }}class Foo { class func ↓foo(param1: Int, param2: Bool, param3: [String]) { }}class Foo { class func ↓foo(param1: Int, param2: Bool, param3: @escaping (Int, Int) -> Void = { _, _ in }) { }}class Foo { class func ↓foo(param1: Int, param2: Bool, param3: @escaping (Int) -> Void = { (x: Int) in }) { }}
Multiple Closures with Trailing Closure
| 标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
multiple_closures_with_trailing_closure |
是 |
否 |
style |
否 |
3.0.0 |
有多个闭包作为参数的时候,不应该使用尾随闭包语法。
示例
非触发
foo.map { $0 + 1 }foo.reduce(0) { $0 + $1 }if let foo = bar.map({ $0 + 1 }) {}foo.something(param1: { $0 }, param2: { $0 + 1 })UIView.animate(withDuration: 1.0) { someView.alpha = 0.0}
触发
foo.something(param1: { $0 }) ↓{ $0 + 1 }UIView.animate(withDuration: 1.0, animations: { someView.alpha = 0.0}) ↓{ _ in someView.removeFromSuperview()}
补充
闭包
Swift闭包简单应用
Nesting
| 标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
nesting |
是 |
否 |
metrics |
否 |
3.0.0 |
类型嵌套最多一级,语句嵌套最多五级。
示例
非触发
class Class0 { class Class1 {} }func func0() {func func1() {func func2() {func func3() {func func4() { func func5() {}}}}}}struct Class0 { struct Class1 {} }func func0() {func func1() {func func2() {func func3() {func func4() { func func5() {}}}}}}enum Class0 { enum Class1 {} }func func0() {func func1() {func func2() {func func3() {func func4() { func func5() {}}}}}}enum Enum0 { enum Enum1 { case Case } }
触发
class A { class B { ↓class C {} } }struct A { struct B { ↓struct C {} } }func func0() {func func1() {func func2() {func func3() {func func4() { func func5() {↓func func6() {}}}}}}}
Nimble Operator
| 标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
nimble_operator |
否 |
是 |
idiomatic |
否 |
3.0.0 |
优先使用Nimble运算符而不是匹配函数
示例
非触发
expect(seagull.squawk) != "Hi!"expect("Hi!") == "Hi!"expect(10) > 2expect(10) >= 10expect(10) < 11expect(10) <= 10expect(x) === xexpect(10) == 10expect(object.asyncFunction()).toEventually(equal(1))expect(actual).to(haveCount(expected))
触发
↓expect(seagull.squawk).toNot(equal("Hi"))↓expect(12).toNot(equal(10))↓expect(10).to(equal(10))↓expect(10).to(beGreaterThan(8))↓expect(10).to(beGreaterThanOrEqualTo(10))↓expect(10).to(beLessThan(11))↓expect(10).to(beLessThanOrEqualTo(10))↓expect(x).to(beIdenticalTo(x))expect(10) > 2 ↓expect(10).to(beGreaterThan(2))
补充
Swift 进阶开发指南:如何使用 Quick、Nimble 执行测试驱动开发(TDD)
No Extension Access Modifier
| 标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
no_extension_access_modifier |
否 |
否 |
idiomatic |
否 |
3.0.0 |
不要对Extension使用权限控制符
示例
非触发
extension String {} extension String {}
触发
↓private extension String {}↓public extension String {}↓open extension String {}↓internal extension String {}↓fileprivate extension String {}
No Fallthrough Only
| 标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
no_fallthrough_only |
是 |
否 |
idiomatic |
否 |
3.0.0 |
使用fallthrough的case语句至少要包含一句其他的语句
示例
非触发
switch myvar {case 1: var a = 1 fallthroughcase 2: var a = 2}switch myvar {case "a": var one = 1 var two = 2 fallthroughcase "b": /* comment */ var three = 3}switch myvar {case 1: let one = 1case 2: // comment var two = 2}switch myvar {case MyFunc(x: [1, 2, YourFunc(a: 23)], y: 2): var three = 3 fallthroughdefault: var three = 4}switch myvar {case .alpha: var one = 1case .beta: var three = 3 fallthroughdefault: var four = 4}let aPoint = (1, -1)switch aPoint {case let (x, y) where x == y: let A = "A"case let (x, y) where x == -y: let B = "B" fallthroughdefault: let C = "C"}switch myvar {case MyFun(with: { $1 }): let one = 1 fallthroughcase "abc": let two = 2}
触发
switch myvar {case 1: ↓fallthroughcase 2: var a = 1}switch myvar {case 1: var a = 2case 2: ↓fallthroughcase 3: var a = 3}switch myvar {case 1: // comment ↓fallthrough}switch myvar {case 1: /* multi line comment */ ↓fallthroughcase 2: var a = 2}switch myvar {case MyFunc(x: [1, 2, YourFunc(a: 23)], y: 2): ↓fallthroughdefault: var three = 4}switch myvar {case .alpha: var one = 1case .beta: ↓fallthroughcase .gamma: var three = 3default: var four = 4}let aPoint = (1, -1)switch aPoint {case let (x, y) where x == y: let A = "A"case let (x, y) where x == -y: ↓fallthroughdefault: let B = "B"}switch myvar {case MyFun(with: { $1 }): ↓fallthroughcase "abc": let two = 2}
补充
fallthrough在case中之后的语句不会执行,转而执行下一个case或者default语句 属于流程控制的一部分
这里是官方文档
No Grouping Extension
| 标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
no_grouping_extension |
否 |
否 |
idiomatic |
否 |
3.0.0 |
不应该使用Extension来对同文件源码进行分组。
示例
非触发
protocol Food {}extension Food {}class Apples {}extension Oranges {}
触发
enum Fruit {}↓extension Fruit {}↓extension Tea: Error {}struct Tea {}class Ham { class Spam {}}↓extension Ham.Spam {}extension External { struct Gotcha {}}↓extension External.Gotcha {}
Notification Center Detachment
| 标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
notification_center_detachment |
是 |
否 |
lint |
否 |
3.0.0 |
当一个对象作为观察者时,需要在deinit中移除
示例
非触发
class Foo { deinit { NotificationCenter.default.removeObserver(self) }}class Foo { func bar() { NotificationCenter.default.removeObserver(otherObject) }}
触发
class Foo { func bar() { ↓NotificationCenter.default.removeObserver(self) }}
补充
deinitialization
Number Separator
| 标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
number_separator |
否 |
是 |
style |
否 |
3.0.0 |
对于比较大的数字来讲,下划线分隔符应该作为千分位的分隔符
示例
非触发
let foo = -100let foo = -1_000let foo = -1_000_000let foo = -1.000_1let foo = -1_000_000.000_000_1let binary = -0b10000let binary = -0b1000_0001let hex = -0xAlet hex = -0xAA_BBlet octal = -0o21let octal = -0o21_1let exp = -1_000_000.000_000e2let foo = +100let foo = +1_000let foo = +1_000_000let foo = +1.000_1let foo = +1_000_000.000_000_1let binary = +0b10000let binary = +0b1000_0001let hex = +0xAlet hex = +0xAA_BBlet octal = +0o21let octal = +0o21_1let exp = +1_000_000.000_000e2let foo = 100let foo = 1_000let foo = 1_000_000let foo = 1.000_1let foo = 1_000_000.000_000_1let binary = 0b10000let binary = 0b1000_0001let hex = 0xAlet hex = 0xAA_BBlet octal = 0o21let octal = 0o21_1let exp = 1_000_000.000_000e2
触发
let foo = ↓-10_0let foo = ↓-1000let foo = ↓-1000e2let foo = ↓-1000E2let foo = ↓-1__000let foo = ↓-1.0001let foo = ↓-1_000_000.000000_1let foo = ↓-1000000.000000_1let foo = +↓10_0let foo = +↓1000let foo = +↓1000e2let foo = +↓1000E2let foo = +↓1__000let foo = +↓1.0001let foo = +↓1_000_000.000000_1let foo = +↓1000000.000000_1let foo = ↓10_0let foo = ↓1000let foo = ↓1000e2let foo = ↓1000E2let foo = ↓1__000let foo = ↓1.0001let foo = ↓1_000_000.000000_1let foo = ↓1000000.000000_1
Object Literal
| 标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
object_literal |
否 |
否 |
idiomatic |
否 |
3.0.0 |
优先使用object literal来取代图像和颜色的初始化
示例
非触发
let image = #imageLiteral(resourceName: "image.jpg")let color = #colorLiteral(red: 0.9607843161, green: 0.7058823705, blue: 0.200000003, alpha: 1)let image = UIImage(named: aVariable)let image = UIImage(named: "interpolated \(variable)")let color = UIColor(red: value, green: value, blue: value, alpha: 1)let image = NSImage(named: aVariable)let image = NSImage(named: "interpolated \(variable)")let color = NSColor(red: value, green: value, blue: value, alpha: 1)
触发
let image = ↓UIImage(named: "foo")let color = ↓UIColor(red: 0.3, green: 0.3, blue: 0.3, alpha: 1)let color = ↓UIColor(red: 100 / 255.0, green: 50 / 255.0, blue: 0, alpha: 1)let color = ↓UIColor(white: 0.5, alpha: 1)let image = ↓NSImage(named: "foo")let color = ↓NSColor(red: 0.3, green: 0.3, blue: 0.3, alpha: 1)let color = ↓NSColor(red: 100 / 255.0, green: 50 / 255.0, blue: 0, alpha: 1)let color = ↓NSColor(white: 0.5, alpha: 1)let image = ↓UIImage.init(named: "foo")let color = ↓UIColor.init(red: 0.3, green: 0.3, blue: 0.3, alpha: 1)let color = ↓UIColor.init(red: 100 / 255.0, green: 50 / 255.0, blue: 0, alpha: 1)let color = ↓UIColor.init(white: 0.5, alpha: 1)let image = ↓NSImage.init(named: "foo")let color = ↓NSColor.init(red: 0.3, green: 0.3, blue: 0.3, alpha: 1)let color = ↓NSColor.init(red: 100 / 255.0, green: 50 / 255.0, blue: 0, alpha: 1)let color = ↓NSColor.init(white: 0.5, alpha: 1)
补充
Swift Literals
Be Literal
Opening Brace Spacing
| 标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
| opening_brace |
是 |
是 |
style |
否 |
3.0.0 |
开口大括号前必须又一个空格,并且应该与声明位于同一行
示例
非触发
func abc() {}[].map() { $0 }[].map({ })if let a = b { }while a == b { }guard let a = b else { }if let a = b, let c = d where a == c{ }while let a = b, let c = d where a == c{ }guard let a = b, let c = d where a == c else{ }struct Rule {}struct Parent { struct Child { let foo: Int }}
触发
func abc()↓{}func abc() ↓{ }[].map()↓{ $0 }[].map( ↓{ } )if let a = b↓{ }while a == b↓{ }guard let a = b else↓{ }if let a = b, let c = d where a == c↓{ }while let a = b, let c = d where a == c↓{ }guard let a = b, let c = d where a == c else↓{ }struct Rule↓{}struct Rule↓{}struct Rule ↓{}struct Parent { struct Child ↓{ let foo: Int }}
Operator Usage Whitespace
| 标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
| operator_usage_whitespace |
否 |
是 |
style |
否 |
3.0.0 |
运算符前后应当被空格包裹
示例
非触发
let foo = 1 + 2let foo = 1 > 2let foo = !falselet foo: Int?let foo: Array<String>let model = CustomView<Container<Button>, NSAttributedString>()let foo: [String]let foo = 1 + 2let range = 1...3let range = 1 ... 3let range = 1..<3#if swift(>=3.0) foo()#endifarray.removeAtIndex(-200)let name = "image-1"button.setImage(#imageLiteral(resourceName: "image-1"), for: .normal)let doubleValue = -9e-11let foo = GenericType<(UIViewController) -> Void>()let foo = Foo<Bar<T>, Baz>()let foo = SignalProducer<Signal<Value, Error>, Error>([ self.signal, next ]).flatten(.concat)
触发
let foo = 1↓+2let foo = 1↓ + 2let foo = 1↓ + 2let foo = 1↓ + 2let foo↓=1↓+2let foo↓=1 + 2let foo↓=barlet range = 1↓ ..< 3let foo = bar↓ ?? 0let foo = bar↓??0let foo = bar↓ != 0let foo = bar↓ !== bar2let v8 = Int8(1)↓ << 6let v8 = 1↓ << (6)let v8 = 1↓ << (6) let foo = 1 > 2
Operator Function Whitespace
| 标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
operator_whitespace |
是 |
否 |
style |
否 |
3.0.0 |
自定义运算符的时候,前后需要用空格包围。
示例
非触发
func <| (lhs: Int, rhs: Int) -> Int {}func <|< <A>(lhs: A, rhs: A) -> A {}func abc(lhs: Int, rhs: Int) -> Int {}
触发
↓func <|(lhs: Int, rhs: Int) -> Int {}↓func <|<<A>(lhs: A, rhs: A) -> A {}↓func <| (lhs: Int, rhs: Int) -> Int {}↓func <|< <A>(lhs: A, rhs: A) -> A {}↓func <| (lhs: Int, rhs: Int) -> Int {}↓func <|< <A>(lhs: A, rhs: A) -> A {}
Overridden methods call super
| 标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
| overridden_super_call |
否 |
否 |
lint |
否 |
3.0.0 |
一些被覆写的方法应该总是调用父类
示例
非触发
class VC: UIViewController { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) }}class VC: UIViewController { override func viewWillAppear(_ animated: Bool) { self.method1() super.viewWillAppear(animated) self.method2() }}class VC: UIViewController { override func loadView() { }}class Some { func viewWillAppear(_ animated: Bool) { }}class VC: UIViewController { override func viewDidLoad() { defer { super.viewDidLoad() } }}
触发
class VC: UIViewController { override func viewWillAppear(_ animated: Bool) {↓ //Not calling to super self.method() }}class VC: UIViewController { override func viewWillAppear(_ animated: Bool) {↓ super.viewWillAppear(animated) //Other code super.viewWillAppear(animated) }}class VC: UIViewController { override func didReceiveMemoryWarning() {↓ }}
Override in Extension
| 标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
override_in_extension |
否 |
否 |
lint |
否 |
3.0.0 |
扩展中不应该覆写方法
示例
非触发
extension Person { var age: Int { return 42 }}extension Person { func celebrateBirthday() {}}class Employee: Person { override func celebrateBirthday() {}}class Foo: NSObject {}extension Foo { override var description: String { return "" }}struct Foo { class Bar: NSObject {}}extension Foo.Bar { override var description: String { return "" }}
触发
extension Person { override ↓var age: Int { return 42 }}extension Person { override ↓func celebrateBirthday() {}}
Pattern Matching Keywords
| 标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
pattern_mactching_keywords |
否 |
否 |
idiomatic |
否 |
3.0.0 |
通过将关键字移出元组来进行模式匹配
示例
非触发
switch foo { default: break}switch foo { case 1: break}switch foo { case bar: break}switch foo { case let (x, y): break}switch foo { case .foo(let x): break}switch foo { case let .foo(x, y): break}switch foo { case .foo(let x), .bar(let x): break}switch foo { case .foo(let x, var y): break}switch foo { case var (x, y): break}switch foo { case .foo(var x): break}switch foo { case var .foo(x, y): break}
触发
switch foo { case (↓let x, ↓let y): break}switch foo { case .foo(↓let x, ↓let y): break}switch foo { case (.yamlParsing(↓let x), .yamlParsing(↓let y)): break}switch foo { case (↓var x, ↓var y): break}switch foo { case .foo(↓var x, ↓var y): break}switch foo { case (.yamlParsing(↓var x), .yamlParsing(↓var y)): break}
Prefixed Top-Level Constant
| 标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
prefixed_toplevel_constant |
否 |
否 |
style |
否 |
3.0.0 |
顶级的常量需要加k作为前缀
示例
非触发
private let kFoo = 20.0public let kFoo = falseinternal let kFoo = "Foo"let kFoo = truestruct Foo { let bar = 20.0}private var foo = 20.0public var foo = falseinternal var foo = "Foo"var foo = truevar foo = true, bar = truevar foo = true, let kFoo = truelet kFoo = truevar foo: Int { return a + b}let kFoo = { return a + b}()
触发
private let ↓Foo = 20.0public let ↓Foo = falseinternal let ↓Foo = "Foo"let ↓Foo = truelet ↓foo = 2, ↓bar = truevar foo = true, let ↓Foo = truelet ↓foo = truelet ↓foo = { return a + b}()
Private Actions
| 标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
| private_action |
否 |
否 |
lint |
否 |
3.0.0 |
IBAction 必须使用private修饰
示例
非触发
class Foo { @IBAction private func barButtonTapped(_ sender: UIButton) {}}struct Foo { @IBAction private func barButtonTapped(_ sender: UIButton) {}}class Foo { @IBAction fileprivate func barButtonTapped(_ sender: UIButton) {}}struct Foo { @IBAction fileprivate func barButtonTapped(_ sender: UIButton) {}}private extension Foo { @IBAction func barButtonTapped(_ sender: UIButton) {}}fileprivate extension Foo { @IBAction func barButtonTapped(_ sender: UIButton) {}}
触发
class Foo { @IBAction ↓func barButtonTapped(_ sender: UIButton) {}}struct Foo { @IBAction ↓func barButtonTapped(_ sender: UIButton) {}}class Foo { @IBAction public ↓func barButtonTapped(_ sender: UIButton) {}}struct Foo { @IBAction public ↓func barButtonTapped(_ sender: UIButton) {}}class Foo { @IBAction internal ↓func barButtonTapped(_ sender: UIButton) {}}struct Foo { @IBAction internal ↓func barButtonTapped(_ sender: UIButton) {}}extension Foo { @IBAction ↓func barButtonTapped(_ sender: UIButton) {}}extension Foo { @IBAction public ↓func barButtonTapped(_ sender: UIButton) {}}extension Foo { @IBAction internal ↓func barButtonTapped(_ sender: UIButton) {}}public extension Foo { @IBAction ↓func barButtonTapped(_ sender: UIButton) {}}internal extension Foo { @IBAction ↓func barButtonTapped(_ sender: UIButton) {}}
Private Outlets
| 标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
| private_outlet |
否 |
否 |
lint |
否 |
3.0.0 |
OBOutlets 必须是使用private修饰来保证对UIKit的高层不可见
示例
非触发
class Foo { @IBOutlet private var label: UILabel?}class Foo { @IBOutlet private var label: UILabel!}class Foo { var notAnOutlet: UILabel}class Foo { @IBOutlet weak private var label: UILabel?}class Foo { @IBOutlet private weak var label: UILabel?}
触发
class Foo { @IBOutlet ↓var label: UILabel?}class Foo { @IBOutlet ↓var label: UILabel!}
补充
大部分场景下都比较讨厌storyboard、xib的方式,无他,习惯。
Private Over filePrivate
| 标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
private_over_fileprivate |
是 |
是 |
idiomatic |
否 |
3.0.0 |
首选使用private而不是fileprivate
示例
非触发
extension String {}private extension String {}public enum MyEnum {}open extension String {}internal extension String {}extension String {fileprivate func Something(){}}class MyClass {fileprivate let myInt = 4}class MyClass {fileprivate(set) var myInt = 4}struct Outter {struct Inter {fileprivate struct Inner {}}}
触发
↓fileprivate enum MyEnum {}↓fileprivate class MyClass {fileprivate(set) var myInt = 4}
补充
swift4访问权限控制
Access Control
Private Unit Test
| 标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
private_unit_test |
是 |
否 |
lint |
否 |
3.0.0 |
默认跳过标记为private的单元测试
示例
非触发
class FooTest: XCTestCase { func test1() {} internal func test2() {} public func test3() {} }internal class FooTest: XCTestCase { func test1() {} internal func test2() {} public func test3() {} }public class FooTest: XCTestCase { func test1() {} internal func test2() {} public func test3() {} }private class Foo: NSObject { func test1() {} internal func test2() {} public func test3() {} }private class Foo { func test1() {} internal func test2() {} public func test3() {} }public class FooTest: XCTestCase { func test1(param: Int) {} }
触发
private ↓class FooTest: XCTestCase { func test1() {} internal func test2() {} public func test3() {} private func test4() {} }class FooTest: XCTestCase { func test1() {} internal func test2() {} public func test3() {} private ↓func test4() {} }internal class FooTest: XCTestCase { func test1() {} internal func test2() {} public func test3() {} private ↓func test4() {} }public class FooTest: XCTestCase { func test1() {} internal func test2() {} public func test3() {} private ↓func test4() {} }
Prohibited Interface Builder
| 标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
prohibited_interface_builder |
否 |
否 |
lint |
否 |
3.0.0 |
避免使用Interface Builder生成视图
示例
非触发
class ViewController: UIViewController { var label: UILabel!}class ViewController: UIViewController { @objc func buttonTapped(_ sender: UIButton) {}}
触发
class ViewController: UIViewController { @IBOutlet ↓var label: UILabel!}class ViewController: UIViewController { @IBAction ↓func buttonTapped(_ sender: UIButton) {}}
Prohibited calls to super
| 标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
| prohibited_super_call |
否 |
否 |
lint |
否 |
3.0.0 |
有一些方法应该避免直接调用父类
示例
非触发
class VC: UIViewController { override func loadView() { }}class NSView { func updateLayer() { self.method1() }}public class FileProviderExtension: NSFileProviderExtension { override func providePlaceholder(at url: URL, completionHandler: @escaping (Error?) -> Void) { guard let identifier = persistentIdentifierForItem(at: url) else { completionHandler(NSFileProviderError(.noSuchItem)) return } }}
触发
class VC: UIViewController { override func loadView() {↓ super.loadView() }}class VC: NSFileProviderExtension { override func providePlaceholder(at url: URL, completionHandler: @escaping (Error?) -> Void) {↓ self.method1() super.providePlaceholder(at:url, completionHandler: completionHandler) }}class VC: NSView { override func updateLayer() {↓ self.method1() super.updateLayer() self.method2() }}class VC: NSView { override func updateLayer() {↓ defer { super.updateLayer() } }}