变量和常量
使用关键字let 声明常量
使用关键字var 声明变量
let hoursOneday = 24
var currentHour = 10
hoursOneday = 25 // error
curentHour = 12
var x = 0, y = 0, z = 0, des = "trangle"
标注变量或常量的类型
var personName : String
personName = "davin"
personName = 18 // error
Swift是类型安全的语言, 明确变量或常量存储的值类型之后, 不可以赋值其他类型的值,会导致编译报错。
变量和常量的命名
Swift可以使用更多的字符来给变量和常量命名, 如:Unicode字符,表情符,制表符等。
但不能包含空白字符,箭头等,也不能以数字开头
let 🐶 = “dog”
var 你好 = “hello”
print("\(你好)\(🐶) ,欢迎你") //字符串插值: \()
数值类型
整数
Swift 提供了8, 16, 32, 64位编码的有符号和无符号整数
命名方式: UInt8, Int32 ... ... Int, UInt
Int 和 UInt 拥有与当前平台的原生字相同的字节长度
通过 max 和 min 属性可以访问每个整数类型的最小值 和 最大值
let a : UInt8 = 256 //error overflow 超出取值范围
print("UInt8 最小值:\(a.min), 最大值: \(a.max)) => Uint8 最小值: 0, 最大值: 255
浮点数
Double : 64位浮点数, 精度 至少有15位
Float: 32位浮点数, 精度至少有6位
Bool
取值范围为:true & false
Swift的类型安全机制会阻止使用一个非布尔量的值替换掉Bool
let i = 1
if i { // error
}
需修改成
if i==1 {
}
类型别名
使用关键字 typealias , 为已存在的类型定义别名, 以更符合业务场景
typealias Age = UInt8
let age: Age = 18
Tuple
元组可以将多个值 合并成 单一的复合值 类型, 元组内的值可以是任意类型, 且不必是同一类型
let error = (401, "客户端错误")
print(error)
元组内的元素可以指定对应的名称 (如果没有对应的元素名, 也可以使用下标访问)
let error = (errorCode: 401, errorMessage: "客户端错误")
print(error.errorCode)
print(error.errorMessage)
Tuple的修改
- 使用
var声明的 元组 就是可变元组,let定义的 就是 不可变元组\ - 不管是可变 还是 不可变, 元组在创建后,就不能增加 和 删除 元素\
- 可以对可变元组的元素进行修改, 但是不能改变其元素类型\
- 如果元组的元素类型是Any类型, 可以改为任意类型
var error = (errorCode: 401, errorMessage: "客户端错误")
error.errorCode = 502
error.errorMessage = "服务端错误"
error.erroMessage = 502 //error 类型不匹配,也可以通过下面的解法处理
var error : (errorCode: Int, errorMessage: Any) = (errorCode : 401, errorMessage: "客户端错误")
error.errorCode = 502
error.errorMessage = 502
Tuple的分解
将一个元组的内容分解成单独的常量或变量
如果只使用其中的一部分数据, 不需要的数据可以用下划线(_)替代
let error = (401, "客户端错误")
let (errorCode, errorMessage) = error
print(errorCode)
print(errorMessage)
let (_, errorMessage2) = error
print(errorMessage2)
Tuple作为函数返回值
使用Tuple为函数 返回 多个返回值
返回值的 Tuple 可以在函数的返回类型部分被命名
func httpRquest(url:String) -> (errorCode : Int, errorMessage : Any) {
return (401, "客户端错误")
}
Optional
为什么需要Optional?
OC中的 nil 是无类型的指针(如果想表示 某一个具体类型的nil, 无法区分, 因为都是nil)
OC中的 数组, 字典, 集合等 不允许传入nil(无法将空置作为占位符放在集合里)
OC中 所有对象的变量都可以为nil (需要很多空值判断, 来进行下一步的操作)
OC中 nil 只能用在对象上,而在其他地方又有其他特殊值, 如 NSNotFound, 表示值的缺失
所以 Swift 引入了 Optinal,通过在变量后面加 ?来表示, 他有两层含义:
- 这里有一个值, 值为x
- 这里根本没有值
可以将 可选变量 赋值为nil 来将其设置为没有值
OC 中的nil 是 一个指向不存在对象的指针
Swift中, nil 不是指针, 而是一个值缺失的特殊类型, 任何类型的可选项都可以设为nil(不仅是对象) Swift中, 只有可选项 才可设为nil
var str:String? = "abc"
let strCount = str.count //error
可选项 是无法直接使用的,需要用!展开后才可使用(意思是我清楚可选项的内容有值, 可以展开)
Optional-if 展开
// Optional - if 展开
var str:String? = "abc"
if str!=nil {
let count = str!.count
}
Optional 强制展开
// Optional 强制展开, 需保证可选值非空
var str:String? = "abc"
let count = str!.count
var str:String? = nil
let count = str!.count //error
Optional Binding
可以使用可选项绑定 来 判断可选项是否包含值, 如果包含就把值赋给一个临时的常量或变量
可选绑定可以与 if 和 while 的语句使用来检查可选项内部的值, 并赋值给一个常量或变量
同一个if 语句中可以包含多个 可选项绑定,用逗号分隔, 如果任一可选绑定结果是nil 或者 布尔值为false, 那么整个if 判断会被看作false
var str:String? = "abc"
if let actualstr = str { // 判断str是否为nil, 如果不为nil 则赋值给actualstr
let count = actualstr.count
print(count)
}
Optional 隐式展开
有些可选项一旦被设定值后, 就会一直拥有值,在这种情况下, 就可以去掉检查,也不必每次访问的时候都进行展开
通过在声明的类型后加叹号(String!)而非问好(String?)来书写隐式展开可选项
隐式展开可选项主要被用在Swift的初始化过程中
var str:String! = "abc"
let count = str.count
print(count)
Optional Chaining
可选项后面加问号?
如果可选项不为nil, 返回一个可选项结果, 否则返回nil
var str:String? = "abc"
let count = str?.count
let count2 = count - 1 // error, 因为count 此时还是一个可选项, 需要对count进行 强制展开 或 判断展开,绑定等才可以使用
Nil-Coalescing Operator
使用空合运算符 ?? 来提供默认值
let imagePaths = ["star": "/glyphs/star.png", "portrait": "/images/content/portrait.jpg", "spacer": "/images/shared/spacer.gif"]
let defaultImagePath = "/images/default.png"
let heartPath = imagePaths["heart"] ?? defaultImagePath
print(heartPath)
// Prints "/images/default.png"
?? 操作符还可以与右边的另一个' Optional '实例一起使用。因此,您可以链接多个?? 操作符在一起。
let shapePath = imagePaths["cir"] ?? imagePaths["squ"] ?? defaultImagePath
print(shapePath)
// Prints "/images/default.png"
Optional 的原理
A type that represents either a wrapped value or the absence of a value.
@frozen public enum Optional<Wrapped> : ExpressibleByNilLiteral {
case none
case some(Wrapped)
public init(_ some: Wrapped)
@inlinable public func map<U>(_ transform: (Wrapped) throws -> U) rethrows -> U?
@inlinable public func flatMap<U>(_ transform: (Wrapped) throws -> U?) rethrows -> U?
public init(nilLiteral: ())
@inlinable public var unsafelyUnwrapped: Wrapped { get }
Optional 类型实际是标准库里的一个 enum 类型, 它包含两个可选值: Optional.none & Optional.some(Wrapper)
Optional.none : 代表没有值
Optional.some(Wrapper) : 代表有值,且值是x
let str : String? = “abc”
等价于
let str : Optional<String> = “abc”
Int? 相当于简写
let number: Int? = Optional.some(42)
let noNumber: Int? = Optional.none
print(noNumber == nil)
// Prints "true"
unsafelyUnwrapped 函数 相当于存储的是 Optional 包装的值, 等价于 !操作符, 如果使用此函数展开, 要确保包装值不为nil!!
let number: Int? = Optional.some(42)
let noNumber: Int? = Optional.none
let num1 = number.unsafelyUnwrapped //42
let num2 = noNumber.unsafelyUnwrapped // error