常量和变量
let设定常量
let encouragement = "You can do it!"
即使两个常量相同,也不能互相赋值
//: ### Two ways of being immutable - #1 Assignment
var goat = UIImage(named:"Chinese-New-Year-3.jpg")!
let yearsOfTheGoat = [1967, 1979, 1991, 2003, 2015]
let yearsOfTheSheep = [1967, 1979, 1991, 2003, 2015]
//以下结果会报错
yearsOfTheGoat = yearsOfTheSheep
常量不能有更改
//以下结果会报错
yearsOfTheGoat.append(2027)
var设定变量
var personalizedEncouragement = "You can do it, Lauren!"
personalizedEncouragement = personalizedEncouragement.stringByReplacingOccurrencesOfString("Lauren", withString: "Cameron")
var + 变量名 : 类型
var age: Int
var string: String = "smile"
省略类型由系统来推断
var a = 20, b:String, c = "Swift"
标识符必须以字符(包括Unicode字符),下划线_,美元符$开头,但不能以数字开头,不可以包含空格,不能使用关键字,其长度没有限制
数据类型
整型
用Int就可以了。其实还有Int16,Int32
let oneMillion = 1_000_000 //可以增加下划线作为分隔符
print(oneMillion)
整型之间转换必须是显式转换
var book1: Int16 = 100
var book2: Int32 = 30
var totalPrice = Int32(book1) + book2 //必须先转换,否则会报错
正无穷,负无穷,非数
var w = 4.0 / 0.0 //正无穷
var w = - 4.0 / 0.0 //负无穷
var f = 0.0 / 0.0 //非数
浮点运算
var width: Float = 2.1
var height: Double = 3.9
var area1 = width * Float(height) //必须先转换,否则会报错
//在Swift2.0 版本中貌似整数不转换也可以哦
var area2 = Int(width) * 4 //必须先转换,否则会报错
类型别名
typealias Age = UInt16
let myAge:Age = 10
元组
赋值方式1.直接赋值
var score = (140,140,"Good")
赋值方式2.先申明类型
var health : (Int , Int , String)
health = (182 , 78 , "Good")
print ("health元组的值为:\(health)") //打印元组所有
print ("health元组中身高的值为:\(health.1)") //打印元组中第二个值
赋值方式3.key-value赋值
//顺序可以调换
var score2 = (math:140, English:140, Assessment:"A")
var score3 :(math:Int, English:Int, Assessment:String)
score3 = (English:140, math:145, Assessment:"A")
print("score3 中数学的成绩是: \(score3.math)")
元组中的嵌套
var test:(Int,(Int,String))
test = (10,(100,"Swift"))
print("test元组中第二个元素的第一个元素为:\(test.1.0)")
可选类型
在swift中不能赋值nil给变量或者对象
var x: Int
x = nil //这样赋值必报错
var c: AnyObject
c = UIColor.redColor()
c = nil //这样赋值必报错
如果遇到可能会出现nil的情况,就使用可选类型,在变量后添加?
情况1. 可能返回值为nil
var y: Int?
var s1: String
var s2: String
s1 = "123"
s2 = "ABC"
y = Int(s1)
y = Int(s2)
情况2. 对象创建时属性还没赋值
class ViewController: UIViewController {
var button: UIButton!
}
情况3. 函数传值为nil. (在swift里,nil是个值,表示值缺失,但在OC里,nil是个空指针)
Example: Picking up groceries in an optional car
func pickUpGroceries(car:Car?) {
if let car = car {
print("We'll pick up the groceries in the \(car.make)")
} else {
print("Let's walk to the store")
}
}
var someCar = Car(make: "Toyota", model: "Corolla")
pickUpGroceries(someCar)
pickUpGroceries(nil)
Example: Hosting a guest in an optional extra room
func host(guest: String, extraRoom: Room?) {
if let extraRoom = extraRoom {
print("Come stay with us, \(guest), you can sleep in the \(extraRoom.name).")
} else {
print("Come stay with us, \(guest), you can sleep on the couch.")
}
}
var someRoom = Room(name: "guest room", occupied: false)
host("Grandma", extraRoom: someRoom)
host("Ryan", extraRoom: nil)
使用if let强制解析(安全)
可选类型的变量就像一个盒子,里面不知道是否装着礼物。使用前必须要打开它确定是否有无,就是强制解析.
var zee: Int?
let strings = ["ABC","123"]
let randomIndex = Int(arc4random() % 2)
let anotherString = strings[randomIndex]
zee = Int(anotherString)
if let intValue = zee {
intValue * 2
} else {
"No value"
}
更为便捷的命名方式,不用再重新命名
var zee: Int?
let strings = ["ABC","123"]
let randomIndex = Int(arc4random() % 2)
let anotherString = strings[randomIndex]
zee = Int(anotherString)
if let zee = zee {
zee * 2
} else {
"No value"
}
使用!强制解析
Example 1 - unwrap optional
使用!时,意味着你确定值是不为nil的,否则就会系统出错。要谨慎使用
let w = Int("123")!
w * 2
Example 2 - implicitly unwrap optionl
一开始就声明它是个需要强制解析的optionl类型,意味着使用时,它会自动unwrap
class BetterViewController: UIViewController {
var myButton: UIButton!
override func viewDidLoad(){
super.viewDidLoad
//如果没有这行,就会报错,因为没有初始化,UIButton就是nil
button = UIButton()
var title = button.titleForState(UIControlState.Normal)
}
}
可选链
强制解析image,获取其size属性
var imageView = UIImageView()
imageView.image = UIImage(named:"puppy_in_box")
if let image = imageView.image {
let size = image.size
} else {
print("This image hasn't been set.")
}
使用可选链直接访问size属性
var size = anotherImageView.image?.size
可选链unwrap image, if let unwrap size, 这样更安全
var anotherImageView = UIImageView()
anotherImageView.image = UIImage(named:"puppy_in_box")
var size = anotherImageView.image?.size
if let imageSize = anotherImageView.image?.size {
print("Here's the image size: \(imageSize)")
} else {
print("This image hasn't been set.")
}
Example 2 (传值为nil)
var animal = Animal(name: "Lenny", species: "lemur", tailLength: 12)
animal = Animal(name: "Gilbert", species: "Gorilla", tailLength: nil )
if let tailLength = animal.tail?.length {
print("\(animal.name)'s tail is \(tailLength) long")
} else {
print("\(animal.name) doesn't have a tail.")
}
as? or as! 转换为子类
ColdDrink, HotDrink是 beverage的子类, drinkChoices是他们的集合
for beverage in drinkChoices{
//强制解析为subclass
if let coldDrink = beverage as? ColdDrink {
print(.....)
}else if let hotDrink = beverage as? HotDrink {
print(.....)
}
}
如果确定的话,使用as!,就不必使用if let了
for beverage in drinkChoices{
//强制解析为subclass
let coldDrink = beverage as!ColdDrink {
print(.....)
}
}
运算符
swift赋值
var a: Int //该表达式没有值
var b = a = 20 //不支持连续赋值
求余运算
var g = 5.2 (结果正负取决于被除数的正负)
var h = 3.1
var mod = g % h
print(mod)
自增自减
Swift1.x
//结果是11,先执行运算,然后a再自加1
var a = 5
var b = a++ + 6
print(b)
//结果是12,先自身加1,再执行运算
var a = 5
var b = ++a + 6
print(b)
Swift2.x
a -=1
a +=1
Swift3.x将取消 ++ 运算符
溢出运算符
//&+ &- &* &/ &% 执行的是位运算
var willUnderflow = UInt8.min //最小值是0
willUnderflow = willUnderflow &-1 //下溢
位运算符
& 按位与
| 或
^ 异或
~ 取反
<< 左位移
右位移 >>
扩展后的赋值运算符
-=
*=
/=
&=
|=
运算符 “+= ” 对于 x+=y 等价于 x = x+y
区间运算符
a..<b (包含a,但不包含b)
a…b(包含a,也包含b)
1 | for a in 0..<10{ |
1 | for a in 0...10{ |
比较运算符,结果为BOOL值
只有a和b指向的类型实例相同时,c为true
var c= a === b
- === 特征相等运算符
- !== 特征不等运算符
例子
let ticketPrice = 7.5
let allowance = 10.0
var iceCreamPrice = 3.0
var pic = UIImage(named:"Chloe.png")!
if allowance >= ticketPrice + iceCreamPrice {
print("Let's go to the movies!")
} else {
print("Let's watch a movie at home and eat ice cream")
}
逻辑运算符
&& 与
|| 或
! 非
空合并运算符 a??b
- a是可选类型,将对可选类型a进行空判断,如果a包含一个值就进行解封
- 否则就返回一个默认值b
- 默认值b的类型必须要和a存储值的类型保持一致
1 | let words = "hello" |
流程控制
分支结构
if…else…
语句的条件执行体必须放在花括号中,条件语句不用括号
var hungry = true
var vegetarian = false
if hungry {
print("Let's eat!")
}else{
print("Let's wait.")
}
if hungry && !vegetarian {
print("Let's eat steak!")
} else if hungry && vegetarian {
print("How about pumpkin curry?")
} else {
print("nevermind")
}
三目运算符 - Ternary conditional
以下两种写法相等
if question { answer1 } else { answer2 }
question ? answer1 : answer2
例子1.
hungry ? print("Let's eat!") : print("Let's wait.")
例子2.
hungry || thereIsPie ? print("Let's eat!") : print("Let's wait.")
例子3.
// Ternary statements can also be used as expressions.
let sandwichPrice = 5.0
var tax = true
var lunchPrice = sandwichPrice + (tax ? 0.50 : 0)
Switch -
格式:case后可以有多个值,每条语句执行完后自动退出
switch variable {
case firstValue:
statement
case secondValue:
statement
case thirdValue, fourthValue:
statement
default:
statement
}
case后可以是个范围
var color = ""
var wavelength = 568
switch wavelength {
case 380...450:
color = "violet"
case 451...495:
color = "blue"
case 496...570:
color = "green"
case 571...590:
color = "yellow"
case 591...620:
color = "orange"
case 621...750:
color = "red"
default:
color = "not visible"
}
case后的条件为元组
var point = (x:5 , y:2)
switch point {
case (0,0):
print("(0,0)位于原点")
case (_,0): //用 "_" 表示可以忽略这个数据
print("(\(point.0),0)位于x轴上")
case (0...Int.max as ClosedInterval, 0...Int.max as ClosedInterval):
print("(\(point.0),\(point.1))位于第一象限")
default:
break
}
使用fallthrough语句才能贯穿,否则不再继续执行下一条
var num = 5
var desc = "\(num)是"
switch num {
case 2, 3, 5, 7 :
desc += "质数,而且还是"
fallthrough
default:
desc += "整数"
}
print(desc) //结果是“5是质数,而且还是整数”
支持值绑定
var point = (x:1 , y:1)
switch point {
case (0,0):
print("(0,0)位于原点")
case (var a, 0)://y坐标为0,进入该case块,并将元组的x成员绑定到临时变量a
print("该点位于x轴上,x值为:\(a)")
case var (x,y) where x>0 && y>0: //条件值绑定
print("(\(x),\(y))位于第一象限")
default:
break
}
循环结构
for loop
传统的C - style for loop (swift也支持)
for var index = 99; index >0; --index {
print ("Hello")
}
更为简洁的形式
for item in Collection {
statements to execute on each item
}
例子1
for index in 1...5 {
print("\(index) times 5 is \(index * 5)")
}
例子2 不访问index的值
let base = 3
let power = 10
var answer = 1
for _ in 1...power { //下划线符号_替代循环中的变量,能够忽略具体的值,并且不提供循环遍历时对值的访问
answer *= base
}
例子3 遍历数组累加
let intArray = [7, 21, 25, 13, 1]
var sum = 0
for value in intArray {
sum += value
}
例子4 遍历字典value值替换key值
for (key, value) in Dictionary {
statement to execute on each key or value
}
let dictionary = ["monkey": "🐒", "iPhone":"📱"]
var newestString = sillyMonkeyString
for (key, value) in dictionary {
newestString = newestString.stringByReplacingOccurrencesOfString(key, withString: value)
}
print(newestString)
嵌套循环遍历时使用的标签
- 紧跟冒号的标识符,只有放在循环语句或者switch语句之前才有作用
- break结束循环,开始执行循环之后的代码
- continue 忽略本次循环的剩下语句,执行下一次循环,但不终止循环
1 | outer: for i in 0...5 { |
while … loop
while condition {
statement
}
var timer = 10
while timer > 0 {
timer -= 1
}
repeat … loop
repeat {
statement
} while condition
repeat {
--timer
} while timer > 0