Apple在WWDC 2014开发者大会上发布了用于Mac OS X和iOS编程的新一代编程语言Swift。
在真正能够使用Swift之前,SF先带大家从Apple的Beta版文档中,简单的一览Swift的基础用法。
SEGMENTFAULT声明:本文是根据**未发布版本**的文档编译整理而成的。
我们无法保证苹果公司未来实际发布的软件,与本文的情况完全一致。
注:不要错过文章末尾的《SF简评Swift》部分!
101:最基本语法
- 编译型(LLVM)
- 等同众多解释型语言的实时输入、实时执行(Playground)
- 全局域自动执行(无需主函数)
- 行尾无分号
- Hello world:
println("Hello world")
- 注释使用
//
和/* */
。但块注释可以嵌套。
例如:/* A /* B */ C */
就是合法的。 -
=
运算符仅用于赋值
与C不同:var = value
不是一个合法的表达式
与C一致的是==
运算符仍然是判断
变量与数据类型
- 弱类型
- 变量:
var length = 10
- 常量:
let MAX_LENGTH = 100
- 强制类型:
var length: Double = 10
(var or let) - 完全禁止隐式转换,例如这个是错误的:
println("Length = " + length + " cm")
必须这样写:println("Length = " + String(length) + " cm")
但是在字符串中嵌入数字有一种简写法:println("Length = \(length) cm")
空值
- 空值表示为
nil
- 必须使用
?
,显式指定变量可以赋空值:var optionalString: String? = nil
(定义或运行时均可) -
nil
在逻辑判断中被隐式转换为false (这与通常的变量值不得隐式转换不同)
另外,如果待引用的变量值可能是nil
,一般需要先行判断。但在Swift中,可以在下标、方法或对象成员的引用之前加?
。
这个语法表示如果?
前边的是nil
,则后边的调用全部省略,整个表达式的值是nil
。
WWDC 2014会上,Craig Federighi 直接展示了这个用法,将数行带有预判断的代码缩成了一行:
数组与字典
- 全部使用方括号包裹
- 数组:
[value 1, value 2, value 3]
- 数组下标从0开始
- 字典:
["key1": value 1, "key2": value 2]
- 空数组:
[]
,空字典:[:]
流程控制
注意:Swift中任何条件判断,必须使用真正的布尔值表达式!数值不会按照“0/非0”的习惯规则隐式转换为true,而是一律报错。
条件分支
if 判断
if condition 1 {
code for condition 1
} else if condition 2 {
code for condition 2
} else {
code for none of above
}
-
if
语句中,小括号可选,大括号必须。
switch 多出口分支
switch variable {
case value 1:
code for value 1
case value 2:
code for value 1
default:
code for none of abolve
}
- 无需
break
- 可以一次比较多个值:
case value 1, value 2:
(值1或值2) - 比较条件不限于值,可以使用自定义的语句:
case let x where x > 10:
-
default
分支不得省略。
循环
for-in 遍历循环
for var_iterator in iterated_array {
code within loop
}
- 循环字典:
for (key, value) in iterated_dictionary
- 使用
..
指定整数的范围:for index in 1..5
for-condition-increment C风格循环
for var index = 0; index < 3; ++index {
code within loop
}
while 循环
while condition {
code
}
do {
code
} while condition
函数
定义与调用
func greet(name: String, day: String) -> String {
return "Hello \(name), today is \(day)."
}
greet("Bob", "Tuesday")
- 一次传入多个值:定义
func f1(p1: Int...) -> Int {code}
调用f1(1, 2, 3)
- 一次返回多个值:
return (3.59, 3.69, 3.79)
(借助tuple)
函数允许嵌套。子函数共享父函数的变量作用域:
func returnFifteen() -> Int {
var y = 10
func add() {
y += 5
}
add()
return y
}
returnFifteen()
闭包特性
函数本身是一种数据类型。函数可以作为返回值:
func makeIncrementer() -> (Int -> Int) {
func addOne(number: Int) -> Int {
return 1 + number
}
return addOne
}
var increment = makeIncrementer()
increment(7)
也可以把函数本身,作为参数传递给其他函数:
func hasAnyMatches(list: Int[], condition: Int -> Bool) -> Bool {
for item in list {
if condition(item) {
return true
}
}
return false
}
func lessThanTen(number: Int) -> Bool {
return number < 10
}
var numbers = [20, 19, 7, 12]
hasAnyMatches(numbers, lessThanTen)
但必须注意类型必须严格等同。
可以使用{}
定义匿名函数。可以在花括号内的第一行,使用in
关键字定义参数和返回值:
numbers.map({
(number: Int) -> Int in
let result = 3 * number
return result
})
- 但也可以在类型已知的情况下省略之。例如:
numbers.map({ number in 3 * number })
这个单行的闭包,只接受一个参数并返回表达式的值。 - 也可以使用数字引用参数。例如:
sort([1, 5, 3, 12, 2]) { $0 > $1 }
这个传参方式类似Shell。
对象与类
定义与实例化
定义:
class Shape {
var numberOfSides = 0
var name: String
init(name: String) {
self.name = name
}
func simpleDescription() -> String {
return "A shape with \(numberOfSides) sides."
}
}
实例化:
var shape = Shape("Triangle")
shape.numberOfSides = 3
println(shape.simpleDescription())
- 构造:
init(name: String) {self.name = name}
- 析构:
deinit() {code}
继承与多态
- 继承在类名后边加
:
- 使用
super
关键字引用父类 - 多态必须显式使用
override
关键字
class Square: NamedShape {
var sideLength: Double
init(sideLength: Double, name: String) {
self.sideLength = sideLength
super.init(name: name)
numberOfSides = 4
}
func area() -> Double {
return sideLength * sideLength
}
override func simpleDescription() -> String {
return "A square with sides of length \(sideLength)."
}
}
let test = Square(sideLength: 5.2, name: "my test square")
test.area()
test.simpleDescription()
属性(property)
能够自定义赋值或取值的代码的变量被称为属性(property)。
- 使用
get
自定义取值,使用set
自定义赋值 -
get
代码段中使用return
返回取值结果 -
set
代码段中固定使用newValue
来表示传入的值 - 也可以使用
willSet
和didSet
,在赋值前后执行代码(不影响赋值本身)
class Circle {
init(radius: Double) {
self.radius = radius
}
var radius: Double {
didSet {
perimeter = radius * 6.28
}
}
var perimeter: Double {
get {
return 6.28 * radius
}
set {
radius = newValue / 6.28
}
}
}
circle = Circle(10)
circle.perimeter // 62.8
circle.perimeter = 31.4
circle.radius // 5
枚举与结构体
使用enum
创建枚举量。枚举量有轻度的对象特性——可以在枚举量中使用方法。
enum Rank: Int {
case Ace = 1
case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten
case Jack, Queen, King
func simpleDescription() -> String {
switch self {
case .Ace:
return "ace"
case .Jack:
return "jack"
case .Queen:
return "queen"
case .King:
return "king"
default:
return String(self.toRaw())
}
}
}
let ace = Rank.Ace
let aceRawValue = ace.toRaw() // 1
使用toRaw
和fromRaw
转换原始值和字面值:
if let convertedRank = Rank.fromRaw(11) {
let jackDescription = convertedRank.simpleDescription() // "Jack"
}
let jackIndex = Rank.toRaw(Rank.Jack) // 11
上边的例子中,由于扑克牌存在数字意义的原始值,所以从Ace开始提供了一个1,而后按顺序自动增加。但Swift的枚举类型,为了没有数字意义的枚举量,也支持不使用原始值的定义方法:enum Color {case Red, Green, Blue}
也可以在枚举量上开辟变量空间,用来存储一些必要的值:
enum ServerResponse {
case Result(String, String)
case Error(String)
}
let success = ServerResponse.Result("6:00 am", "8:09 pm")
let failure = ServerResponse.Error("Out of cheese.")
switch success {
case let .Result(sunrise, sunset):
let serverResponse = "Sunrise is at \(sunrise) and sunset is at \(sunset)."
case let .Error(error):
let serverResponse = "Failure... \(error)"
}
结构体
结构体使用struct
定义,其定义语法和类非常相似。结构体支持构造器、成员方法等类的特性。
注意:结构体是按值传递的,而类/对象是按引用传递的。
struct Card {
var rank: Rank
var suit: Suit
func simpleDescription() -> String {
return "The \(rank.simpleDescription()) of \(suit.simpleDescription())"
}
}
let threeOfSpades = Card(rank: .Three, suit: .Spades)
let threeOfSpadesDescription = threeOfSpades.simpleDescription()
协议和扩展
使用protocol
定义协议:
protocol ExampleProtocol {
var simpleDescription: String { get }
mutating func adjust()
}
协议可以用在类、枚举和结构体上。
class SimpleClass: ExampleProtocol {
var simpleDescription: String = "A very simple class."
var anotherProperty: Int = 69105
func adjust() {
simpleDescription += " Now 100% adjusted."
}
}
var a = SimpleClass()
a.adjust()
let aDescription = a.simpleDescription
struct SimpleStructure: ExampleProtocol {
var simpleDescription: String = "A simple structure"
mutating func adjust() {
simpleDescription += " (adjusted)"
}
}
var b = SimpleStructure()
b.adjust()
let bDescription = b.simpleDescription
用extension
定义扩展,用来为已有的类型增加新的功能:
extension Int: ExampleProtocol {
var simpleDescription: String {
return "The number \(self)"
}
mutating func adjust() {
self += 42
}
}
7.simpleDescription
泛型
使用<>
声明泛型:
func repeat<ItemType>(item: ItemType, times: Int) -> ItemType[] {
var result = ItemType[]()
for i in 0..times {
result += item
}
return result
}
repeat("knock", 4)
泛型可以用在类、枚举和结构体上。
// Reimplement the Swift standard library's optional type
enum OptionalValue<T> {
case None
case Some(T)
}
var possibleInteger: OptionalValue<Int> = .None
possibleInteger = .Some(100)
使用where
对泛型提出一些约束:
func anyCommonElements <T, U where T: Sequence, U: Sequence, T.GeneratorType.Element: Equatable, T.GeneratorType.Element == U.GeneratorType.Element> (lhs: T, rhs: U) -> Bool {
for lhsItem in lhs {
for rhsItem in rhs {
if lhsItem == rhsItem {
return true
}
}
}
return false
}
anyCommonElements([1, 2, 3], [3])
SF简评Swift
Swift无疑是本次WWDC 2014中,贴近苹果开发者的最大亮点。
Swift并不是对语言思想的本质革新,而是从当前的各种优秀语言中博采众家之长,从而制成为苹果平台提供的优秀工具。
Swift尤其是对于各种“坑”的处理非常用心。例如:
- 嵌套注释
- 封锁隐式类型转换
- 封锁隐式逻辑判断
- ……
这些对于新手和老手而言,都是好的。“减轻新手痛苦,节约老手时间”——我想起了这一句广告词。
我们相信Swift(至少在部分场合下)作为Objective-C的代用语言,将在苹果开发过程中发挥不可或缺的作用。
我们目前主要对Swift存疑的地方有:
- 浮夸的Benchmark数据。
WWDC大会上Swift宣传相对Python等语言数十至数百倍的性能提升,是一种纯粹的广告口径——因为优秀编程语言之间出现如此巨大的性能差距,这本身就不太现实。我们期待将来能有第三方,对Swift本身给出资料和样例数据充分的公正的Benchmark。 - Swift的开源程度。
编程语言作为系统基础工具,其行为的透明性是非常关键的。斯诺登把世界吓怕了——希望自己的代码能够放心使用,而不至于在编程语言这一层面,就存在被植入预期以外的行为,这是现在的某些开发者客观存在的一个合理担忧。 - Swift的应用领域。
Swift究竟会成为一门通用的编程语言,还是只是作为苹果SDK的一部分而存在?这一点和Swift的开源程度是有重叠的——开源也许就意味着广为使用,而闭源就等同于Swift专用于苹果平台。
我们不愿意做任何的预先判断,只期待Swift公布后实际的表现如何。
Swift相关阅读推荐
语言介绍
苹果官方文档:(Pre-relase,发布前版本)
A Swift Tour, The Swift Programming Language, iOS Developer Library — Pre-Release
本文很多内容来自于对该文档的翻译。
来自其他作者的同一译文:来自苹果的编程语言——Swift简介
网络讨论
如何评价 Swift 语言?
新发布的 Swift 语言对初学者来说是新的机遇吗?
SegmentFault编译原创文章,转载请遵守本站相关声明。
外文原作者:Apple Inc.
编译与原创部分:沙渺
责任编辑:沙渺
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。