1. 基础类型
- Int
- Float
- Double
- Bool
- String
- tuple: 元组,OC中不存在,元组主要可以用于一次性创建或者传递或者返回多个值
- Optional: 可选类型。类似于OC中的空指针,但是可选类型可以作用于任何类型,不仅仅是classes.
2.常量和变量
常量一旦被定义则不可以再被赋值。常量和变量都需要在被使用前被赋值:
-
var
: 用于声明变量 -
let
: 用于声明常量
注意和JS中有所区别
// 常量
// 常量声明之后不能更改 否则会报错
let maximumNumberOfLoginAttempts = 10
// 变量
var currentLoginAttempt = 0
var x = 0.0, y = 0.0, z = 0.0 // 同时声明多个变量 这种形式和JS一个样
// 变量声明之后还可以更改
currentLoginAttempt = 2
3.类型注释
例如:
var welcomeMessage: String;
welcomeMessage = "Hello";
var red, blue, yellow: Double;
// 表示的是 red, blue, yellow 都是 Double 类型
// 等价于
var red: Double
var blue: Double
var yellow: Double
一般我们可以不用定义变量的类型,因为Swift会 隐式类型推断(Type Inference)
4.分号
swift中分号 ;
和JS一样也是可选的,可以加上,也可以去掉,目前看来不使用分号的比较多
let name = "james"; print(name) // ok
// Ok
let age = 18
print(String(age))
5.整型(Integers)
Swift 提供 8, 16, 32, 64 位有符(signed: positive, zero, negative)或者无符(unsigned: positive or zero) 类型的整型。例如
- UInt8
- Int8
- UInt16
- Int16
5.1 整型边界(Integer Bounds)
可以使用 min | max
属性来访问最大值或者最小值
let minValue = UInt8.min // 0
let maxValue = UInt8.max // 255
5.2 Int
大多数情况下,不需要特意选择特别的整型类型,Swift提供了 Int
类型,它对所处平台保持一致的字节数:
- 在 32-bit 平台,Int和 Int32 字节数一样
- 在 64-bit 平台,Int和 Int64 字节数一样
即使在32位平台上,Int类型也能够存储 -2,147,483,648
到 2,147,483,647
区间范围的值。
5.3 UInt
只有在需要无符整型类型的时候才使用 UInt,同样这个类型会和所处平台的字节保持一致
6.浮点(Float | Double)
浮点能够表示的范围比整型更加的宽广,能够存储比Int更大的或者更小的书:
-
Double
: 64位双精度浮点, 至少小数点15位,更偏向于使用Double类型的浮点数 -
Float
: 32位单精度浮点数,小数点6位
将整型强转为Double类型
// 这个和强转为 String 类型一样, String(10)
let a = 10
let b = 3.14
// 抛出错误 Error
// error: binary operator '+' cannot be applied to operands of type 'Int' and 'Double'
let c = a + b
// 强制转换 OK
let c = Double(a) + b
// 开始使用下面方式进行转换 但是会报错 Error
// error: cannot convert value of type 'Int' to type 'Double' in coercion
let c = (a as Double) + b
7.类型推断(Type Inference)
let meaningOfLift = 42 // 推断为 Int
// 对于浮点数 推断为 Double
let pi = 3.14159
// 推断为 Double
let anotherPi = 3 + 0.14159
8.数字字面量(Numeric Literals)
整型字面量可以写为以下形式:
- 10进制(decimal),没有前缀
- 2进制(binary),
0b
作为前缀 - 8进制(octal),
0o
作为前缀 - 16进制(hexadecimal),
0x
作为前缀
// 17 的表示
let decimalInteger = 17
let binaryInteger = 0b10001
let octalInteger = 0o21
let hexadecimalInterger = 0x11
浮点字面量可以是10进制,或者16进制的,它们必须在小数点2侧有数字(或者16进制字符)。
- 10进制浮点可以使用指数,可以是大写的
E
或者 小写的e
- 16进制浮点可以使用指数,可以是大写的
P
或者 小写的p
// 10进制的浮点 带指数
1.25e2 // 表示 1.25 x 10的2次方,或者 125.0
1.25e-2 // 表示 1.25 x 10的负2次方, 或者 0.0125
// 16进制指数
0xFp2 表示 15 x 2的2次方,或者 60.0
0xFp-2 表示 15 x 2的负2次方,或者 3.75
// 表示 12.1875 的方式
let decimalDouble = 12.1875
let exponentDouble = 1.21875e1
let hexadecimalDouble = 0xC.3p0
数字字面量包含其它易读的格式。整型和浮点可以使用填充0并且包含下划线来增加可读性
let paddedDouble = 000123.456 // 123.456
let oneMillion = 1_000_000 // 100万 1000000
let justOverOneMillion = 1_000_000.000_000_1 // 100000.0000001
9.类型转换
// UInt (0 - 255) 无符整型
// 不能为负数报错
let cannotBeNegative: UInt8 = -1
// Int8 不能存储大过最大值 报错
let tooBig: Int8 = Int8.max + 1
let twoThousand: UInt16 = 2_000
let one: UInt8 = 1
// 不同类型不能直接相加 需要先进行转换
let result = twoThousand + UInt16(one)
10.类型别名(typealias)
类型别名一般是在某个上下文环境中该别名更加合适,比如:
typealias AudioSample = UInt16
var maxAmplitudeFound = AudioSample.min // 等价于 UInt16.min
11.布尔值(Bool)
swift 的类型安全不允许非布尔值来表示Bool类型,下面示例会报编译错误:
let i = 1
if i {
// 编译错误
// error: 'Int' is not convertible to 'Bool'
}
上面的写法在JS中没有半点问题(除开书写语法)
写成下面形式则没有问题:
let i = 1
if i == 1 {
// OK
}
12.元组(Tuples)
元组中的值可以是任意类型的,可以不相同:
let http404Error = (404, "Not Found") // (Int, String)
可以解耦元组,和JS中的解构一样:
let (statusCode, statusMessage) = http404Error
print("the status code is \(statusCode)")
// 如果想要忽略某个值
// 可以使用 '_' 作为占位符
let (_, statusMessage) = http404Error
print("hi \(httpMessage)") // "hi Not Found"
元组在函数返回值中特别有用,因为它可以返回不同的类型
13.可选类型(Optionals)
在一个值可能缺失的时候使用可选类型。可选类型在OC或者C中是不存在的。在OC中可以返回nil,否则返回object,但是这只对object有用,对结构体,基本的C类型或者枚举值则没用。OC通常返回一个特殊值(NSNotFound
) 来表示某个值的缺失。
例如, Int
的初始化器(initializer) 有一个尝试将String类型转换成Int类型的功能
let possibleNumber = "123"
// convertedNumber 被推断为 'Int?' 或者 'optional Int' 类型
// 因为 假如 let possibleNumber = "hello" 则转换会失败
let convertedNumber = Int(possibleNumber) // 123
// 转换失败的情形
let possibleNumber = "hello123"
let convertedNumber = Int(possibleNumber) // nil
可选类型表示可能包涵某个类型的值,也有可能根本不存在该值
可以将可选变量设置为nil
// Int? 类型
var serverResponseCode: Int? = 404
serverResponseCode = nil
// 注意不能将一个非可选类型的常量或者变量设置为nil
如果没有给可选类型设置一个初始值,则默认为nil
var surveyAnswer: String? // 默认为nil
13.1 if语句和强制解包(forced unwrapping)
可以使用 if 语句通过对比 nil
来查看某个可选变量是否有值
// 如果一个可选变量有值,则将不等于 nil
// 也就是js里面的不为空
if convertedNumber != nil {
print("convertedNumber 包含某个值")
}
// 再比如
let c: Int? = 0
if c != nil {
print("hello")
}
强制解包: 假如你100%确认某个可选变量包含某个值,则可以在变量名后添加 !
(感叹号),表示强制解包,意味着可以放心的使用
// 字典
let info: Dictionary? = [
"name": "James",
"age": 19
]
// 'info!' 表示对可选类型强制解包
// ?? "Kobe" 表示如果解包失败,则使用默认提供的值("Kobe")
print(info!["name"] ?? "Kobe")
尝试使用 !
访问一个不存在的可选类型值会导致运行时错误。在使用强制解包前,请确保可选类型包含一个 non-nil
(非空值)
13.2 可选绑定(Optional Binding)
使用可选绑定查看是否可选变量是否包含一个值,如果存在值,则将值作为 临时常量或者临时变量。可选绑定可以和 if | while
语句结合使用,既可以检测可选变量是否为空,若非空同时将其赋值给另一个变量
if let constantName = someOptional {
// statements
}
示例:
let possibleNumber = "123"
// 其中 Int(possibleNumber) 返回的是一个 Int? 类型
// 将转换的结果赋值给常量 actualNumber
if let actualNumber = Int(possibleNumber) {
print("\" \(possibleNumber) \" 有一个整型值 \(actualNumber)") // 将会打印这句
} else {
print("转换失败")
}
// 赋值给变量是一样的
if var actualNumber = Int(possibleNumber) {
print("\" \(possibleNumber) \" 有一个整型值 \(actualNumber)") // 将会打印这句
} else {
print("转换失败")
}
可以包含多个可选绑定,使用 ,
分隔开:
if let firstNum = Int("42"), let secondNum = Int("98"),
firstNum < secondNum && secondNum < 100 {
print("\(firstNum) < \(secondNum) < 100")
}
// 打印 42 < 98 < 100
// 上面的式子等价于
if let firstNum = Int("42") {
if let secondNum = Int("98") {
if firstNum < secondNum && secondNum < 100 {
print("\(firstNum) < \(secondNum) < 100")
}
}
}
13.3 隐式解包可选类型(Implicitly Unwrapped Optionals)
有时在第一次赋值后,可以确定一个可选类型总会有值,这种情况下,每次都要去判断和解析可选类型值是非常低效的,因为可以确定它总会有值。这种类型的可选类型称之为隐式解析(或解包?)可选类型。例如将 String?
写为 String!
即可。
隐式解析可选类型主要被用于Swift中类的构造过程中,参考 无主引用以及隐式解析可选属性
一个隐式解析可选类型其实就是一个普通的可选类型,但是可以不需要每次都是用解析来获取可选值:
let possibleString: String? = "一个可选字符串"
let forcedString: String = possibleString! // 需要感叹号来获取值
// 如果不适用 ! 进行解析访问 则会报错
// error: value of optional type 'String?' not unwrapped; did you mean to use '!' or '?'
let forcedString: String = possibleString // 报错
// 声明时使用 String! 表示隐式解析可选类型
let assumedString: String! = "一个隐式解析可选字符串"
let implicitString: String = assumedString // 不需要感叹号
你可以把隐式解析可选类型当做一个可以自动解析的可选类型。你要做的只是声明的时候把感叹号放到类型的结尾,而不是每次取值的可选名字的结尾。
可以把隐式解析可选类型当做普通可选类型来判断是否包含值:
let assumedString: String! = "一个隐式解析可选字符串"
let implicitString: String = assumedString // 不需要感叹号
if assumedString != nil {
print(assumedString)
}
// 也可以在可选绑定中使用饮食街西可选类型来检查并解析它的值
if let definiteStr = assumedString {
print(definiteStr)
}
14.错误处理(Error Handling)
一个函数可以通过声明中添加 throws
关键词来抛出错误消息。当你的函数能抛出错误消息时,则要在表达式中前置 try
关键词
func canThrowAnError() throws {
// 这个函数可能抛出错误
}
do {
try canThrowAnError() // 使用 try
// 没有错误消息抛出
} catch {
// 有一个错误消息抛出
}
swift中可以使用多个 catch 语句
func makeSandwich() throws {
// ...
}
do {
try makeSandwich()
eatASandwich() // 上面没有错误 则执行这一行代码
} catch SandwichError.outOfCleanDishes {
// 如果没有干净盘子了 则去洗盘子
washDishes()
} catch SandwichError.missingIngredients(let ingredients) {
// 如果没有了原材料 则去购买原材料
buyGroceries(ingredients)
}
网友评论