Swift学习笔记(一)

学习Swift的方向:通过斯坦福大学公开课-CS193P iPhone Application Development的课程,结合苹果官方教程-《The Swift Programming Language》中文版,逐步了解Swift语法,与Obective-C全面对比,掌握Swift各种特性跟上苹果的节奏。

常量与变量

OC中,我们一般这样声明宏、常量和变量

1
2
3
4
5
6
7
8
//宏
#define CoderX @"xayoung"

//变量
NSString *CoderX;

//常量
NSString * const CoderX = @"xayoung";

在Swift中,使用letvar分别定义常量和变量

声明常量或者变量的时候可以加上类型标注(type annotation),说明常量或者变量中要存储的值的类型。如果要添加类型标注,需要在常量或者变量名后面加上一个冒号和空格,然后加上类型名称。
注意点:一旦你将常量或者变量声明为确定的类型,你就不能使用相同的名字再次进行声明,或者改变其存储的值的类型。同时,你也不能将常量与变量进行互转。

1
2
3
4
//常量
let CoderX
//or
let CoderX = "xayoung"
1
2
3
4
5
6
7
//变量
var CoderX
//or
var CoderX = "xayoung"
//or
var CoderX: String
CoderX = "xayoung"

输出

在OC中我们一般使用NSLog进行输出

1
2
3
4
NSLog(@"xayoung is a coder!");
//or
NSString *CoderX = @"xayoung is a coder!"
NSLog(@"%@",CoderX);

Swift则通过print进行输出

1
2
3
print("xayoung is a coder!")
var CoderX = "xayoung"
print("\(CoderX) is a coder!")

类型安全和类型推断

Swift 是类型安全的,所以它会在编译你的代码时进行类型检查(type checks),并把不匹配的类型标记为错误。这可以让你在开发的时候尽早发现并修复错误。
当你要处理不同类型的值时,类型检查可以帮你避免错误。然而,这并不是说你每次声明常量和变量的时候都需要显式指定类型。如果你没有显式指定类型,Swift 会使用类型推断(type inference)来选择合适的类型。有了类型推断,编译器可以在编译代码的时候自动推断出表达式的类型。原理很简单,只要检查你赋的值即可。因为有类型推断,和 C 或者 Objective-C 比起来 Swift 很少需要声明类型。
常量和变量虽然需要明确类型,但是大部分工作并不需要你自己来完成。

在定义常量的时候,下方的常量CoderX会被推断为String类型

1
2
3
4
//常量
let CoderX
//or
let CoderX = "xayoung"

如果定义的时候声明类型,就只能传入该类型的值

1
2
var CoderX: String
CoderX = "xayoung"

可选类型

C 和 Objective-C 中并没有可选类型这个概念。最接近的是 Objective-C 中的一个特性,一个方法要不返回一个对象要不返回nil,nil表示“缺少一个合法的对象”。然而,这只对对象起作用——对于结构体,基本的 C 类型或者枚举类型不起作用。对于这些类型,Objective-C 方法一般会返回一个特殊值(比如NSNotFound)来暗示值缺失。这种方法假设方法的调用者知道并记得对特殊值进行判断。然而,Swift 的可选类型可以让你暗示任意类型的值缺失,并不需要一个特殊值。

如CS193P公开课代码实例中就展示了这个概念

1
2
3
4
5
6
7
8
9
10
11
12
13
@IBOutlet weak var display: UILabel!

//点击button方法
@IBAction func appendDigit(sender: UIButton) {
//默认是Optional类型,通过!将button的值解包
let digit = sender.currentTitle!
if userIsInTheMiddleOfTypingANumber{
display.text = display.text! + digit
}else{
display.text = digit
userIsInTheMiddleOfTypingANumber = true
}
}

函数

Swift 统一的函数语法足够灵活,可以用来表示任何函数,包括从最简单的没有参数名字的 C 风格函数,到复杂的带局部和外部参数名的 Objective-C 风格函数。参数可以提供默认值,以简化函数调用。参数也可以既当做传入参数,也当做传出参数,也就是说,一旦函数执行结束,传入的参数值可以被修改。
在 Swift 中,每个函数都有一种类型,包括函数的参数值类型和返回值类型。你可以把函数类型当做任何其他普通变量类型一样处理,这样就可以更简单地把函数当做别的函数的参数,也可以从其他函数中返回函数。函数的定义可以写在在其他函数定义中,这样可以在嵌套函数范围内实现功能封装。

在OC中,我们一般这么定义函数

1
-(double)preformOperationxWithDouble1:(double )d1 Double2:(double )d2;

Swift更简洁

1
func preformOperationx(operation:(Double, Double)-> Double)

CS193P公开课中计算器的实现方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//运算
@IBAction func operate(sender: UIButton) {
let operation = sender.currentTitle!
if userIsInTheMiddleOfTypingANumber {
enter()
}
switch operation {
//给preformOperationx传入函数{ $0 * $1 },返回一个double
case "×": preformOperationx(){ $0 * $1 }
case "÷": preformOperationx(){ $1 / $0 }
case "+": preformOperationx(){ $0 + $1 }
case "-": preformOperationx(){ $1 - $0 }
//函数虽然同名,但是swift会推断传入的参数调用哪个方法
case "√": preformOperationx(){ sqrt($0)}
default:break
}
}
//自定义函数,复用运算的代码
private func preformOperationx(operation:(Double, Double)-> Double) {
if operandStark.count >= 2 {
displayValue = operation(operandStark.removeLast() , operandStark.removeLast())
enter()
}
}
private func preformOperationx(operation:(Double)-> Double) {
if operandStark.count >= 1 {
displayValue = operation(operandStark.removeLast())
enter()
}
}

课程示例程序截图

此处输入图片的描述

附上代码的github连接:https://github.com/xayoung/CS193P-DemoCode

课程视频截图

此处输入图片的描述

小结

通过两个课时的讲解,并结合苹果官方的《The Swift Programming Language》,对Swift有了基本的认识,老头子讲得很仔细很透彻,一个不错的开始😊