Swift编程规范:保持代码优美的10个方法

Posted CSDN

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Swift编程规范:保持代码优美的10个方法相关的知识,希望对你有一定的参考价值。

这篇Swift风格指南与你看到的其他的指南有所不同,此篇指南主要焦点集中在打印和Web展示的可读写上。我们创建此篇风格指南的目的,是为了让我们的图书、教程以及初学者套件中的代码保持优美和一致,即使我们有很多不同的作者共同编写这些图书。


我们的首要目标是一致性,可读性和简洁性。


还在使用Objective-C?也可以参考我们的Objective-C风格指南(中译版)。


命名(Naming)


使用驼峰式的描述性命名方式,为类,方法,变量等命名。类名的首字母应该大写,而方法和变量的首字母使用小写字符。

推荐做法:


[cpp] view plaincopy

  1. private let maximumWidgetCount = 100

  2. class WidgetContainer {

  3. var widgetButton: UIButton

  4. let widgetHeightPercentage = 0.85

  5. }


不推荐做法:


[cpp] view plaincopy

  1. let MAX_WIDGET_COUNT = 100

  2. class app_widgetContainer {

  3. var wBut: UIButton

  4. let wHeightPct = 0.85

  5. }


对于函数和初始化方法,推荐对所有的参数进行有意义的命名,除非上下文已经非常清楚。如果外部参数命名可以使得函数调用更加可读,也应该把外部参数命名包含在内。


[cpp] view plaincopy

  1. func dateFromString(dateString: String) -> NSDate

  2. func convertPointAt(#column: Int, #row: Int) -> CGPoint

  3. func timedAction(#delay: NSTimeInterval, perform action: SKAction) -> SKAction!

  4. // 调用方式如下:

  5. dateFromString("2014-03-14")

  6. convertPointAt(column: 42, row: 13)

  7. timedAction(delay: 1.0, perform: someOtherAction)


对于方法来说,参照标准的苹果惯例,方法命名含义要引用到第一个参数:


[cpp] view plaincopy

  1. class Guideline {

  2. func combineWithString(incoming: String, options: Dictionary?) { ... }

  3. func upvoteBy(amount: Int) { ... }

  4. }


枚举(Enumerations)


使用首字母大写的驼峰命名规则来命名枚举值:


[cpp] view plaincopy

  1. enum Shape {

  2. case Rectangle

  3. case Square

  4. case Triangle

  5. case Circle

  6. }


文章(Prose)


当我们在文章中(教程,图书,注释等)需要引用到函数时,需要从调用者的视角考虑,包含必要的参数命名,或者使用_表示不需要命名的参数。


从你自身实现的init中调用convertPointAt(column:row:)。
如果你调用dateFromString(_:),需要保证你提供的输入字符串格式是”yyyy-MM-dd”。
如果你需要在viewDidLoad()中调用timedAction(delay:perform:),记得提供调整后的延迟值和需要处理的动作。
你不能直接调用数据源方法tableView(_:cellForRowAtIndexPath:)


当你遇到疑问时,可以看看Xcode在jump bar中是如何列出方法名的 —— 我们的风格与此匹配。



类的前缀(Class Prefixes)


Swift类型自动被模块名设置了名称空间,所以你不需要加一个类的前缀。如果两个来自不同模块的命名冲突了,你可以附加一个模块名到类型命名的前面来消除冲突。


[cpp] view plaincopy

  1. import SomeModule

  2. let myClass = MyModule.UsefulClass()


空格(Spacing)


使用2个空格的缩进比使用tabs更好,可以减少占用空间和帮助防止多次换行。确保在Xcode进行了下图的偏好设置:




  • 方法定义的大括号或者其他大括号(if/else/switch/while等)—— 般都放在定义名称的同一行,并且使用一个新的行来结束。

  • 提示:你可以通过以下方法重新进行缩进:选择一些代码(或者使用⌘A选择所有),然后按Control-I(或者点击菜单栏 Editor\Structure\Re-Indent)。一些Xcode模板代码使用的缩进是4个空格,所以这种方法可以很好的修复缩进。


推荐做法:


[cpp] view plaincopy

  1. if user.isHappy {

  2. // Do something

  3. } else {

  4. // Do something else

  5. }


不推荐做法:


[cpp] view plaincopy

  1. if user.isHappy

  2. {

  3. // Do something

  4. }

  5. else {

  6. // Do something else

  7. }


  • 应该在方法之间空出一行,从视觉上有更好的区分和组织。方法内的空白行隔开不同的功能,但是当一个方法中有很多段落时,也意味着你应该将该方法重构成几个方法。


注释(Comments)


当你需要时,使用注释来解释一段特定的代码段的作用。注释必须保证更新或者及时删除。


避免在代码中使用块注释,代码尽可能自己能表达含义。以下情况除外:当使用注释来生成文档时。


类和结构体(Classes and Structures)


选择使用谁?(Which one to use?)


请记住,结构体是值类型。使用结构体并没有一个标识。一个数组包含[a, b, c]和另外一个数组同样包含[a, b, c]是完全一样的,它们完全可以交换使用。使用第一个还是使用第二个无关紧要,因为它们代表的是同一个东西。这就是为什么数组是结构体。


类是引用类型。使用类是有一个标识或者有一个特定的生命周期。你需要对一个人类建模为一个类,因为两个不同的人的实例,是两个不同的东西。只是因为两个人有同样的名字和生日,也不能断定这两个人是一样的。但是人的生日是一个结构体,因为日期1950-3-3和另外一个日期1950-3-3是相同的。日期不需要一个标识。


有时,一些事物应该定义为结构体,但是需要兼容AnyObject或者已经在以前的历史版本中定义为类(NSDate,NSSet)。尽可能的尝试遵守这些规则。


定义的案例(Example definition)


以下是一个风格很好的类定义:


[cpp] view plaincopy

  1. class Circle: Shape {

  2. var x: Int, y: Int

  3. var radius: Double

  4. var diameter: Double {

  5. get {

  6. return radius * 2

  7. }

  8. set {

  9. radius = newValue / 2

  10. }

  11. }

  12. init(x: Int, y: Int, radius: Double) {

  13. self.x = x

  14. self.y = y

  15. self.radius = radius

  16. }

  17. convenience init(x: Int, y: Int, diameter: Double) {

  18. self.init(x: x, y: y, radius: diameter / 2)

  19. }

  20. func describe() -> String {

  21. return "I am a circle at \(centerString()) with an area of \(computeArea())"

  22. }

  23. override func computeArea() -> Double {

  24. return M_PI * radius * radius

  25. }

  26. private func centerString() -> String {

  27. return "(\(x),\(y))"

  28. }

  29. }


以上例子遵循了以下风格规范:


  • 指定属性、变量、常量、参数定义或者其他定义的类型,在冒号后面,紧跟着一个空格,而不是把空格放在冒号前面。比如:x: Int和Circle: Shape。

  • 如果能表示相同的目的和上下文,可以在同一行定义多个变量和结构体。

  • 缩进getter,setter的定义和属性观察器的定义。

  • 不需要添加internal这样的默认的修饰符。同样的,不需要在重写一个方法时添加访问修饰符。


Self的使用(Use of Self)


为了保持简洁,避免使用 self 关键词,Swift 不需要使用 self 来访问对象属性和调用对象方法。


必须使用 self 来区分构造器中属性命名和参数命名,还有在闭包表达式中引用属性值(编译器需要区分):


[cpp] view plaincopy

  1. class BoardLocation {

  2. let row: Int, column: Int

  3. init(row: Int, column: Int) {

  4. self.row = row

  5. self.column = column

  6. let closure = {

  7. println(self.row)

  8. }

  9. }

  10. }


协议遵守(Protocol Conformance)


当我们对一个类添加协议时,推荐使用一个单独的类扩展来实现协议的方法。这可以保持协议相关的方法聚合在一起,同时也可以简单的标识出一个协议对应类中需要实现哪些对应的方法。


同时,别忘了添加// MARK:,注释可以使得代码组织的更好!


推荐做法:


[cpp] view plaincopy

  1. class MyViewcontroller: UIViewController {

  2. // class stuff here

  3. }

  4. // MARK: - UITableViewDataSource

  5. extension MyViewcontroller: UITableViewDataSource {

  6. // table view data source methods

  7. }

  8. // MARK: - UIScrollViewDelegate

  9. extension MyViewcontroller: UIScrollViewDelegate {

  10. // scroll view delegate methods

  11. }


不推荐做法:


[cpp] view plaincopy

  1. class MyViewcontroller: UIViewController, UITableViewDataSource, UIScrollViewDelegate {

  2. // all methods

  3. }


计算属性(Computed Properties)


为了保持简洁,如果一个计算属性是只读的,请忽略掉get语句。只有在需要定义set语句的时候,才提供get语句。

推荐做法:


[cpp] view plaincopy

  1. var diameter: Double {

  2. return radius * 2

  3. }


不推荐做法:


[cpp] view plaincopy

  1. var diameter: Double {

  2. get {


完整文章请点击“阅读原文”


本文为CSDN原创,点击“阅读原文”可查看原文并参与讨论。


以上是关于Swift编程规范:保持代码优美的10个方法的主要内容,如果未能解决你的问题,请参考以下文章

Swift编程规范:保持代码优美的10个方法

从零开始学Swift——编程规范 第五季-关东升-专题视频课程

前端编程规范

Swift 设计指南之 编程规范

如何提升Python编程能力

2.1.10 java编程规范