Skip to content

Latest commit

 

History

History
113 lines (70 loc) · 4.47 KB

ThinkingInSwift.md

File metadata and controls

113 lines (70 loc) · 4.47 KB

#Thinking in Swift

从Objective-C转到Swift,我们往往脑袋里还带着旧的一套编程套路。为了利用Swift写出更优雅,更健壮的代码。让我们用初心者的心态来学习新的编程范式,新的可能。

##1.拥抱Optional。哲学: 一个值要么有值,要么就是optional。

Optionals are an example of the fact that Swift is a type safe language. Swift helps you to be clear about the types of values your code can work with. If part of your code expects a String, type safety prevents you from passing it an Int by mistake. This restriction enables you to catch and fix errors as early as possible in the development process.

Swift引进了一个新的概念Optional,以及相关的一系列语法:

  • ?! 声明Optional
  • if let Optional binding
  • guard
  • as?as!
  • try?

Optional的核心在于类型安全,在于和Nil做斗争。在于在运行前就处理好所有值为空或不为空的情况,如果有错误的话,直接在编译的时候就给出error,不等到运行的时候才crash。

在Swift的世界里,如果我们不声明一个对象为Optional,则它一定是有值的。这一点是非常有价值的,避免了我们对空对象进行操作。虽然在Objective-C中对空对象发送消息不会导致crash。但是有许多情况下对空对象操作会导致Crash,比如向数组插入空对象等许多操作操作。(详情查阅:Crash in Cocoa

更重要的是,我们更希望达到一种状态,就是我操作对象和数据的时候,我能够确信它不为空。这种哲学避免了许多冗杂无用的判断Nil操作,同时也大大减少了忘记判断nil导致的crash。

那Swift究竟通过什么途径来保证一个对象如果不是Optional,他就一定有值呢?

  1. 如果我们使用了没被初始化的变量和常量,编译器会抛出error。

    var testString:String
    print(testString)
    //error: variable 'testString' used before being initialized
  2. 类和结构体的实例在创建时,一定要为所有存储型属性设置初始值。我们可以在initializer或是定义属性的时候为其设置默认值,否则编译器会抛出error.

    class testClass {
    var a:String
    
        init(){ 
        }
        //	error:return from initializer without initializing all stored properties
    
    }

由此我们也引出了optional的概念。Optional表示一个值可能为空。要么有值,要么为空(nil)。

那么这时候你可能会问,在Objective-C也是这样,一个对象要么有值,要么为nil。

从最简单的语法入手:

var optionalInt:Int?
  1. 首先,在OC中,nil只针对对象而已,对于结构体,枚举类型,基本的C类型来说,是没有nil的。我们不能直接判断它们是否有值。在OC中,nil是一个指向不存在对象的指针,在Swift中,nil不知指针,它是一个确定的值,用来表示值为空。 (事实上,nil是一个枚举值)

    Swift之 ? 和 !

    而Swift的Optional让我们能明确地标注一个值有没有可能为空。并且值的类型没有限制。

  2. Swift的Optional Binding机制确保我们在使用Optional值时先判断值是否为空。

    在Objective-C中,判空操作不是强制和必须的。判空是一个良好的习惯,但是因为没有约束和规范。很多时候判空操作都被遗漏了,导致了许多潜在的问题。

    但在Swift中,r

比较绕的一点:

let optionalLet:String?
var optionalVar:String?

//标记为optional的let,一定要在使用前赋值,要么永远为nil,要么永远有值
//标记为optional的var,不需要要在使用前赋值,因为它可能有时有值,有时没值

if let unwarp = optionalLet{
//error: variable used before being initalized
}

if let unwarp = optionalVar{
    //OK
}

参考 why use optional let

##2.学习泛型。抽象的魅力。

泛型编程其实简单来说,就是让我们写出不局限于单一类型的代码。

举个最简单的例子:交换。对比以下两种写法,一种是只针对Int类型的交换。而我们用泛型改写后,适用于其它所有类型。

func oldSwap(inout a:Int ,inout _ b:Int){
    let temp = a
    a = b
    b = temp
}

func genericSwap<T>(inout a:T,inout _ b:T){
    let temp = a
    a = b
    b = temp
}