01、swift 基础内容

变量与常量

常量

  • let 关键字声明
  • 声明之后不可以修改值
    1
    2
    3
    4
    let name = 'test'

    // 这是错误的
    name = 'test2'

变量

  • var 关键字声明
  • 声明之后可以修改值
    1
    2
    3
    var name = 'test'

    name = 'test2'

类型标注

  • 在常量 或 变量后面加 : Typename 即是类型标注
  • 明确了该常量 或 变量允许存储何种类型字符
    1
    2
    3
    4
    var welcomeMessage: String = "hello"

    // 这是错误的
    welcomeMessage = 123 // 该变量已声明为字符串类型,只允许存储字符串

命名方法

  • 采用小驼峰写法
    1
    2
    let firstName = "杨"
    var lastName = "圆建"

输出常量和变量

  • 在字符串中,用 \(varibaleName) 可以输出变量或常量值
    1
    2
    3
    let fristName = "杨"
    var lastName = "圆建"
    print("他的名字是:\(firstName)\(lastName)") // 输出:他的名字是:杨圆建

注释

单行注释

1
// 这是单行注释

多行注释

1
2
3
4
5
6
/* 这是多行注释
多行注释啊 */

/* 这是第二种多行注释啊
/* 第二种多行注释啊 */
这种注释是不是很奇葩 */

分号

  • Swift 并不要求你在每一句代码结尾写分号( ; ), 在一行中写多句代码还是需要的
    1
    2
    3
    4
    // 这是正确的写法
    let firstName = "杨";
    let lastName = "圆建"
    let cat = "?"; print(cat)

整数

  • 整数就是没有小数部分的数字,比如 42 和 -43。整数可以是有符号(正、零、负数)和无符号(正数、零)
  • swift 提供了 8、16、32、64 位编码的有符号和无符号整数,这些整数类型的命名方式和 C 相似,例如 8 位无符号数的类型是 UInt8,32位有符号整数是 Int32

整数范围

  • 可以通过 minmax 来确定每个整数类型的最小值和最大值
    1
    2
    let minValue = UInt8.min // 最小值 0,值的类型是 UInt8
    let maxValue = UInt8.max // 最大值 255,值的类型是 UInt8

Int

  • swift 提供了一个额外的整数类型 Int,它与当前平台的原生字长度相同
  • 在项目中,如无特殊情况,一般都用 IntUInt 来声明
  • 在 32 位平台上,Int 的长度和 Int32 相同
  • 在 64 位平台上,Int 的长度和 Int64 相同
  • Int 在 32 位平台上存储大小为 -2147483648 - 2147483647 之间的任意值

UInt

  • swift 也提供了一个额外的无符号整数类型,UInt,它与当前平台的原生字长度相同
  • 在 32 位平台上,UInt 的长度和 UInt32 相同
  • 在 64 位平台上,UInt 的长度和 UInt64 相同

数值型字面量

  • 一个十进制数,没有前缀
  • 一个二进制数,前缀:0b
  • 一个八进制数,前缀:0o
  • 一个十六进制数,前缀:0x
    1
    2
    3
    4
    5
    // 下面这些字面量都是十进制 17
    let decimalInteger = 17
    let binaryInteger = 0b10001
    let octalInteger = 0o21
    let hexadecimalInteger = 0x11

十进制指数

  • 1.25e2 = 1.25 x 102 = 125.0
  • 1.25e-2 = 1.25 x 10-2 = 0.0125

    十六进制指数

  • 0xFp2 = 15 x 22 = 60.0
  • 0xFp-2 = 15 x 2-2 = 3.75

    数值型字面量可读性

  • 可以使用 _ 来增强可读性
    1
    2
    3
    let paddedDouble = 000123.456
    let oneMillion = 1_000_000
    let justOverOneMillion = 1_000_000.000_000_1

数值类型转换

整数转换

  • 不同整数的类型存储的数字范围是不同的, Int8 类型可以存储数字范围是 -128 ~ 127, 而 UInt8 类型可存储数字范围是 0 ~ 255, 如果数字超出了可存储范围,编译或运行就会报错

    1
    2
    let cannotBeNegative: UInt8 = -1 // 这是错误的,无符号 UInt8 存储范围是 `0~255`
    let tooBig: Int8 = Int8.max + 1 // 这是错误的,Int8 存储范围是 `-128 ~ 127`
  • 不同类型转换

    • 需要声明一个新的类型变量或常量
      1
      2
      3
      let towThousand: UInt16 = 2_000
      let one: UInt8 = 1
      let twoThousandAndOne: UInt16 = twoThousand + UInt16(one)

整数和浮点数转换

  • 必须要转成相同的数据类型
    1
    2
    3
    4
    5
    6
    7
    let one = 1
    let point = 23.12934
    let oneAndPoint: Double = Double(one) + point

    let two = 2
    let random = 0.11123
    let twoAndRandom: Double = Int(random) + two

类型别名

  • typealias 可以对类型重新定义一个新的名字
    1
    typealias AudioSample = UInt16

布尔值

1
2
let isTrue = true
let isFalse = false

元组

  • 元组内的值可以是任何类型,而且可以不必是同一类型,等同于 PHP 中的一维数组,如果要想实现比较复杂的数据结构,需要定义结构体来代替元组
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    let http404Status = (404, "Not Found")

    let (statusCode, statusMessage) = http404Status
    print("当前状态码是: \(statusCode)")
    print("当前状态值是: \(statusMessage)")

    // 分解元组的时候,如果只需要使用其中的一部分数据,不需要的数据可以用下划线 ( `_` )代替
    let (justTheStatusCode, _) = http404Status
    print("当前状态码是: \(justTheStatusCode)")

    // 可以通过索引数字访问元组中的单独元素
    print("The status code is \(http404Status.0)")
    print("The status message is \(http404Status.1)")

    // 可以给元组的元素设置键名
    let http200Status = (statusCode: 200, description: "200")
    print("The status code is \(http200Status.statusCode)")
    print("The status message is \(http200Status.description)")


    let http

可选项

  • 意味着值有可能存在 或者 根本没有值,在没有值得情况下,可选项将返回 nil
    1
    2
    3
    4
    let possibleNumber = "123"
    let convertedNumber = Int(possibleNumber)
    // 这里初始化可能会失败,所以他会返回一个可选的值
    let convertedNumber: Int? = Int(possibleNumber)

nil

  • 可以给可选变量赋值一个 nil 来将之设置为没有值

    1
    2
    var serverResponseCode: Int? = 404
    serverResponseCode = nil
  • 如果可选变量没有提供一个默认值,变量回自动被设置成 nil

    1
    var surveyAnswer: String?

if 语句以及强制展开

  • 可以通过 if 语句和 nil 比较来判断一个可选类型是否包含值,可以使用 ==!= 来比较

    1
    2
    3
    4
    5
    let possibleNumber = "123"
    let convertedNumber = Int(possibleNumber)
    if convertedNumber != nil {
    print("convertedNumber 包含值")
    }
  • 当你确定可选类型确实包含值之后,可以在可选的名字后面加一个 ! 来获取值,! 表示这个可选类型存在具体的值,请强制使用这个值

    1
    2
    3
    4
    5
    let possibleNumber = "123"
    let convertedNumber = Int(possibleNumber)
    if convertedNumber != nil {
    print("convertedNumber 存在值: \(convertedNumber!)")
    }

使用 ! 来获取一个不存在的可选值会导致运行时错误,使用 ! 来强制展开值之前,一定要确保可选类型存在值

可选类型绑定

  • 使用可选类型绑定来判断可选类型是否包含值,如果包含就把值赋给一个临时常量或者变量,可选绑定可以用在 ifwhile 语句中,这条语句不仅仅可以用来判断可选类型中是否有值,同时也可以将可选类型中的值赋给一个常量或者变量。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    if let constantName = someOptional {
    // do something ...
    }
    // 可以将下面的代码按照上面的格式去写
    let possibleNumber = "123"
    if let actualNumber = Int(possibleNumber) {
    print("存在值: \(actualNumber)")
    } else {
    print("不存在值: nil")
    }

    // 可多个可选类型绑定写在一个 `if` 语句中
    if let firstNumber = Int("4"), let secondNumber = Int("42"), firstNumber < secondNumber {
    print("\(firstNumber) < \(secondNumber) < 100")
    }

    if let firstNumber = Int("4") {
    if let secondNumber = Int("3") {
    if firstNumber < secondNumber {
    print("\(firstNumber) < \(secondNumber) < 100")
    }
    }
    }

隐式展开可选类型

  • 在程序设计中,很多变量或者常量被定义后,可以确定总会有值,这样的情况下每次都要判断和解析可选值是非常低效的
  • 为了解决这个问题,可以在可选的类型后面的 ? 改成 ! 来声明一个隐式解析可选类型
  • 隐式解析可选类型主要用在 Swift 中类的构造过程中
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    let possibleString: String? = "An optional string"
    let forcedString: String = possibleString! // 需要加感叹号

    let assumedString: String! = "An implicitly unwrapped optional string"
    let implicitString: String = assumedString // 不需要加感叹号

    // 任然可以把隐式解析可选类型当做普通可选类型来判断他是否包含值
    if assumedString != nil {
    print(assumedString)
    }

    if let definiteString = assumedString {
    print(definiteString)
    }

错误处理

断言与先决条件

  • 如果布尔条件在断言或先决条件中计算为 true, 则代码继续运行, 如果为 false 则代码停止运行, app 将会中止

    使用断言进行调试

    1
    2
    let age = -3
    assert(age >= 0, "A person's age cannot be less that zero")
  • 如果已经检查了条件,可以使用 assertionFailure(_:file:line) 函数来断言失败,比如:

    1
    2
    3
    4
    5
    6
    7
    8
    let age = -3
    if age > 10 {
    print("age 大于 10")
    } else if (age > 0) {
    print("age 大于 0")
    } else {
    assertionFailure("错误啦")
    }

强制先决条件

1
precondition(index > 0, "索引必须大于 0 ")
0%