前言: 作为一个水平一般,没有追求的OC开发者,从swift1.0开始就买了几本swift参考书,直到现在swift3.0+了还没看完一本完整的swift参考书,没有写过一个完整的swif项目甚是惭愧,其实期间也断断续续学了一阵子,没有坚持住,加之公司项目一直是以OC为主,大量时间浪费在写业务代码,老是抱着swift不成熟,API还不稳定等一等的井底之蛙心态,现在是时候反省下自己了,所谓知途迷返,亡羊补牢,为时不晚。(从现在开始,立刻,马上学习swif的必要性重要性可以参考下微博@没故事的卓同学的文章: Swift 再等等?我的答案是:快上车http://www.jianshu.com/p/2452cb269ae2
话不多说,先撸为敬,以下是记录整理学习小码哥Mr why 的swift课程笔记,以作为复习查看之用
一 . 初识swift
Playground是什么?
从Xcode6开始出现(Swift开始出现) 翻译为:操场/游乐场,对于学习Swift基本语法非常方便,所见即所得(快速查看结果),语法特性发生改变时,可以快速查看.
Swift最基本的语法变化:
- swift中如何导入框架? 直接 import 框架名称 即可
例如 import UIKit - 如何定义标识符?
定义标识符必须告知系统 该标识符是一个变量还是常量
格式: let/var 标识符的名称 : 标识符的数据类型 = 值 - 语句结束有何变化?
一般情况下不需要写; 如果一行中有多条语句;则需要以;分割 - 怎么打印内容?
print(a)
二. 常量&变量
变量的基本使用
let a :Int =40
//a=20// 错误写法,当一个字段定义为常量时是不可以修改的
var b : Int = 60
一般习惯写成 var b = 60 (swift中的类型推导)
变量的基本使用
let a :Int =40
//a=30// 错误写法,当一个字段定义为常量时是不可以修改的
var b : Int = 60
一般习惯写成 var b = 60 (swift中的类型推导)
三. swift中数据类型
swift类型的介绍
Swift中的数据类型也有:整型/浮点型/对象类型/结构体类型等等
先了解整型和浮点型
整型
有符号
Int8 : 有符号8位整型
Int16 : 有符号16位整型
Int32 : 有符号32位整型
Int64 : 有符号64位整型
Int : 和平台相关(默认,相当于OC的NSInteger)
无符号
UInt8 : 无符号8位整型
UInt16 : 无符号16位整型
UInt32 : 无符号32位整型
UInt64 : 无符号64位整型
UInt : 和平台相关(常用,相当于OC的NSUInteger)(默认)
浮点型
Float : 32位浮点型
Double : 64浮点型(默认)
// 定义一个Int类型的变量m,并且赋值为10
var m : Int = 10
// 定义一个Double类型的常量n,并且赋值为3.14
let n : Double = 3.14
swift中的类型推导
swift是强类型的语言
swift中任何一个标识符都有明确的类型
注意:
如果定义一个标识符时有直接进行赋值,那么标识符后面的类型可以省略. 因为swift有类型推导,会自动根据后面的赋值来决定前面的标识符的数据类型
可以通过option+鼠标左键来查看变量的数据类型
// 定义变量时没有指定明确的类型,但是因为赋值给i一个20.20为整型.因此i为整型
var i = 20
// 错误写法:如果之后赋值给i一个浮点型数值,则会报错
// i = 30.5
// 正确写法
var j = 3.33
j = 6.66
swift中基本运算
/
import UIKit
// 定义变量时没有指定明确的类型,但是因为赋值给i一个20.20为整型.因此i为整型
var i=20
//i=30.5 // 错误写法:如果之后赋值给i一个浮点型数值,则会报错
// 正确写法
var j=3.33
j=6.66
/
Swift中在进行基本运算时必须保证类型一致,否则会出错
相同类型之间才可以进行运算
因为Swift中没有隐式转换
数据类型的转化
Int类型转成Double类型:Double(标识符)
Double类型转成Int类型:Int(标识符)
*/
let a = 10
let b = 3.14
// 错误写法
//let c = a + b
//let c = a * b
// 正确写法
let c = Double(a)+b
let d = a + Int(b)
三.逻辑分支
(一). 分支的介绍
分支即if/switch/三目运算符等判断语句
通过分支语句可以控制程序的执行流程
(二). if分支语句
和OC中if语句有一定的区别
判断句可以不加(),在Swift的判断句中必须有明确的真假,不再有非0即真,必须有明确的Bool值,Bool有两个取值:false/true
/
//1 swift 中if的写法
//1> if后面的()可以省略
//2>判断句不在有非0/nil即真,判断句中必须有明确的真假Bool值,Bool值有两个取值:false/tru
// 演练一:
let a = 10
// 错误写法: 不再有非0即真 必须有明确的Bool值 false/true
//if a {
// print("a")
//}
// 正确写法
if a > 9 {
print(a)
}
//2. swift 中else if的用法:用法和if的用法一致
let score = 92
if score < 0 || score>100 {
print("不合理的分数")
} else if score < 60 {
print("不及格")
} else if score < 80 {
print("及格")
} else if score < 90 {
print("良好")
} else if score <= 100 {
print("优秀")
}
/
(三). 三目运算符
Swift 中的 三目 运算保持了和 OC 一致的风格
/
//3. 三目运算符
//取二者最大值
let x = 20
let y = 30
// if写法
//var result = 0
//if m > n {
// result = m
//}else {
// result = n
//}
let result = x > y ? x :y
/
(四).guard的使用
guard是Swift2.0新增的语法
它与if语句非常类似,它设计的目的是提高程序的可读性
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: age)
/
(五).switch分支
switch的介绍
Switch作为选择结构中必不可少的语句也被加入到了Swift中
只要有过编程经验的人对Switch语句都不会感到陌生
但苹果对Switch进行了大大的增强,使其拥有其他语言中没有的特性
switch的简单使用
基本用法和OC用法一致
不同之处:
switch后可以不跟()
case后可以不跟break(默认会有break)
/
//1. switch的基本用法
let sex = 0
switch sex {
case 0:
print("男")
case 1:
print("女")
default:
print("其他")
}
/
简单使用补充1:
一个case判断中,可以判断多个值
多个值以,隔开
/
let sex1 = 0
switch sex1 {
case 0,1:
print("正常人")
default:
print("其他")
}
/
简单使用补充2:
如果希望出现之前的case穿透,则可以使用关键字fallthrough
/
let sex2 = 0
switch sex2 {
case 0:
print("男")
fallthrough
case 1:
print("女")
default:
print("其他")
}
/
Switch支持多种数据类型
浮点型的switch判断
/
let f = 3.14
switch f {
case 3.14:
print("π")
default:
print("not π")
}
/
支持字符串类型
字符串的使用后面会详细讲解
/
let m = 5
let n = 10
var results = 0
let operation = "+"
switch operation {
case "+" :
results = m + n
case "-" :
results = m - n
case "" :
results = m * n
case "/" :
results = m / n
default:
results = 0
print("非法操作符")
}
/*
switch支持区间判断
什么是区间?
通常我们指的是数字区间:010,100200
swift中的区间常见有两种
半开半闭区间:0..<10 表示:0~9,不包括10
闭区间:0...10 表示:0~10
*/
let scores = 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/while,因为for/while最常见
//for循环的写法
// OC写法
//for (int i = 0;i< 10; i++){
// NSLog(@"%d", i);
//}
//swift写法 for后面的()可以省
//最常规写法
// 1.传统写法
//for var i = 0; i <10; i++ {
// print(i)
//}
// 2.区间for循环 for循环的forin写法
for i in 0..<10 {
print(i)
}
//3. 特殊写法:如果在for循环中不需要用到下标i 可以使用 _ 来代替
for _ in 0..<10 {
print("hello")
}
//while和do while循环
//while循环
//1>.while的判断句必须有正确的真假,没有非0即真
//2>.while后面的()可以省略
var a=0
while a < 10 {
a ++
}
//do while循环
//使用repeat关键字来代替了do
let b = 0
repeat {
print(b)
b++
} while b < 20
五. 字符串
字符串的介绍
字符串在任何的开发中使用都是非常频繁的,OC和Swift中字符串的区别,在OC中字符串类型时NSString,在Swift中字符串类型是String
OC中字符串@"",Swift中字符串""
使用 String 的原因:
String 是一个结构体,性能更高, NSString 是一个 OC 对象,性能略差, String 支持直接遍历
Swift 提供了 String 和 NSString 之间的无缝转换
//1. 字符串的定义
//定义不可变字符串
let str = "hello world"
for c in str.characters {
print(c)
}
//2.字符串的使用
//2.1获取字符串的长度
//获取字符集合,再获取集合的count属性
//定义可变字符串
let count = str.characters.count
var str0 = "hello world"
//2.2遍历字符串
for c in str.characters{
print(c)
}
//3.字符串的拼接
//3.1两个字符串之间的拼接
let str1 = "我是码农界"
let str2 = "古天乐"
let str3 = str1 + str2
print(str3)
//3.2字符串和其他标识符之间的拼接
let name = "mxp"
let age = 18
let height = 1.88
let info = "my name is (name), my age is (age), my height is (height)"
//3.3拼接字符串时,字符串的格式化 比如时间:03:04
let min = 2
let second = 18
let timeString = String(format:"%2d:%02d",arguments :[min,second])
print(timeString)
//4.字符串的截取
/*Swift中提供了特殊的截取方式
该方式非常麻烦
Index创建较为麻烦
简单的方式是将String转成NSString来使用
在标识符后加:as NSString即可
*/
let myStr = "www.520.it.com"
var subStr = (myStr as NSString).substring(from: 4)
subStr = (myStr as NSString).substring(to: 3)
subStr = (myStr as NSString).substring(with: NSRange(location:4,length:5))
//swift截取方式
// 4.1定义字符串
let str5 = "http://weibo.com/2187793237/profile?topnav=1&wvr=6"
// 4.2截取开始位置
let fromIndex = str5.startIndex
let header = str5.substring(from: fromIndex)
// 4.3 截取结束位置
//let toIndex = str5.endIndex.advancedBy(-3) //swift2.0写法
let toIndex = str5.index(str5.endIndex, offsetBy: -3) //swift3.0写法
// 4.4 截取中间的字符串
//var range = string.rangeOfString("520")//swift2.0写法
let range = str5.range(of:"520")//swift3.0写法
六. 数组
(一). 数组的介绍
数组(Array)是一串有序的由相同类型元素构成的集合
数组中的集合元素是有序的,可以重复出现
Swift中的数组
swift数组类型是Array,是一个泛型集合
(二). 数组的初始化/定义
数组分成:可变数组和不可变数组
使用let修饰的数组是不可变数组
使用var修饰的数组是可变数组
*/
// 定义一个可变数组,必须初始化才能使用
var arr : [String] = String
// 定义一个不可变数组
let arr0 : [NSObject] = ["Fsociety" as NSObject,28 as NSObject]
//在声明一个Array类型的时候可以使用下列的语句之一
var stuArr1 : Array<String>
var stuArr2 : [String]
//声明的数组需要进行初始化才能使用,数组类型往往是在声明的同时进行初始化的
// 定义时直接初始化
var array = ["古天乐","吴彦祖","陈冠希"]
// 先定义,后初始化
var array0 : Array<String>
array0 = ["古天乐","吴彦祖","陈冠希"]
// (三). 对(可变)数组的基本操作
// 添加数据
array0.append("刘亦菲")
// 删除元素
array0.removeLast()
// 修改元素
array0[1] = "艾薇儿"
// 取值
array0[0]
(四). 数组的遍历
// 遍历数组
for i in 0..<array.count {
print(array[i])
}
// forin方式
for item in array{
print(item)
}
// 设置遍历的区间
for item in array[0..<2] {
print(item)
}
// 遍历数组的同时获取下标值
let names = ["古天乐","吴彦祖","陈冠希"]
for (index, name) in names.enumerated() {
print(index)
print(name)
}
(五). 数组的合并
// 注意:只有相同类型的数组才能合并
var array01 = ["古天乐","吴彦祖","陈冠希"]
var array02 = ["艾薇儿","景甜","范冰冰"]
var array03 = array01 + array02
// 不建议一个数组中存放多种类型的数据
var array04 = [25, 44, "古天乐"] as [Any]
var array05 = ["艾薇儿","景甜","范冰冰",18] as [Any]
array04 + array05
七. 字典
(一). 字典的介绍
字典允许按照某个键来访问元素
字典是由两部分集合构成的,一个是键(key)集合,一个是值(value)集合
键集合是不能有重复元素的,而值集合是可以重复的,键和值是成对出现的
Swift中的字典
Swift字典类型是Dictionary,也是一个泛型集合
*/
//(二). 字典的初始化
//Swift中的可变和不可变字典
//使用let修饰的数组是不可变字典
//使用var修饰的数组是可变字典
// 定义一个不可变字典
let dict = ["name" : "Fsocoiety", "age" : 18] as [String : Any]
// 定义一个可变字典
var dict1 : [String : NSObject] = String :NSObject
//在声明一个Dictionary类型的时候可以使用下面的语句之一
var dict2: Dictionary<Int, String>
var dict3: [Int: String]
//声明的字典需要进行初始化才能使用,字典类型往往是在声明的同时进行初始化的
// 定时字典的同时,进行初始化
var dict4 = ["name" : "Fsocoiety", "age" : 18] as [String : Any]
// swift中任意对象,通常不使用NSObject,使用AnyObject
var dict5 : Dictionary<String, AnyObject>
dict5 = ["name" : "陈冠希" , "age" : 28] as [String : Any] as Dictionary<String, AnyObject>
//(三). 字典的基本操作
// 添加数据
dict5["height"] = 1.89 as AnyObject?
dict5["weight"] = 72.0 as AnyObject?
// 删除字段
dict5.removeValue(forKey: "height")
dict5
// 修改字典
dict5["name"] = "古天乐" as AnyObject?
dict5.updateValue( "古天乐" as AnyObject , forKey: "name")
dict5
// 查询字典
dict5["name"]
//(四).字典的遍历
// 遍历字典中所有的值
for value in dict5.values {
print(value)
}
// 遍历字典中所有的键
for key in dict5.keys {
print(key)
}
// 遍历所有的键值对
//(五).字典的合并
// 字典的合并
var dict6 = ["name" : "PrinceMei","age":18] as [String : Any]
var dict7 = ["height" : 1.88, "Tel" : "+86 18526366356"] as [String : Any]
// 字典不可以相加合并
for (key,value) in dict6 {
dict7[key] = value
}
八. 元组
(一). 元组的介绍
元组是Swift中特有的,OC中并没有相关类型
那什么是元组呢?
它是一种数据结构,在数学中应用广泛
类似于数组或者字典
可以用于定义一组数据
组成元组类型的数据可以称为“元素”
// (二). 元组的定义
//元组的常见写法
("0001","张三丰", 80, 70)
// 给元素加上元素名称,之后可以通过元素名称访问元素
(id : "0001",name: "张三丰", age: 80, weight:70)
// (三). 元组的简单使用
//用元组来描述一个HTTP的错误信息
// 元组:HTTP错误提示
let array = [404, "Not Found"] as [Any]
// 写法一:
let error = (404, "Not Found")
print(error.0)
print(error.1)
// 写法二:
let error1 = (errroCode : 404, errorInfo : "Not Found")
print(error1.errroCode)
print(error1.errorInfo)
// 写法三:
let (errorCode,errorInfo) = (404,"Not Found")
print(errorCode)
print(errorInfo)
/*
九. 可选类型
(一). 可选类型的介绍
注意:
可选类型时swift中较理解的一个知识点
暂时先了解,多利用Xcode的提示来使用
随着学习的深入,慢慢理解其中的原理和好处
概念:
在OC开发中,如果一个变量暂停不使用,可以赋值为0(基本属性类型)或者赋值为空(对象类型)
在swift开发中,nil也是一个特殊的类型.因为和真实的类型不匹配是不能赋值的(swift是强类型语言)
但是开发中赋值nil,在所难免.因此推出了可选类型
可选类型的取值:
空值
有值
*/
// (二). 定义可选类型
//定义一个可选类型有两种写法
//最基本的写法
//语法糖(常用)
// 错误写法
// let string : String = nil //swift2.0
// 注意:name的类型是一个可选类型,但是该可选类型中可以存放字符串.
// 正确写法:
// 写法一:定义可选类型,语法糖(常用, 极力推荐)
let string : String? = nil
// 写法二:定义可选类型
let name : Optional<String> = nil
// (三).可选类型的使用
// 演练一:给可选类型赋值
// 定义可选类型
var string0 : Optional <String> = nil
// 给可选类型赋值
// 错误写法:因此该可选类型中只能存放字符串
//string0 = 134
// 正确写法:
string0 = "I am Handsome"
// 打印结果
print(string0 as Any)
// 演练二:取出可选类型的值
// 取出可选类型的真实值(解包)
print(string0!)
// 注意:如果可选类型为nil,强制取出其中的值(解包),会出错
//string0 = nil
//print(string0!) // 报错
// 正确写法:
if string0 != nil {
print(string0!)
}
// 简单写法:为了让在if语句中可以方便使用string
// 可选绑定
if let str = string0 {
print(str)
}
// (四). 真实应用场景
//目的:让代码更加严谨
// 通过该方法创建的URL,可能有值,也可能没有值.
// 错误写法:如果返回值是nil时,就不能接收了
// 如果字符串中有中文,则返回值为nil,因此该方法的返回值就是一个可选类型,而使用一个NSURL类型接收是错误的
//let url : NSURL = NSURL(String: "www.520it.com") //错误写法
// 正确写法:使用可选类型来接收
//let url : NSURL? = NSURL(String: "www.520it.com")
// 该方式利用类型推导
let url1 = NSURL(string: "www.520it.com")
// 通过url来创建request对象:在使用可选类型前要先进行判断是否有值
// 该语法成为可选绑定(如果url有值就解包赋值给tempURL,并且执行{})
if let tempUrl = url1 {
let request = NSURLRequest(url: tempUrl as URL)
}
十. 类型转化
常见的类型转化符号
is : 用于判断一个实例是否是某一种类型
as : 将实例转成某一种类型
*/
//例子
// 1.定义数组
let array : [AnyObject] = [18 as AnyObject,"Jack" as AnyObject,1.85 as AnyObject]
// 2.取出数组中的第一个元素
let objc = array.first!
// 3.判断第一个元素是否是一个Int类型
if objc is Int {
print("是Int类型")
}else {
print("非Int类型")
}
// 4.将objc转成真正的类型来使用
// 4.1.as? 将AnyObject转成可选类型,通过判断可选类型是否有值,来决定是否转化成功了
let age = objc as? Int
print(age!)
// 4.2.as! 将AnyObject转成具体的类型,但是注意:如果不是该类型,那么程序会崩溃
let age1 = objc as! Int
print(age1)