例如:
/// 1.1 编译通过
class Langke {
var chenlong: NSObjectProtocol?
}
/// 1.2 编译通过,但是触发swiftlint的 weak_delegate警告, 原因是变量名 myDelegate 中有 delegate 关键字,这属于名字滥用
class Langke {
var myDelegate: NSObjectProtocol?
}
/// 1.3 编译通过, 不会触发警告, 原因是在 var 关键字前面加了 weak
class Langke {
weak var myDelegate: NSObjectProtocol?
}
/// 2.1 编译通过,但是触发 weak_delegate 警告,原因是 scrollDelegate 中 Delegate 放在了最后, 被理解成了代理
class Langke {
var scrollDelegate: UIScrollViewDelegate?
}
/// 2.2 编译通过, 既然变量名被理解成了代理, 那为了类似防止循环引用, 应该加关键字 weak
class Langke {
weak var scrollDelegate: UIScrollViewDelegate?
}
/// 编译通过, 不会触发警告, 因为delegate放在了前面, 没有被理解成代理
class Langke {
var delegateScroll: UIScrollViewDelegate?
}
总结, 如果要使用swiftlint中的这个 weak_delegate 属性, 当你所定义的变量名被理解成某某代理时, 则需要加关键字 weak 来消除warning, 最好的方式是别乱取名字, 比如这样取名也是错误的:var delegate: String?, 这也会trigger swiftlint warning!
例如:
/// 触发void_return 和 属性46:redundant_void_return
func XingYun() -> () {
print("星云摁羊不厉害!")
}
// 触发void_return
let xingYun: () -> ()
/// 不触发 void_return, 但是会触发属性46: redundant_void_return
func XingYun() -> Void {
print("星云摁羊很厉害!")
}
// 不触发
let xingYun: () -> Void
总结, 返回为空全部统一用关键字 Void, 不要用 ()
例如:
/// 没有空格, nonTriggerWarning
override func viewDidLoad() {
super.viewDidLoad()
let aaa = 0
}
/// 有一行空格, nonTriggerWarning
override func viewDidLoad() {
super.viewDidLoad()
let aaa = 0
............................1
}
/// >=2行,就会触发警告
override func viewDidLoad() {
super.viewDidLoad()
let aaa = 0
.............................1
.............................2
}
这个推荐到项目中,垂直方向行间数最多为1, 这样可以保证code的饱满性、可读性
例如:
本例来自于官方文档
nonTriggeringExamples: [
"let myLet = 0",
"var myVar = 0",
"private let _myLet = 0",
"class Abc { static let MyLet = 0 }",
"let URL: NSURL? = nil",
"let XMLString: String? = nil"
],
triggeringExamples: [
"↓let MyLet = 0",
"↓let _myLet = 0", //这里我就郁闷了,这样命名不可以?
"private ↓let myLet_ = 0",
"↓let myExtremelyVeryVeryVeryVeryVeryVeryLongLet = 0",
"↓var myExtremelyVeryVeryVeryVeryVeryVeryLongVar = 0",
"private ↓let _myExtremelyVeryVeryVeryVeryVeryVeryLongLet = 0",
"↓let i = 0",
"↓var id = 0",
"private ↓let _i = 0"
]
属性5 : valid_ibinspectable 。 @IBInspectable在swiftlint中的使用需要注意, 第一必须是变量, 第二必须要有指定的类型,如果指定的类型是可选类型或者隐式类型,则目前官方只支持以下几种类型:
String, NSString, UIColor, NSColor, UIImage, NSImage.
例如:
/// 指定为变量var, 类型为String?和String!
@IBInspectable private var yyy: String?
@IBInspectable private var zzz: String!
/// 如果写成这样,编译能通过,但是会触发警告, 因为swiftlint暂不支持Int可选和隐式类型:
@IBInspectable private var dddl: Int!
@IBInspectable private var eeel: Int?
/// 如果指定的类型不是可选类型, 就应该初始化,否则系统不允许,会报错所在的类没有初始化
对:
@IBInspectable private var counts: Int = 0
系统报错:
@IBInspectable private var counts: Int
例如:
/// 不会触发warning
如果我新建一个工程,在ViewController.swift文件中, 开始的注释应该是:
//
// ViewController.swift
// SwiftLint
//
// Created by langke on 17/1/17.
// Copyright © 2017年 langke. All rights reserved.
//
改变一下变为:
//
// MyViewController.swift...................由于这里和外面的文件名不一样,所以触发warning(实际上在swift 3.0上测试这个属性暂时没有任何作用!!)
// SwiftLint
//
// Created by langke on 17/1/17.
// Copyright © 2017年 langke. All rights reserved................官方terminal表示,Copyright和Created没有对齐,也会触发warning!!!
//
例如:
/// 不会触发warning
class VC: UIViewController {
override func loadView() {
}
}
class NSView {
func updateLayer() {
self.method1()
}
}
/// 会触发warning
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()
}
}
属性10 : trailing_newline 。尾部新行,官方文档给出的description是:”Files should have single trailing newline”, 也就是说,文件(属性、方法)结束的的时候(“}”之前), 应该有一个空格新行,但这里要注意的是, 只是应该, 而不是必须, 所以这个属性也算是一个可选属性。官方给出的例子是这样的:
/// 空一行,不会触发警告
nonTriggeringExamples: [
"let a = 0\n"
],
/// 下面会触发警告
triggeringExamples: [
"let a = 0", /// 不空行,会触发警告(实际上,我试过,不会触发警告)
"let a = 0\n\n" /// 空两行, 会触发警告(实际上,我试过,会触发警告,但是触发的是vertical_whitespace警告而不是trailing_newline)
],
/// 说说这里,它要求改正为都空一行,虽然这样code看起来很轻松,但如果定义变量或常量太多,就太分散了(值得说的是,就算不空行也不会触发trailing_newline, 应该刚才也已经说了,这个属性只是说“应该”,而不是必须)
corrections: [
"let a = 0": "let a = 0\n",
"let b = 0\n\n": "let b = 0\n",
"let c = 0\n\n\n\n": "let c = 0\n"
]
既然如此,那这个属性什么时候回触发,具体的触发是在哪个地方呢?我自己测试了一下,这个方法的触发是在当前所在类的页面中的闭包最外面的尾部,也就是在“ }”的后面有一个空格新行,或者没有空格新行,如果 >= 2 则就会触发trailing_newline警告,比如:
}..............第40行
...............第41行空行
...............第42行空行-------->触发警告
这个属性是swiftlint的一个随意的属性,如果对代码要求style特别严格的那就用一下吧,其他几乎没有什么影响。
例如:
/// 下面这个例子不会触发警告,但是一旦其中有一个空行就会触发警告trailing_whitespace, 这和vertical_whitespace实质上有些冲突,vertical_whitespace要求两行code之间不超过1行,要么没有空行,要么只有1行,而trailing_whitespace要求没有空行!!!
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let a = 0
let b = 1
let c = 2
}
func chenlong() -> Void {
let a = 0
print(a)
}
}
这个属性强烈不推荐,代码之间不允许有一个空行,这会使程序的可读性差,所以希望禁用!!!
属性12 : line_length 。行的字符长度属性。这个强烈不推荐使用。官方的规定是超过120字符就给warning, 超过200个字符就直接报error!!!我们又不是写底层脚本的,所以建议这种方式禁用!!
属性13 : mark 。 标记方法或者属性。这个推荐使用, 可以统一方法标记的格式, 有利于review查找某个方法或者属性的时候更清晰。使用也非常简单: “MARK”前空一格,”MARK:”后空一格。
属性14 :todo 。TODO 和 FIXME 应该避免使用, 使用“notaTODO 和 notaFIXME”代替。另外, 和 MARK 标记不同的是, “notaTODO 和 notaFIXME”没有空格要求,但是我建议如果要使用这个 todo 属性, 尽量写成和 MARK 一样的规范。
属性15 : trailing_comma 。尾部逗号, 这个强烈推荐使用, 这个属性主要针对数组和字典最后一个元素。
例如:
/// 数组这样写是没有任何问题的, 但是最后一个元素3后面加了一个逗号“,”尽管这样不会报错,但是这会让程序的可读性变差
let ages = [1, 2, 3,]
let person = ["XingYun": 98, "JinGang": 128, "LangKe": 18,]
/// 使用swiftlint的trailing_comma规则后,就会报warning, 所以正确的写法不应该加上这个“,”
let ages = [1, 2, 3]
let person = ["XingYun": 98, "JinGang": 128, "LangKe": 18]
属性16 : trailing_semicolon 。末尾分号, 强烈推荐使用,尽管在变量或常量赋值之后加不加分号在swift中没有硬性的要求,但是为了使code style更swift化,所以尽量或者绝对不要加“;”。
属性17 : closing_brace 。封闭大括号, 大括号和括号中间不应该有任何的空格, 也就是 “{}”和“()”不能有空格, 这个属性推荐使用。
例如:
/// 没问题
({})
/// 有问题
( {})
/// 有问题
({} )
例如:
/// 必须注意的是,大括号左边“{”前面有一个空格,没有则会触发closure_end_indentation警告
langke.beginFishing {.........
.............
}
例如:
[].filter { content }
例如:
/// number 和 { 在同一行
let names = [1, 2, 3]
names.forEach { (number) in
print(number)
}
let names = [1, 2, 3]
names.map { number in
number + 1
}
/// 这样不行,违背 closure_parameter_position规则, 触发warning
let names = [1, 2, 3]
names.forEach {
(number) in
print(number)
}
let names = [1, 2, 3]
names.map {
number in
number + 1
}
属性21 : dynamic_inline 。动态–内联, 避免一起使用 dynamic 和 @inline(_ _always), 否则报 error
例如:
/// 正确的做法
class LangKe {
dynamic func myFunction() {
}
}
class LangKe {
@inline(__always) func myFunction() {
}
}
class LangKe {
@inline(never) dynamic func myFunction() {
}
}
/// 只要同时使用 dynamic 和 @inline(_ _always)都报错 error!!!
class LangKe {
@inline(__always) public dynamic func myFunction() {
}
}
这个属性这样做我也不知道什么原因, dynamic 和 @inline(__always) 不能同时使用, 不过既然它这样做,那必然有着它的道理, 所以这个属性也推荐使用。
例如:
/// 不会触发warning
[1, 2].map { _ in
return 3
}
/// 会触发warning
[1, 2].map { number in
return 3
}
例如官方的完整讲解是这样的:
public static let description = RuleDescription(
identifier: "compiler_protocol_init",
name: "Compiler Protocol Init",
description: "The initializers declared in compiler protocols such as `ExpressibleByArrayLiteral` " +
"shouldn't be called directly.",
/// 不会触发警告
nonTriggeringExamples: [
"let set: Set<Int> = [1, 2]\n",
"let set = Set(array)\n"
],
/// 会触发warning(实际上我在swift 3.0中测试过,根本就不会触发swiftlint的warning)
triggeringExamples: [
"let set = ↓Set(arrayLiteral: 1, 2)\n",
"let set = ↓Set.init(arrayLiteral: 1, 2)\n"
]
)
例如:
nonTriggeringExamples: [
"if condition {\n",
"if (a, b) == (0, 1) {\n",
"if (a || b) && (c || d) {\n",
"if (min...max).contains(value) {\n",
"if renderGif(data) {\n",
"renderGif(data)\n",
"for item in collection {\n",
"for (key, value) in dictionary {\n",
"for (index, value) in enumerate(array) {\n",
"for var index = 0; index < 42; index++ {\n",
"guard condition else {\n",
"while condition {\n",
"} while condition {\n",
"do { ; } while condition {\n",
"switch foo {\n"
],
triggeringExamples: [
"↓if (condition) {\n", /// 有 “()”, warning
"↓if(condition) {\n", /// if 和 条件之间没空格, 而且有 “()”
"↓if ((a || b) && (c || d)) {\n",
"↓if ((min...max).contains(value)) {\n",
"↓for (item in collection) {\n",
"↓for (var index = 0; index < 42; index++) {\n",
"↓for(item in collection) {\n",
"↓for(var index = 0; index < 42; index++) {\n",
"↓guard (condition) else {\n",
"↓while (condition) {\n",
"↓while(condition) {\n",
"} ↓while (condition) {\n",
"} ↓while(condition) {\n",
"do { ; } ↓while(condition) {\n",
"do { ; } ↓while (condition) {\n",
"↓switch (foo) {\n"
]
这个属性保证了代码的简洁性, 一般而言,在swift中的条件句中尽量不加括号, 直接写条件,除非特别需要! 另外注意条件前后的空格,一般都有一个空格,这个属性推荐使用。
属性25 : custom_rules 。 自定义规则。 这个属性可以通过提供正则表达式来创建自定义规则, 可选指定语法类型搭配, 安全、级别和要陈列的什么信息。 这个属性只要熟悉使用正则表达式的人使用,目前可以不适用。
属性26 : cyclomatic_complexity 。循环复杂度。函数体的复杂度应该要限制,这个属性主要约束条件句、循环句中的循环嵌套问题, 当嵌套太多的循环时,则会触发swiftlint中的warning和error,当达到10个循环嵌套时就会报warning,达到20个循环嵌套时就会报error,强烈推荐这个属性。嵌套太多,可读性差!
例如:
// warning or error
func LangKe() -> Void {
if true {
if false {
guard true else { return }
if false {
...............循环复杂
}
}
}
}
例如:
/// swiftlint不喜欢这样使用
let number = "long"
if number.characters.count == 0 {
print("为空")
} else {
print("不为空")
}
/// swiftlint更喜欢这种正式风格
if number.isEmpty {
print("为空")
} else {
print("不为空")
}
这个属性推荐使用, 尽管我在swift 3.0上测试并没有触发警告, 但是这是一个比较好的约束, 可以规范开发者对语法的使用, 同时更符合swift的风格。
例如:
/// 没有空格,触发warning
let number = "long"
if number.isEmpty {
print("为空")
}else {.............................注意这里
print("不为空")
}
/// 这里也会触发warning, 因为else if换行了
let number = "long"
if number.isEmpty {
print("为空")
}
else if number.contains("long") {............................注意这里
print("不为空")
} else {
print("s")
}
/// 正确的写法
let number = "long"
if number.isEmpty {
print("为空")
} else {
print("不为空")
}
例如:
/// trigger warning
let number = "long"
if number.isEmpty {
print("为空")
} else{............................注意这里
print("s")
}
/// nonTrigger warning
let number = "long"
if number.isEmpty {
print("为空")
} else {
print("s")
}
当然,如果有小括号的时候, 就不要有空格, 比如:({ })——->这是属性 closing_brace的规则。
例如:
/// 01 不会触发warning
let abc: () -> Void
func foo(completion: () -> Void) {
}
/// 02 直接报错
let bcd: Void -> Void
func foo(completion: Void -> Void) {
}
/// 03 在终端上查看swiftlint rules, 应该只会报warning, 但是直接报error, 然后系统提示 “02”应该改为:
let bcd: (Void) -> Void
func foo(completion: (Void) -> Void) {
}
例如:
/// 触发warning
[1, 2].map() { $0 + 1 }
[1, 2].map( ) { $0 + 1 }
[1, 2].map() { number in\n number + 1 \n}
[1, 2].map( ) { number in\n number + 1 \n}
/// 不会触发warning
[1, 2].map { $0 + 1 }
[1, 2].map { $0 + 1 }
[1, 2].map { number in\n number + 1 \n}
[1, 2].map { number in\n number + 1 \n}
属性32 : file_length 。 文件长度。 这个属性我在swift 3.0上测试并没有起到任何作用, 官方给的内容是:
identifier: "file_length",
name: "File Line Length",
description: "Files should not span too many lines.",
nonTriggeringExamples: [
repeatElement("//\n", count: 400).joined()
],
triggeringExamples: [
repeatElement("//\n", count: 401).joined()
]
属性33 : force_cast 。强制转换, 强制转换应该被避免,否则直接报 error。
例如:
/// 正确转换
NSNumber() as? Int
/// 直接报错, 不要强制转换
NSNumber() as! Int
这个force_cast强制转换属性, 至于是否使用还有待商榷。
例如:
/// 这样写是可以的,不会触发 error
func myFunction() throws {
}
do {
try myFunction()
} catch {
}
/// 这样直接触发 error
func myFunction() throws {
}
try! myFunction()
属性35 : function_body_length 。函数体长度, 函数体不应该跨越太多行, 超过40行给warning, 超过100行直接报错。推荐使用。
属性36 : function_parameter_count 。函数参数个数, 函数参数数量(init方法除外)应该少点, 不要太多,swiftlint规定函数参数数量超过5个给warning, 超过8个直接报error。这个属性推荐使用, 由于简单就不举例了。注:function_parameter_count: error 这样并不能改变它的警告或错误,该属性不允许修改,但是可以禁用
属性37 : imlicit_getter 。隐式getter方法。计算的只读属性应该避免使用 get 关键字, 也就是说, 如果只是为了只读, 那就可以直接返回就行, 而不用写 get 关键字, 如果既可读又可写,那就可以写。
例如:
/// 报warning
var foo: Int {
get{
return 20
}
}
/// 应该写成这样(直接写)
var foo: Int {
return 20
}
总结: 也就是说, 如果只有 get 一个关键字, 就不能写 get, 如果除 get关键字外,还有 set, 那就可以写 get , 再简化说:只读计算属性省略get, 可读可写不省略get, 当然, 这只针对 计算只读属性 的时候。
例如:
/// 这样不推荐使用
CGRectGetWidth(someView.frame)
/// 推荐使用下面的形式
rect.width
rect.height
rect.minX
rect.midX
rect...................
/// 我在swift 3.0, Xcode 8.1中作如下尝试, 编译直接失败,报错:CGRectGetMaxX has been replaced by property CGRect.maxX
let myLabel = UILabel(frame: CGRect(x: CGRectGetMaxX(myView.frame), y: 22, width: 33, height: 44))
/// 根据**系统**提示信息改正如下
let myLabel = UILabel(frame: CGRect(x: myView.frame.maxX, y: 22, width: 33, height: 44))
总结:swiftlint已经将这个属性紧靠系统原生API, OC带过来的CG几何函数很多已被弃用, 这个属性强烈推荐使用。
例如:
/// 规范的写法,不会触发warning
CGPoint.zero
/// 不规范的写法, 会触发warning
CGPointZero
CGRectZero
推荐使用这样的语法, 而且swift 3.0已经开始强制使用这种规范的点语法了。
例如:
/// swift语法, swift 3.0已经强制使用了,所以尽管swiftlint不定制这种规则, 系统也会强制规定使用
CGPoint(x: 10, y: 20)
/// 错误的构造器语法
CGPointMake(10, 20)
例如:
/// 正确
view.width/height/minX
/// 错误
NSWidth(view.frame)
例如:
let sum = 1 + 2
let mutiplier = 2 * 3
let devide = 10 /2
例如:
/// 正确的写法
override func viewWillAppear(_ animated: Bool) {
/// 注意重写父类方法
super.viewWillAppear(animated)
}
*属性44 : private_outlet 。私人输出, IBOutlet 这个属性应该是私人的, 为了避免泄露UIKit到更高层, 官方:”IBOutlets should be private to avoid leaking UIKit to higher layers.”
例如:
/// swiftlint 建议当使用 IBOutlet属性的时候, 在其后面加一个 private 表示私有的, 但是我在swift 3.0上测试, 尽管使用了swiftlint, 但并没有起到任何作用
// swiftlint建议不能下面这样写
class LangKe {
@IBOutlet var label: UILabel?
}
/// swiftlint 建议这样写
class LangKe {
@IBOutlet private var label: UILabel?
}
例如:
// warning 1
enum Numbers: String {
case one = "one"
case two
}
enum Numbers: String {
case one
case two = "two"
}
enum Numbers: String {
case one = "one"
case two = "two"
}
当然, 只要有一个case 的成员名和枚举值不相等, 那就没有warning, 比如:
enum Numbers: String {
case one = "ONE"
case two = "two"
}
例如:
/// 这个属性要求这样写, 返回值为空省略
func XingYun() {
print("摁��")
}
/// 这个属性要求别这样写,否则会有warning(但是我在swift 3.0上测试并没有触发warning)
func XingYun() -> Void {
print("摁��")
}
注意: 在属性2中, void_return中, 喜欢 “-> Void”胜过于 “-> ()”, 这并不代表使用 -> Void 很好, 我觉得省略比较好, 所以这个属性推荐使用 。
例如:
/// 报warning
func XingYun() ->Int {
print("摁牛")
return 22
}
/// 不报warning ------> 推荐使用
func XingYun() -> Int {
print("摁牛")
return 22
}
/// swiftlint 不反对“->”和“type”之间换行, 不报warning ------> 但是不推荐使用
func XingYun() ->
Int {
print("摁牛")
return 22
}
属性48 : type_name 。类型名, 类型名应该只包含字母数字字符, 并且以大写字母开头,长度在3-40个字符。这个属性没什么好说的,强烈推荐使用。
属性49 : syntactic_sugar 。语法糖, swiftlint推荐使用速记语法糖, 例如 [Int] 代替 Array, 强烈建议推荐使用。
例如:
/// 触发warning
let myArray: Array<Int> = [1, 2, 3]
print(myArray)
/// 正确写法,不会触发warning
let myArray: [Int] = [1, 2, 3]
print(myArray)
例如:
/// swiftlint表示会触发warning
switch type {
case .value1: print("1")...................在同一行错
case .value2: print("2")...................在同一行错
default: print("3")...................在同一行错
}
/// 不会触发warning
switch type {
case .value1:
print("1")
case .value2:
print("2")
default:
print("3")
}
总结来说,就是要求在switch语句中,case要求换行。这个属性强烈推荐使用。
例如:
/// 不推荐使用(在swift 3.0上并不会触发warning或error)
var value = 4
value = value / 2
print(value)
/// 推荐使用
var value = 4
value /= 2
print(value)
例如:
identifier: "sorted_imports",
name: "Sorted Imports",
description: "Imports should be sorted.",
nonTriggeringExamples: [
"import AAA\nimport BBB\nimport CCC\nimport DDD"
],
triggeringExamples: [
"import AAA\nimport ZZZ\nimport ↓BBB\nimport CCC"
]
这个属性不推荐使用,导入的时候没必要按顺序来导入,一般来说,在项目中你也不会导入太多的类,特别是在swift语言中。
例如:
/// 推荐使用这种形式
let xxx = 1_000_000_000.000_1
print(xxx)
/// 不推荐使用这种形式(在swift 3.0上无warning,也就是说这个属性暂时并未起到任何作用)
let xxx = 1000000000.0001
print(xxx)
例如:
/// 会触发warning
(person.voice).toNot(equal("Hello world")) // 人的声音不等于“Hello world”
10.to(beGreaterThan(5)) // 10比5大
99.to(beLessThan(100)) // 99比100小
// 改为以下
(person.voice) != "Hello world" // 人的声音不等于“Hello world”
10 > 5 // 10比5大
99 < 100 // 99比100小
例如:
/// no warning
func langke() {
func xingyun() {
func caicai() {
func xiaohui() {
func jingang() {
}
}
}
}
}
/// trigger warning
func langke() {
func xingyun() {
func caicai() {
func xiaohui() {
func jingang() {
//开始触发警告
func beginTriggerWarning() {
}
}
}
}
}
}
例如:
/// 触发warning(实际上在swift 3.0上并没有触发)
var myVar: Int? = nil
var myVar: Optional<Int> = nil
var myVar: Int?=nil
var myVar: Optional<Int>=nil
/// 正确的写法
var myVar: Int?
var myVar: Optional<Int>
var myVar: Int?
var myVar: Optional<Int>
这个属性可以使用,虽然暂时在terminal上没有,但后续应该会集成到相应的swiftlint环境中。
例如:
/// 不会触发warning
//
// ViewController.swift
// SwiftLint
//
// Created by langke on 17/1/12.
// Copyright © 2017年 langke. All rights reserved.
//
/// 会触发warning
//..................................这里有一个空格
// ViewController.swift
// SwiftLint
//
// Created by langke on 17/1/12.
// Copyright © 2017年 langke. All rights reserved.
//
/// 会触发warning
......................................这里是一个空行
//
// ViewController.swift
// SwiftLint
//
// Created by langke on 17/1/12.
// Copyright © 2017年 langke. All rights reserved.
//
例如:
nonTriggeringExamples: [
func validateFunction(_ file: File, kind: SwiftDeclarationKind,
dictionary: [String: SourceKitRepresentable]) { }
func validateFunction(_ file: File, kind: SwiftDeclarationKind,
dictionary: [String: SourceKitRepresentable]) -> [StyleViolation]
func validateFunction(_ file: File, kind: SwiftDeclarationKind,
dictionary: [String: SourceKitRepresentable])
-> [StyleViolation]
func validateFunction(
_ file: File, kind: SwiftDeclarationKind,
dictionary: [String: SourceKitRepresentable]) -> [StyleViolation]
func validateFunction(\n" +
_ file: File, kind: SwiftDeclarationKind,\n" +
dictionary: [String: SourceKitRepresentable]
) -> [StyleViolation]\n",
]
triggeringExamples: [
func validateFunction(_ file: File, kind: SwiftDeclarationKind,
dictionary: [String: SourceKitRepresentable]) { }
func validateFunction(_ file: File, kind: SwiftDeclarationKind,
dictionary: [String: SourceKitRepresentable]) { }
func validateFunction(_ file: File,
kind: SwiftDeclarationKind,
dictionary: [String: SourceKitRepresentable]) { }
]
例如:
/// swiftlint 不推荐的写法, 否则会触发warning(但是在swift 3.0上测试并不会触发任何warning)
if true { return }
guard true else { return }
/// swiftlint 推荐的写法
if true {
return
}
guard true else {
return
}
例如:
/// 将触发warning
navigationController!.pushViewController(myViewController, animated: true)
let url = NSURL(string: "http://www.baidu.com")!
print(url)
return cell!
/// 不会触发warning
navigationController?.pushViewController(myViewController, animated: true)
例如:
/// 使用显式初始化则触发warning(但实际上我在swift 3.0上测试并没有发现触发warning!!!)
[88].flatMap{ String↓.init($0) }
UITableView.init()
///正确的写法
[88].flatMap{ String($0) }
UITableView()
例如:
不会触发warning
// public, documented using /// docs
/// docs
public func langke() {}
// public, documented using /** docs */
/** docs */
public func langke() {}
// internal (implicit), undocumented
func langke() {}
// internal (explicit) / private, undocumented
internal/private func langke() {}
1、协议成员被文件标记、注释, 但是继承的成员就不用
/// docs
public protocol A {
/// docs
var b: Int { get }
}
/// docs
public struct C: A {
public let b: Int
}
2、本地定义的父类成员被文件标记, 但是子类成员就不用
/// docs
public class A {
/// docs
public func b() {}
}
/// docs
public class B: A {
override public func b() {}
}
3、外部定义的父类成员被文件标记, 但是子类成员就不用
import Foundation
/// docs
public class B: NSObject {
// no docs
override public var description: String { fatalError() }
}
</br>
</br>
会触发warning(实际上在swift 3.0目前并不会触发!!)
// public , undocumented
public func langke() {}
// public , undocumented
// regular comment
public func a() {}
// public, undocumented
/* regular comment */
public func a() {}
// protocol member and inherited member are both undocumented
/// docs
public protocol A {
// no docs
var b: Int { get }
}
/// docs
public struct C: A {
public let b: Int
}
属性63 : valid_docs 。有效文件 。 文件声明应该有效 。这个属性和属性62有冲突, 而且重复, 官网文档写得有问题。另外在swift 3.0上测试并不会发生warning。暂时不举例,这个属性禁用!!!后期等官方完善之后再追加。
属性64 : type_body_length 。类型体长度。类型体长度不应该跨越太多行, 超过200行给warning,超过350行给error。一般是大括号或者括号内, 比如定义一个enum或struct。
例如:
class langke {
这里有201行,warning!!!
}
例如:
/// 触发warning
var myVar: Int? = nil
myVar↓ ?? nil
var myVar: Int? = nil
myVar↓??nil
//不会触发warning
var myVar: Int?
myVar ?? 0
var myVar: Int? = nil
let langke = myVar
例如:
/// 官方给出的例子, 非触发warning
"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)"
例如:
private ↓class FooTest: XCTestCase { ...............继承于测试用例类XCTestCase, 被标记为private,所以触发warning
func test1() {}
internal func test2() {}
public func test3() {}
private func test4() {}.......另外注意这里,上面既然不会通过,那显然这里也不会通过,根本不会走这个func
}
internal class FooTest: XCTestCase { ......开始通过测试,因为没有被标记为private
func test1() {}
internal func test2() {}
public func test3() {}
private ↓func test4() {}................不通过,因为被标记为private
}
public class FooTest: XCTestCase { ..........通过
func test1() {}
internal func test2() {}
public func test3() {}
private ↓func test4() {}.................不通过,因为被标记成private
}
class FooTest: XCTestCase { ..........通过
func test1() {}
internal func test2() {}
public func test3() {}
private ↓func test4() {}.................不通过,因为被标记成private
}
例如:
description: "Prefer using `.first(where:)` over `.filter { }.first` in collections.",
nonTriggeringExamples: [
"kinds.filter(excludingKinds.contains).isEmpty && kinds.first == .identifier\n",
"myList.first(where: { $0 % 2 == 0 })\n",
"matchPattern(pattern).filter { $0.first == .identifier }\n"
],
triggeringExamples: [
"↓myList.filter { $0 % 2 == 0 }.first\n",
"↓myList.filter({ $0 % 2 == 0 }).first\n",
"↓myList.map { $0 + 1 }.filter({ $0 % 2 == 0 }).first\n",
"↓myList.map { $0 + 1 }.filter({ $0 % 2 == 0 }).first?.something()\n",
"↓myList.filter(someFunction).first\n"
]
例如:
// 触发警告
class Something: Equatable {
var text: String?
// "=="和“(lhs: Something, rhs: Something)”之间应该有一个空格
static func ==(lhs: Something, rhs: Something) -> Bool {
return lhs.text == rhs.text
}
}
例如:
/// 这样会触发警告
class VCd: UIViewController {
override func viewWillAppear(_ animated: Bool) {
//没有调用父类
}
}
/// 不会触发警告
class VCd: UIViewController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}
}
持续更新中…..