Swift:苹果在2014年推出的面向对象开发的语言,用来撰写OS X 和 iOS 应用程序的强类型语言,顺带提一下Chris Lattner~克里斯·拉特纳Swift的亲爹,Swift的大部分基础架构均由他1人完成,他本人也对Swift的开源化作出了贡献.
语言特点:让开发变得 ---> 简快稳
- 语法简单、代码简洁、使用方便
- 可以和Objective-C混合使用;
- 提供了命名空间(namespace)、泛型(generic)、运算对象的重载(operator overloading)
Swift基本语法
- 导入框架import UIKit
- 语句结束不需要加 ;
- 打印语句print(内容)
- 定义标识符时,必须声明标识符是变量还是常量 ,使用let声明常量,使用var声明变量.标识符的类型必须和你赋给它们的值一样.声明的同时赋值,编译器会自动判断类型的方式称作类型推导
import UIKit
var a = 20
a = 30
var b : Int = 40
let value1 = 7.0
let value2 :Double = 7.77
Swift中基本运算
Swift中在进行基本运算时必须保证类型一致,同类型之间才可以进行运算,Swift中没有隐式转换
let label = "hello world "
let width = 50
let widthLabel = label + String(width)
print(widthLabel) // "hello world 50"
if语句
- 判断句可以不加()
- 判断句中必须有明确的真假(不再有非0即真)
- 条件必须是Bool表达式,取值:true/false
let score = 87
if score < 60 {
print("不及格")
} else if score <= 70 {
print("及格")
} else if score <= 80 {
print("良好")
} else if score <= 90 {
print("优秀")
} else {
print("完美")
}
三目运算符
var a = 10
var b = 50
var result = a > b ? a : b
println(result) // 50
guard的使用
- guard是Swift新增语法.
- guard语句必须带有else语句当条件表达式为true时候跳过else语句中的内容,执行语句组内容;条件表达式为false时候执行else语句中的内容,跳转语句一般是return、break、continue和throw
guard 条件 else {
//条件语句
break
}
代码...
例:
var age = 18
func online(age : Int) -> Void {
guard age >= 18 else {
print("回家去")
return
}
print("可以上网")
}
online(age) // 可以上网
switch
- 苹果对switch进行了加强,swich后可以不加() ,case后可以不跟break(默认会有)
let sex = 0
switch sex {
case 0 :
print("男")
case 1 :
print("女")
default :
print("其他")
}
- 一个case可以判断多个值 以,隔开
let sex = 0
switch sex {
case 0, 1:
print("正常人")
default:
print("其他")
}
- case的穿透,可以使用关键字fallthrough
let sex = 0
switch sex {
case 0:
fallthrough
case 1:
print("正常人")
default:
print("其他")
}
- 支持多种数据类型:字符串,浮点型,重点提一下区间型
开区间: 0..<10 表示:0-9
闭区间: 0...10 表示:0-10
let score = 88
switch score {
case 0..<60:
print("不及格")
case 60..<80:
print("几个")
case 80..<90:
print("良好")
case 90..<100:
print("优秀")
default:
print("满分")
}
循环:for/while/do while
//一般写法
for var i = 0; i < 5; i++ {
print(i)
}
//特殊写法:如果不需要用到下角标
for _ in 0..<5 {
print("666666")
}
//需要用到下角标的区间循环
for i in 0..<5 { // 0-4
print(i)
}
for i in 0...5 { // 0-5
print(i)
}
//while后面()可以省略
var a = 0
while a < 10 {
a++
}
//do while循环:使用repeat关键字代替do
var b = 0
repeat {
print(b)
b++
} while b < 10
Swift中的字符串String
OC和Swift中字符串的区别:
- 在OC中字符串类型时NSString,在Swift中字符串类型是String
- OC中字符串@"",Swift中字符串""
- String 是一个结构体,性能更高
- NSString 是一个 OC 对象,性能略差
- String 支持直接遍历
- Swift 提供了 String 和 NSString 之间的无缝转换
//字符串的遍历
var str = "Hello, Swift"
for c in str.characters {
print(c)
}
//字符串的拼接
let str1 = "Hello"
let str2 = "World"
let str3 = str1 + str2 // "HelloWorld"
//和其他数据类型的拼接 使用 \\\\\\\\()
let name = "shei"
let age = 18
let info = "my name is \\\\\\\\(name), age is \\\\\\\\(age)"
//字符串的格式化
let min = 3
let second = 4
let time = String(format: "%02d:%02d", arguments: [min, second]) // 03:04
//字符串的截取
//只提简单的方式,将String转成NSString来使用.格式:(标识符 as NSString)
let myStr = "www.baidu.com"
var subStr = (myStr as NSString).substringFromIndex(2)
subStr = (myStr as NSString).substringToIndex(3)
subStr = (myStr as NSString).substringWithRange(NSRange(location: 4, length: 5))
数组(Array):你猜对了没有NS开头,swift中的数组是一个泛型集合.let修饰不可变数组;var修饰可变数组.
//声明一个Array类型
var array1:Array<String>
var array2: [String]
// 定义一个可变数组,必须初始化才能使用
var array3 : [String] = [String]()
// 定义一个不可变数组
let array4 : [NSObject] = ["666", 66]
// 定义时直接初始化
var array5 = ["Sasuke", "Naruto", "Sakura"]
// 先定义,后初始化
var array6 : Array<String>
array6 = ["Sasuke", "Naruto", "Sakura"]
//对数组的操作
//增
array6.append("abc")
//删
array6.removeLast()
//改
array6[0] = "IU"
//查
array6[2]
//数组的遍历
// 遍历数组
for i in 0..<array6.count {
print(array6[i])
}
// forin方式
for item in array6 {
print(item)
}
// 设置遍历的区间
for item in array6[0..<2] {
print(item)
}
//数组的合并
// 注意:只有相同类型的数组才能合并
var huo = ["Sasuke", "Naruto"]
var ying = ["Sakura"]
var huoYing = huo + ying;
字典:swift中的字典Dictionary,是个泛型集合
// 定义一个可变字典
var dict1 : [String : NSObject] = [String : AnyObject]()
// 定义一个不可变字典
let dict2 = ["name" : "Sakura", "age" : 18]
//声明
var dict3: Dictionary<Int, String>
var dict4: [Int: String]
// 定时字典的同时,进行初始化
var dict = ["name" : "Sakura", "age" : 18]
// swift中任意对象,通常不使用NSObject,使用AnyObject
var dict : Dictionary<String, AnyObject>
dict = ["name" : "Sakura", "age" : 18]
//增
dict["height"] = 1.75
dict["weight"] = 62.0
//删
dict.removeValueForKey("name")
//改
dict["name"] = "abc"
//查
dict["name"]
//遍历字典
// 遍历字典中所有的值
for value in dict.values {
print(value)
}
// 遍历字典中所有的键
for key in dict.keys {
print(key)
}
// 遍历所有的键值对
for (key, value) in dict {
print(key)
print(value)
}
//字典的合并:字典不可以相加合并
var dict1 = ["name" : "hz", "age" : 20]
var dict2 = ["height" : 1.80, "phoneNum" : "114"]
for (key, value) in dict1 {
dict2[key] = value
}
元组
- 元组:swift中特有的,它是一种数据结构,类似字典或数组,用于定义一组数据,内容成为元素.
//使用方法一
let man = ("mfk",27)
print(man.0) //通过.角标的形式取值
print(man.1)
//使用方法二
let man = (name : "mfk", age : 27)
print(man.name) //通过取别名的方式取出值
print(man.age)
//使用方法三
let (name, age)= ( "mfk", 27)
print(name)
print(age)
可选类型:在swift开发中,nil是一个特殊的类型,由于赋值时要明确真实类型,所以不能赋值为nil.但开发中需要赋值nil,因此推出可选类型.
- 取值包括空值和有值
- 定义可选类型一般使用语法糖
//定义的一般写法
let name : Optional<String> = nil // 使用关键字Optional
//语法糖
let name : String? = nil //可选类型中只能存放字符串
name = "mfk"
print(name) // Optional("mfk")\\\\\\\\n 打印结果是可选类型的字符串
print(name!) //mfk\\\\\\\\n 相当是一个强制解包操作,此操作是危险的
//注意:若果可选类型是nil,强制解包,系统会报错.要进行一次判断
if name != nil {
print(name!)
}
//简单写法(可选绑定)
if let nameStr = name {
print(nameStr)
}
函数
- 格式: func 函数名(标识符 : 数据类型 , 等等) -> 返回值类型 {
代码块
return 返回值
} - func为关键字,形参列表内多个参数之间用,号隔开(可以没有参数).箭头是指向的意思,没有返回值可以写Void,也可以省略不写,具体看代码部分
// 1.没有参数,没用返回值
func about() -> Void {
print("666666")
}
// 调用函数
about()
// 简单写法
// 如果没用返回值,Void可以写成()
func about1() -> () {
print("666666")
}
// 如果没有返回值,后面的内容可以都不写
func about2() {
print("666666")
}
about2()
// 2.有参数,没用返回值
func callPhone(phoneNum : String) {
print("打电话给\\\\\\\\(phoneNum)")
}
callPhone(" 110")
// 3.没用参数,有返回值
func readMessage() -> String {
return "吃饭了吗?"
}
var str = readMessage()
print(str)
// 4.有参数,有返回值
func sum(num1 : Int, num2 : Int) -> Int {
return num1 + num2
}
var result = sum(20, num2: 30)
print(result)
- 在函数内部可以看到的参数,就是内部参数
在函数外面可以看到的参数,就是外部参数
默认情况下,从第二个参数开始,参数名称既是内部参数也是外部参数
如果第一个参数也想要有外部参数,可以设置标签:在变量名前加标签即可
如果不想要外部参数,可以在参数名称前加_
// num1和a是外部参数的名称
func ride(num1 num1 : Int, a num2 : Int, b num3 : Int) -> Int {
return num1 * num2 * num3
}
var result1 = ride(num1: 20, a: 4, b: 5)
// 方法的重载:方法名称相同,但是参数不同,可以称之为方法的重载(了解)
func ride(num1: Int, _ num2 :Int) -> Int {
return num1 * num2
}
var result2 = ride(20, 20)
- 默认参数:若果没有传入具体的参数,可以使用默认参数
func giveme(type :String = "coffee") -> String {
return "给我\\\\\\\\(type)。"
}
let me1 = giveme("面包") //给我面包
let me2 = giveme() // 给我coffee
- 可变参数: 可以接受不确定数量的输入类型参数,它们必须具有相同的类型,通过在参数类型名后面加入(...)的方式来指示这是可变参数
func sum(numbers:Double...) -> Double {
var total: Double = 0
for number in numbers {
total += number
}
return total
}
sum(100.0, 200, 300)
sum(3.3, 10.1)
- 引用类型(指针类型):默认情况下,函数的参数是值传递.如果想改变外面的变量,则需要传递变量的地址,必须是变量,因为需要在内部改变其值,Swift提供的inout关键字就可以实现
// 函数一:值传递
func swap(var a : Int, var b : Int) {
let temp = a;
a = b;
b = temp
print("a:\\\\\\\\(a), b:\\\\\\\\(b)")
}
var a = 10
var b = 20
swap(a, b: b)
print("a:\\\\\\\\(a), b:\\\\\\\\(b)")
// 函数二:指针的传递
func swap1(inout a : Int, inout b : Int) {
let temp = a
a = b
b = temp
print("a:\\\\\\\\(a), b:\\\\\\\\(b)")
}
swap1(&a, b: &b)
print("a:\\\\\\\\(a), b:\\\\\\\\(b)")
- 函数的嵌套使用:swift中func可以嵌套使用,方法不推荐(可阅读性差),不多举例子
Swift 中的类
- Swift 中class为定义类的关键字,定义的类,可以没有父类.那么该类是rootClass,通常,定义类时继承自NSObject(非OC的NSObject)
- 类的属性
(1)存储属性:存储实例的常量和变量- 存储属性是最简单的属性,它作为类实例的一部分,用于存储常量和变量;可以给存储属性提供一个默认值,也可以在初始化方法中对其进行初始化.
class Student : NSObject {
// 定义属性
// 存储属性
var age : Int = 0
var name : String?
var chineseScore : Double = 0.0
var mathScore : Double = 0.0
}
// 创建学生对象
let stu = Student()
// 给存储属性赋值
stu.age = 10
stu.name = "why"
stu.chineseScore = 89.0
stu.mathScore = 98.0
(2) 计算属性:通过某种方式计算出来的属性
- 计算属性并不存储实际的值,而是提供一个getter和一个可选的setter来间接获取和设置其它属性,计算属性一般只提供getter方法,则该计算属性为只读属性,并且可以省略get{}
class Student : NSObject {
// 定义属性
// 存储属性
var age : Int = 0
var name : String?
var chineseScore : Double = 0.0
var mathScore : Double = 0.0
// 计算属性
var averageScore : Double {
get {
return (chineseScore + mathScore) / 2
}
// 没有意义,因为之后获取值时依然是计算得到的
// newValue是系统分配的变量名,内部存储着新值
set {
self.averageScore = newValue
}
}
}
// 获取计算属性的值
print(stu.averageScore)
(3) 类属性:与整个类自身相关的属性
- 类属性是与类相关联的,而不是与类的实例相关联
所有的类和实例都共有一份类属性.因此在某一处修改之后,该类属性就会被修改,类属性的设置和修改,需要通过类来完成
class Student : NSObject {
// 定义属性
// 存储属性
var age : Int = 0
var name : String?
var chineseScore : Double = 0.0
var mathScore : Double = 0.0
// 计算属性
var averageScore : Double {
get {
return (chineseScore + mathScore) / 2
}
// 没有意义.newValue是系统分配的变量名,内部存储着新值
set {
self.averageScore = newValue
}
}
// 类属性
static var corseCount : Int = 0
}
// 设置类属性的值
Student.corseCount = 3
// 取出类属性的值
print(Student.corseCount)
监听属性的改变
- 在OC中我们可以重写set方法来监听属性的改变
- Swift中可以通过属性观察者来监听和响应属性值的变化
- 通常是监听存储属性和类属性的改变.(对于计算属性,我们不需要定义属性观察者,因为我们可以在计算属性的setter中直接观察并响应这种值的变化)
- 我们通过设置以下观察方法来定义观察者
- willSet:在属性值被存储之前设置。此时新属性值作为一个常量参数被传入。该参数名默认为newValue,我们可以自己定义该参数名
- didSet:在新属性值被存储后立即调用。与willSet相同,此时传入的是属性的旧值,默认参数名为oldValue
- willSet与didSet只有在属性第一次被设置时才会调用,在初始化时,不会去调用这些监听方法
//监听age和name的变化
class Person : NSObject {
var name : String? {
// 可以给newValue自定义名称
willSet (new){ // 属性即将改变,还未改变时会调用的方法
// 在该方法中有一个默认的系统属性newValue,用于存储新值
print(name)
print(new)
}
// 可以给oldValue自定义名称
didSet (old) { // 属性值已经改变了,会调用的方法
// 在该方法中有一个默认的系统属性oldValue,用于存储旧值
print(name)
print(old)
}
}
var age : Int = 0
var height : Double = 0.0
}
let p : Person = Person()
// 在赋值时,监听该属性的改变
// 在OC中是通过重写set方法
// 在swift中,可以给属性添加监听器
p.name = "why"
//p.name = "yz"