swift系统扫盲(技术帖Swift代码规范)

命名
  • 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

    }

    }

    格式

    在团队开发过程中,代码格式非常重要,保持良好的代码编写习惯。

    • 每个文件结尾后又空白行。

    • 每一行都不能以空白作为结尾。

    swift系统扫盲(技术帖Swift代码规范)(1)

    • 左边的大括号不用另起一行。

    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() {

    / * ... * /

    }

    }

    ,

    免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

      分享
      投诉
      首页