Swiftlint代码规范属性说明
2017-02-15 11:01
429 查看
SwiftLint代码规范属性详细说明
属性1 : weak_delegate 。 代理应该写成weak类型(弱代理)来避免循环引用例如:
/// 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!
属性2 : void_return 。 返回值为空,我们一般推荐用 ” -> Void “, 而不是 ” -> () “, 主要针对全局变量/常量闭包:如let xingYun: () -> () = {}
例如:
/// 触发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, 不要用 ()
属性3 : vertical_whitespace 。 垂直方向上的空格行,限制为一行(注释除外),
例如:
/// 没有空格, 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的饱满性、可读性
属性4 : variable_name 。 变量名应该只包含字符数字字符, 并且只能以小写字母开头或者应该只包含大写字母。此外,当变量名被声明为static(静态)变量时或者immutable不可变的时候,这时或许可以以一个大写字母开头。最后,变量名不应该太长或者太短(应该在3-40个字符间,否则会触发警告!!!)。注意:目前变量名只适用于自己写的方法的参数和自己写的class中的全局常量或变量, 对于系统自带的方法里面和自己写的方法里面没有作用
例如:
本例来自于官方文档 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
属性6 : file_header 。文件头。文件应该有一致的注释, 主要看下面例子:
例如:
/// 不会触发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!!! //
属性7 : prohibited_super_call 。被禁止的父类响应。一些方法不应该响应父类。
例如:
/// 不会触发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() } }
属性8 : colon 。冒号的使用, swiftlint的这个colon属性规则很简单,要求“ :”紧靠所定义的常量或变量等,必须没有空格,与所指定的类型之间必须只有一个空格,多一个或少一个都不行,如果是用在Dictionary中,则要求紧靠Key,与Value之间必须有且仅有一个空格。这个规则我觉得应该强制推荐使用。由于简单,就不举例子了。
属性9 : comma 。逗号规则, 冒号的使用可以使代码看起来不让人感到那么疲惫、头疼, 使用只要遵循“前不离身后退一步”就行了,这个也强制推荐使用。
属性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特别严格的那就用一下吧,其他几乎没有什么影响。
属性11 : trailing_whitespace 。 尾部空白行,这个强烈不推荐使用。看下面例子:
例如:
/// 下面这个例子不会触发警告,但是一旦其中有一个空行就会触发警告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 。封闭大括号, 大括号和括号中间不应该有任何的空格, 也就是 “{}”和“()”不能有空格, 这个属性推荐使用。
例如:
/// 没问题 ({}) /// 有问题 ( {}) /// 有问题 ({} )
属性18 : closure_end_indentation 。 闭包结束缩进, 什么意思呢?就是 大括号(一般是方法)上下对齐的问题,这样使code看起来更加整洁。
例如:
/// 必须注意的是,大括号左边“{”前面有一个空格,没有则会触发closure_end_indentation警告 langke.beginFishing {......... ............. }
属性19 : closure_spacing 。 闭包空格,闭包表达式在每个大括号内应该有一个单独的空格, 要注意的是这里指的是“应该”, 我自己测试了一下,在swift 3.0并没有报warning, 所以这也不是强制性要求,但这个推荐使用。
例如:
[].filter { content }
属性20 : closure_parameter_position 。 闭包参数位置, 闭包参数应该和大括号左边在同一行, 推荐使用。
例如:
/// 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) 不能同时使用, 不过既然它这样做,那必然有着它的道理, 所以这个属性也推荐使用。
属性22 : unused_closure_parameter 。 不使用的闭包参数, swiftlint建议最好不使用的闭包参数使用 “_”代替。推荐使用。
例如:
/// 不会触发warning [1, 2].map { _ in return 3 } /// 会触发warning [1, 2].map { number in return 3 }
属性23 : compiler_protocol_init 。 编译器协议初始化, 属性在swiftlint的有着例子,但是我在swift 3.0中运行并没有起到任何作用, 所以这个属性是否需要使用待定。不过仔细在 terminal上使用 swiftlint rules 查看了一下,并没有发现compiler_protocol_init属性,也许是新加的属性,还没有集成到new version上?
例如官方的完整讲解是这样的:
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" ] )
属性24 : control_statement 。 控制语句, if、for、while、do语句不应该将 条件 写在 圆括号 中, 另外注意条件出的空格。
例如:
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 { ...............循环复杂 } } } }
属性27 : empty_count 。比起检查 count 是否为 0 , swiftlint上说更喜欢检测 “isEmpty”。
例如:
/// swiftlint不喜欢这样使用 let number = "long" if number.characters.count == 0 { print("为空") } else { print("不为空") } /// swiftlint更喜欢这种正式风格 if number.isEmpty { print("为空") } else { print("不为空") }
这个属性推荐使用, 尽管我在swift 3.0上测试并没有触发警告, 但是这是一个比较好的约束, 可以规范开发者对语法的使用, 同时更符合swift的风格。
属性28 : statement_position 。 陈述句位置, 这里主要指的是 else 和 catch 前面要加一个空格, 也不能大于1个空格, 否则就会触发警告。
例如:
/// 没有空格,触发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("不为空") }
属性29 : opening_brace 。在声明的时候, 左大括号应该有一个空格,并且在同一行,推荐使用。
例如:
/// 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的规则。
属性30 : empty_parameters 。为空参数。swiftlint更喜欢 “()->” 比起 “Void ->”
例如:
/// 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) { }
属性31 : empty_parentheses_with_trailing_closure 。尾随闭包中使用空的圆括号, 在使用尾随闭包的时候, 应该尽量避免使用空的圆括号, 是否使用待定。
例如:
/// 触发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强制转换属性, 至于是否使用还有待商榷。
属性34 : force_try 。 强制尝试, swiftlint禁止使用强制尝试, 否则直接报 error。
例如:
/// 这样写是可以的,不会触发 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, 当然, 这只针对 计算只读属性 的时候。
属性38 : legacy_cggeometry_functions 。遗留的CG几何函数, 当获取某个视图的宽、高、最小X、最大X值等等, swiftlint推荐使用swift的标准语法, 尽量不要使用从Objective-C中的遗留版本, 尽量语法swift化。
例如:
/// 这样不推荐使用 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几何函数很多已被弃用, 这个属性强烈推荐使用。
属性39 : legacy_constant 。遗留版本常数, 和属性38(legacy_cggeometry_functions)一样, 结构范围常数尽量分开、明确、具体, 不要使用OC的遗留整体常数。
例如:
/// 规范的写法,不会触发warning CGPoint.zero /// 不规范的写法, 会触发warning CGPointZero CGRectZero
推荐使用这样的语法, 而且swift 3.0已经开始强制使用这种规范的点语法了。
属性40 : legacy_constructor 。遗留版本构造器, swiftlint要求系统自带构造器, 使用swift语法化, 不要使用OC版本的构造器。
例如:
/// swift语法, swift 3.0已经强制使用了,所以尽管swiftlint不定制这种规则, 系统也会强制规定使用 CGPoint(x: 10, y: 20) /// 错误的构造器语法 CGPointMake(10, 20)
属性41 : legacy_nsgeometry_functions 。 ns类几何函数, 和前面的几个属性一样, 使用swift点语法函数, 不使用以前的版本。
例如:
/// 正确 view.width/height/minX /// 错误 NSWidth(view.frame)
属性42 : operator_usage_whitespace 。操作符使用规则, 操作符两边应该有空格。比如 “+” “-” “??”
例如:
let sum = 1 + 2 let mutiplier = 2 * 3 let devide = 10 /2
属性43 : overridden_super_call 。 重写父类方法, 强烈推荐使用。
例如:
/// 正确的写法 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? }
属性45 : redundant_string_enum_value 。 多余的字符串枚举值, 在定义字符串枚举的时候, 不要让枚举值和枚举成员名相等
例如:
// 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" }
属性46 : redundant_void_return 。多余的返回值为空, 在函数声明的时候,返回值为空是多余的。定义常量或者变量的时候可以。
例如:
/// 这个属性要求这样写, 返回值为空省略 func XingYun() { print("摁��") } /// 这个属性要求别这样写,否则会有warning(但是我在swift 3.0上测试并没有触发warning) func XingYun() -> Void { print("摁��") } 注意: 在属性2中, void_return中, 喜欢 “-> Void”胜过于 “-> ()”, 这并不代表使用 -> Void 很好, 我觉得省略比较好, 所以这个属性推荐使用 。
属性47 : return_arrow_whitespace 。 返回箭头空格, swiftlint推荐返回箭头和返回类型应该被空格分开, 也就是 “->”和 type 之间有空格。
例如:
/// 报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)
属性50 : switch_case_on_newline 。switch语句新行, 在switch语法里, case应该总是在一个新行上面。 看看例子就知道了。
例如:
/// 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要求换行。这个属性强烈推荐使用。
属性51 : shorthand_operator 。速记操作符, 什么是速记操作符呢? 在swiftlint中, 就是我们常用的简洁操作运算符,比如:+= , -=, *=, /= 等等。在swiftlint中,在做一些赋值操作的时候,推荐使用简短操作符。
例如:
/// 不推荐使用(在swift 3.0上并不会触发warning或error) var value = 4 value = value / 2 print(value) /// 推荐使用 var value = 4 value /= 2 print(value)
属性52 : sorted_imports 。 分类/有序导入。 这个属性有些奇怪, 要求导入的时候导入的类要按顺序导入。另外,这个属性暂时在terminal上使用swiftlint rules是没有的。直接看官方给的示例:
例如:
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语言中。
属性53 : number_separator 。数字分割线。当在大量的小数中, 应该使用下划线来作为千分位分割线。推荐使用。
例如:
/// 推荐使用这种形式 let xxx = 1_000_000_000.000_1 print(xxx) /// 不推荐使用这种形式(在swift 3.0上无warning,也就是说这个属性暂时并未起到任何作用) let xxx = 1000000000.0001 print(xxx)
属性54 : nimble_operator 。 敏捷操作符。和自由匹配函数相比, 更喜欢敏捷操作符, 比如:>=、 ==、 <=、 <等等。
例如:
/// 会触发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小
属性55 : nesting 。嵌套。类型嵌套至多一级结构, 函数语句嵌套至多五级结构。
例如:
/// 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() { } } } } } }
属性56 : redundant_optional_initialization。 多余的可选初始化, 可选变量初始化为 nil 时是多余的,官方描述:description: “Initializing an optional variable with nil is redundant.”。
例如:
/// 触发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环境中。
属性57 : leading_whitespace 。文件开始不应该有空格或者换行, 否则就会触发warning
例如:
/// 不会触发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. //
属性58 : vertical_parameter_alignment 。垂直方向上的参数对齐。当函数参数有多行的时候, 函数参数在垂直方向上应该对齐(参数换行的时候左边对齐)。这个属性在 terminal 上使用 swiftlint rules查看目前是没有的。
例如:
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]) { } ]
属性59 : conditional_returns_on_newline 。条件返回语句应该在新的一行。 当有条件返回的时候应该换行返回,而不是在同一行。这个属性强烈推荐。
例如:
/// swiftlint 不推荐的写法, 否则会触发warning(但是在swift 3.0上测试并不会触发任何warning) if true { return } guard true else { return } /// swiftlint 推荐的写法 if true { return } guard true else { return }
属性60 : force_unwrapping 。 强制解包/拆包。我们知道,当一个类型是可选类型的时候,当我们获取值时,需要强制解包(也叫隐式解包), 通常我们是在一个变量或者所需要的常量、类型等后面加一个“ !”, 然而,swiftlint建议强制解包应该要避免, 否则将给予warning。
例如:
/// 将触发warning navigationController!.pushViewController(myViewController, animated: true) let url = NSURL(string: "http://www.baidu.com")! print(url) return cell! /// 不会触发warning navigationController?.pushViewController(myViewController, animated: true)
属性61 : explicit_init 。显式初始化。显式初始应该避免。
例如:
/// 使用显式初始化则触发warning(但实际上我在swift 3.0上测试并没有发现触发warning!!!) [88].flatMap{ String↓.init($0) } UITableView.init() ///正确的写法 [88].flatMap{ String($0) } UITableView()
属性62 : missing_docs 。缺失说明注释, 官方解释:”Public declarations should be documented.”, 公共声明应该被注释/标记。 在函数声明的时候, 一般情况下, 带public关键字的函数的注释只能用 “///”和 “/* /”来注释, 如果不带public关键字的函数只能用 “//”和 “/* */” 。这个属性应该禁用,没必要!!!
例如:
不会触发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!!! }
属性65 : redundant_nil_coalescing 。多余的为空联合操作符。为空联合操作符用来判断左边是否为空,伴随nil的为空操作符在右边是多余的。
例如:
/// 触发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
属性66 : object_literal 。对象字面量, swiftlint表示比起图片和颜色初始化,更喜欢对象字面量。因为swift初始化可以用表情,图片,颜色等,这不符合项目中的一些习惯用法。目前在terminal上使用swiftlint rules查看并没有这个属性。那自然现在在swift 3.0上测试并没有起到任何作用。但是这个属性推荐使用。
例如:
/// 官方给出的例子, 非触发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)"
属性67 : private_unit_test 。私有的单元测试。被标记为private的单元测试不会被测试工具XCTest运行, 也就是说,被标记为private的单元测试会被静态跳过。
例如:
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 }
属性68 : frist_where 。直接看下面官方解释和示例, 这个属性没有测试。
例如:
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" ]
属性69 : operator_whitespace 。空格/空白操作符。当定义空格操作符的时候,被定义的名字或类型两边应该各有一个单行空格操作符。推荐使用。
例如:
// 触发警告 class Something: Equatable { var text: String? // "=="和“(lhs: Something, rhs: Something)”之间应该有一个空格 static func ==(lhs: Something, rhs: Something) -> Bool { return lhs.text == rhs.text } }
属性70 : overridden_super_call。一些复写方法应该总是调用父类
例如:
/// 这样会触发警告 class VCd: UIViewController { override func viewWillAppear(_ animated: Bool) { //没有调用父类 } } /// 不会触发警告 class VCd: UIViewController { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) } }
持续更新中…..
相关文章推荐
- SwiftLint代码规范属性说明(二)
- SwiftLint代码规范属性说明(三)
- SwiftLint代码规范属性说明(一)
- 关于我上传的代码规范的说明
- HTML代码中标签的全部属性 中文注释说明
- 团队开发之:代码规范说明
- 规范 6.2 不要使用危险的许可与目标组合 说明: 有些许可和目标的组合会导致权限过大, 而这些权限本不应该被赋予。另外有些权限 必须只赋予给特定的代码。 1. 不要将AllPermission许可赋
- PowerDesigner XML 文件直接生成 VB 实体(包含属性说明)、ibatisNet 代码
- Object-C 声明属性为什么用下划线,代码规范和编程风格
- Object-C 声明属性为什么用下划线,代码规范和编程风格
- CSS代码中的important属性的使用和说明:
- PHPDocumentor代码注释规范说明
- PHPDocumentor的代码注释规范说明
- Android笔记:代码规范(新浪微博sdk示例工程附带的说明)
- PHPDocumentor代码注释规范说明
- HTML代码中标签的全部属性 中文注释说明
- PHPDocumentor的代码注释规范说明
- RSS介绍、RSS 2.0规范说明和示例代码
- SwiftLint 代码规范安装使用(demo下载)
- Vue组件中prop属性使用说明实例代码详解