-
PascalCase使用驼峰命名规则和描述性的名称来定义类、方法、变量等。类名和模块中的常量的第一个字母应该大写,而方法名和变量应该开始用小写字母。这一点跟OC一样的命名规则
推荐
class UserInfo{
var userName: String
var userAge: String
}
-
camelCase使用小骆驼拼写法 (首字母小写) 为函数,方法,变量,常量,参数等命名。
-
在实际使用过程中,对于函数和int函数,需对所有参数进行命名,除非上下文非常清清楚,是函数调节具有可读性。 例子:
funcupdateUserInfo(userName: String, userAge: Int)
-
首字母缩略词在命名中一般来说都是全部大写,例外的情形是如果首字母缩略词是一个命名的开始部分,而这个命名需要小写字母作为开头,这种情形下首字母缩略词全部小写。
// "HTML" is at the start of a constant name, so we use lowercase "html"
let htmlBodyContent: String = "<p>Hello, World!</p>"
// Prefer using ID to Idlet profileID: Int = 1
// Prefer URLFinder to UrlFinder
使用前缀 k 大骆驼命名法 为所有非单例的静态常量命名。
不要缩写,简写命名,或用单个字母命名。
// 推荐
class RoundAnimatingButton: UIButton {
let animationDuration: NSTimeInterval
func startAnimating() {
let firstSubview = subviews.first
}
}
// 不推荐
class RoundAnimating: UIButton {
let aniDur: NSTimeInterval
func srtAnmating() {
let v = subviews.first
}
}
格式在团队开发过程中,代码格式非常重要,保持良好的代码编写习惯。
-
每个文件结尾后又空白行。
-
每一行都不能以空白作为结尾。
-
左边的大括号不用另起一行。
class PPClass {
func ppMethod(){
if x == y {
/* .... */
} else if x == z {
/* .... */
} else {
/* .... */
}
}
/* .... */
}
-
在写一个变量、一个字典、一个函数等等的时候,在:在不加空格,在:后面加空格。
// 指定类型
let age: Int = 27
// 字典语法(注意这里是向左对齐而不是分号对齐)
let userInfo: [String: AnyObject] = [
"userName": "Austin",
"age": 27]
// 声明函数
func myFunction<t, u: someprotocol where t.relatedtype == u>(firstArgument: U, secondArgument: T) {
/* ... */
}
// 调用函数
someFunction(someArgument: "Austin")
// 父类
class CustomViewController: UIViewController {
/* ... */
}
// 协议
extension PirateViewController: UITableViewDataSource {
/* ... */
}</t, u: someprotocol where t.relatedtype == u>
-
基本上,要在,后面加空格
let array = [1, 2, 3, 4, 5]
-
在做二元运算符的时候前后都要需要添加空格,有时候可能读不出来。
let sum = 20 (30 / 2) * 3
if 2 3 == 5 {
fatalError("The universe is broken.")
}
func pancake() -> Pancake {
/* ... */
}
-
当调用的函数有多个参数时,每一个参数另起一行,并比函数名多一个缩进。
someFunction(
first: "Hello, I am Austin",
second: resultFromSomeFunction()
third: someOtherLocalVariable)
-
如果要进行多条件一起判断,尽量使用本地变量或者其他方式,增强代码可读性
// 推荐
let firstCondition = x == firstReallyReallyLongPredicateFunction()
let secondCondition = y == secondReallyReallyLongPredicateFunction()
let thirdCondition = z == thirdReallyReallyLongPredicateFunction()
if firstCondition && secondCondition && thirdCondition {
// 你要干什么
}
// 不推荐
if x == firstReallyReallyLongPredicateFunction()
&& y == secondReallyReallyLongPredicateFunction()
&& z == thirdReallyReallyLongPredicateFunction() {
// 你要干什么
}
风格-
能用let用let,尽量少用var
-
在对数组或者集合进行操作的时候,尽量使用高级函数map,filter,reduce
// 推荐
let stringOfInts = [1, 2, 3].flatMap { String($0) }
// ["1", "2", "3"]
// 不推荐
var stringOfInts: [String] = []
for integer in [1, 2, 3] {
stringOfInts.append(String(integer))
}
// 推荐
let evenNumbers = [4, 8, 15, 16, 23, 42].filter { $0 % 2 == 0 }
// [4, 8, 16, 42]
// 不推荐
var evenNumbers: [Int] = []
for integer in [4, 8, 15, 16, 23, 42] {
if integer % 2 == 0 {
evenNumbers(integer)
}
}
-
如果一个函数有多个返回值,推荐使用 元组 而不是 inout 参数, 如果你见到一个元组多次,建议使用typealias ,而如果返回的元组有三个或多于三个以上的元素,建议使用结构体或类。
func UserName() -> (firstName: String, lastName: String) {
return ("Guybrush", "Threepwood")
}
let name = UserName()
let firstName = name.firstName
let lastName = name.lastName
-
当使用委托和协议时,请注意避免出现循环引用,基本上是在定义属性的时候使用 weak 修饰,在闭包里使用 self 的时候要注意出现循环引用,使用捕获列表可以避免这一点。
myFunctionWithClosure() { [weak self] (error) -> Void in
// 方案 1
self?.doSomething()
// 或方案 2
guard let strongSelf = self else {
return
}
strongSelf.doSomething()
}
-
使用if做判断的时候,不使用()
// 推荐
if x == y {
/* ... */
}
// 不推荐
if (x == y) {
/* ... */
}
-
写枚举的时候,请简写
// 推荐
imageView.setImageWithURL(url, type: .person)
// 不推荐
imageView.setImageWithURL(url, type: AsyncImageView.Type.person)
-
在使用类方法的时候不用简写,因为类方法不如 枚举 类型一样,可以根据轻易地推导出上下文。
// 推荐
imageView.backgroundColor = UIColor.whiteColor
// 不推荐
imageView.backgroundColor = .whiteColor
-
不建议使用用self.修饰除非需要。
-
访问修饰符不应单独另起一行,应和访问修饰符描述的对象保持在同一行。
// 推荐
public class Pirate {
/* ... */
}
// 不推荐
public
class Pirate {
/* ... */
}
-
自定义操作符
不推荐使用自定义操作符,如果需要创建函数来替代。
在重写操作符之前,请慎重考虑是否有充分的理由一定要在全局范围内创建新的操作符,而不是使用其他策略。
你可以重载现有的操作符来支持新的类型(特别是 ==),但是新定义的必须保留操作符的原来含义,比如 == 必须用来测试是否相等并返回布尔值。
-
不要使用 as! 或 try!。
-
如果对于一个变量你不打算声明为可选类型,但当需要检查变量值是否为 nil,推荐用当前值和 nil 直接比较,而不推荐使用 if let 语法。
// 推荐
if someOptional != nil {
// 你要做什么
}
// 不推荐
if let _ = someOptional {
// 你要做什么
}
-
在实现协议的时候,有两种方式来组织你的代码: 使用 // MARK: 注释来分割协议实现和其他代码。 使用 extension 在 类/结构体已有代码外,但在同一个文件内。
-
使用 guard 语句 总体上,我们推荐使用提前返回的策略,而不是 if 语句的嵌套。使用 guard 语句可以改善代码的可读性。
// 推荐
func eatDoughnut(atIndex index: Int) {
guard index >= 0 && index < doughnuts else {
// 如果 index 超出允许范围,提前返回。
return
}
let doughnut = doughnuts[index]
eat(doughnut)
}
// 不推荐
func eatDoughnuts(atIndex index: Int) {
if index >= 0 && index < donuts.count {
let doughnut = doughnuts[index]
eat(doughnut)
}
}
如果需要在2个状态间做出选择,建议使用if 语句,而不是使用 guard 语句。
// 推荐
if isFriendly {
print("你好, 远路来的朋友!")
} else {
print(“穷小子,哪儿来的?")
}
// 不推荐
guard isFriendly else {
print("穷小子,哪儿来的?")
return
}
print("你好, 远路来的朋友!")
文档与注释如果一个函数比较复杂,通常需要给函数添加注释文档。使用苹果标准的方式进行注册 option command /进行注释 请务必查看在Apple文档中描述的Swift的注释标记中提供的全部功能。
指南:
-
1.160字符列限制
-
1.即使注释只占用一行,请使用/** */
-
1.不要再每一行附加一个*
-
1.确定使用新的 – parameter格式,而不是就得Use the new -:param:格式,另外注意 parameter 是小写的。
class Human {
/**
This method feeds a certain food to a person.
- parameter food: The food you want to be eaten.
- parameter person: The person who should eat the food.
- returns: True if the food was eaten by the person; false otherwise.
*/
func feed(_ food: Food, to person: Human) -> Bool {
// ...
}
}
-
1.如果需要给一个方法的 参数/返回值/抛出异常 添加注释,务必给所有的添加注释,即使会看起来有部分重复,否则注释会看起来不完整,有时候如果只有一个参数值得添加注释,可以在方法注释里重点描述。
-
1.对于复杂的类,可以使用一些潜在的例子来描述类的用法。请记住,Swift的注释文档中的markdown语法是有效的。换行符,列表等是适当的。
/**
## Feature Support
This class does some awesome things. It supports:
- Feature 1
- Feature 2
- Feature 3
## Examples
Here is an example use case indented by four spaces because that indicates a
code block:
let myAwesomeThing = MyAwesomeClass()
myAwesomeThing.makeMoney()
## Warnings
There are some things you should be careful of:
1. Thing one
2. Thing two
3. Thing three
*/
class MyAwesomeClass {
/* ... */
}
-
1.在写文档注释时,尽量保持简洁。当提到代码时,使用 -
/ **
这样做会有一个“UIViewController”,有时间。
- 警告:在运行此函数之前,请确保`someValue`为`true`。
* /
func myFunction() {
/ * ... * /
}
-
1.//后面要保留空格。
-
1.注释必须要另起一行。
-
1.使用注释 // MARK: - xoxo 时, 下面一行保留为空行。
class Pirate{
// MARK: - 实例属性
private let pirateName : String
// MARK: - 初始化
init() {
/ * ... * /
}
}
,