常量与变量

  • 常量与变量必须在使用前声明,用let来声明常量,用var来声明变量。

  • 常量的值一旦设定就不能改变,而变量的值可以随意更改。

  • 常量与变量的命名几乎可以使用任何字符,包括 Unicode 字符:

    let π = 3.14159
    let 你好 = "你好世界"
    let 🐶🐮 = "dogcow"
    
    var friendlyWelcome = "Hello!"
    friendlyWelcome = "Bonjour!"
    
    // print 函数
    print(friendlyWelcome)
    

数据类型

  • Swift 是一门类型安全的语言,所以必须清楚每个变量或常量的数据类型。

  • Swift 提供了多种数据类型,比如整型,浮点型,布尔型,字符串型,字符型,可选型等等。

  • Swift 语言中的数据类型一般都是大写开头的,比如IntFloatDoubleBoolStringCharacterOptional等等。

  • Swift 是强类型语言。

    • 强类型语言:变量的类型一旦被确定,就不能再修改了。

运算

  • Swift 支持常见的运算符,比如加法运算符(+),减法运算符(-),乘法运算符(*),除法运算符(/),求余运算符(%),求反运算符(-),自增运算符(++),自减运算符(--)等等。

  • 值不会隐式转换,如果需要转换类型,必须使用显示转换。

    let label = "The width is "
    let width = 94
    let widthLabel = label + String(width)
    

字符串使用

  • 遍历字符串

    let str = "Hello, Swift!"
    for c in str {
        print(c)
    }
    
  • 字符串拼接

    let str1 = "Hello"
    let str2 = "Swift"
    let str3 = str1 + str2
    print(str3)
    
  • 字符串插值

    let name = "Swift"
    let str = "Hello, \(name)!"
    print(str)
    
  • 字符串长度

    let str = "Hello, Swift!"
    print(str.count)
    
  • 字符串截取

    let str = "Hello, Swift!"
    let index = str.index(str.startIndex, offsetBy: 7)
    let subStr = str[..<index]
    print(subStr)
    
  • 字符串大小写转换

    let str = "Hello, Swift!"
    print(str.uppercased())
    print(str.lowercased())
    
  • 字符串判断前后缀

    let str = "Hello, Swift!"
    print(str.hasPrefix("Hello"))
    print(str.hasSuffix("Swift!"))
    
  • 字符串分割

    let str = "Hello, Swift!"
    let arr = str.split(separator: ",")
    print(arr)
    
  • 使用 2 对 3 引号来创建多行字符串

    let str = """
    Hello, Swift!
    Hello, World!
    """
    print(str)
    

数组使用

  • 创建数组

    var arr1 = [Int]()
    var arr2 = Array<Int>()
    var arr3: [Int] = []
    var arr4: Array<Int> = []
    var arr5 = [1, 2, 3]
    var arr6: [Int] = [1, 2, 3]
    var arr7: Array<Int> = [1, 2, 3]
    
  • 对数组基本操作

    var arr = [1, 2, 3]
    
    // 添加元素
    arr.append(4)
    
    // 插入元素
    arr.insert(5, at: 0)
    
    // 删除元素
    arr.remove(at: 0)
    
    // 修改元素
    arr[0] = 6
    
    // 遍历数组
    for item in arr {
        print(item)
    }
    
    // 设置区间遍历
    for item in arr[0..<2] {
        print(item)
    }
    
    
    // 数组长度
    print(arr.count)
    
    // 数组合并
    var arr1 = [1, 2, 3]
    var arr2 = [4, 5, 6]
    var arr3 = arr1 + arr2
    

字典使用

  • 字典是由两部分集合构成的,一个是键(key)集合,一个是值(value)集合。键集合是不能有重复元素的,值集合可以重复,键和值是成对出现的。

  • 创建字典

    var dict1 = [String: Int]()
    var dict2 = Dictionary<String, Int>()
    var dict3: [String: Int] = [:]
    var dict4: Dictionary<String, Int> = [:]
    var dict5 = ["name": "Swift", "age": 18]
    var dict6: [String: Int] = ["name": "Swift", "age": 18]
    var dict7: Dictionary<String, Int> = ["name": "Swift", "age": 18]
    
  • 字典基本操作

    var dict = ["name": "Swift", "age": 18]
    
    // 添加元素
    dict["height"] = 180
    
    // 删除元素
    dict.removeValue(forKey: "height")
    
    // 修改元素
    dict["age"] = 20
    
    // 遍历字典
    for (key, value) in dict {
        print("\(key): \(value)")
    }
    
    // 遍历字典的键
    for key in dict.keys {
        print(key)
    }
    
    // 遍历字典的值
    for value in dict.values {
        print(value)
    }
    
    // 字典长度
    print(dict.count)
    

元组使用

  • 元组是一种数据结构,可以用来存储多个值,可以是不同类型的值。

  • 创建元组

    var tuple1 = (1, 2, 3)
    var tuple2: (Int, Int, Int) = (1, 2, 3)
    var tuple3: (Int, Int, Int) = (1, 2, 3)
    var tuple4 = (1, "Swift", 18)
    var tuple5: (Int, String, Int) = (1, "Swift", 18)
    var tuple6: (Int, String, Int) = (1, "Swift", 18)
    
  • 元组基本操作

    var tuple = (1, "Swift", 18)
    
    // 获取元素
    print(tuple.0)
    print(tuple.1)
    print(tuple.2)
    
    // 修改元素
    tuple.0 = 2
    
    // 遍历元组
    for item in tuple {
        print(item)
    }
    
    // 元组长度
    print(tuple.count)
    

可选型使用

  • 可选型是一种特殊的数据类型,可以用来存储值或者nil

  • 创建可选型

    var optional1: Int?
    var optional2: Optional<Int> = nil
    var optional3: Int? = nil
    var optional4: Optional<Int> = nil
    var optional5: Int? = 10
    var optional6: Optional<Int> = 10
    
  • 可选类型的使用

    var optional: Int? = 10
    
    // 强制解包
    print(optional!)
    
    // 可选绑定
    if let value = optional {
        print(value)
    }
    
    // 隐式解包
    var optional1: Int! = 10
    print(optional1)
    

    函数使用

    • 函数是一段完成特定任务的独立代码片段,可以通过给函数命名来标识某个函数的功能,需要使用的时候通过函数名来“调用”这个函数完成它的任务。

    • 函数的定义格式如下:

      func 函数名(参数名: 参数类型, 参数名: 参数类型, ...) -> 返回值类型 {
          // 函数体
          return 返回值
      }
      
    • 常见函数类型

      // 无参无返回值
      func test1() {
          print("Hello, Swift!")
      }
      
      // 有参无返回值
      func test2(name: String) {
          print("Hello, \(name)!")
      }
      
      // 无参有返回值
      func test3() -> String {
          return "Hello, Swift!"
      }
      
      // 有参有返回值
      func test4(name: String) -> String {
          return "Hello, \(name)!"
      }
      

外部参数 & 内部参数

  • 外部参数:在函数内部使用的参数名。
  • 内部参数:在函数外部使用的参数名。
// 外部参数 & 内部参数, 如果不想外部参数,可以在参数名前面加 _
func test5(name: String, age: Int) -> String {
    return "Hello, \(name)! You are \(age) years old."
}

默认参数

  • 默认参数:在定义函数的时候给参数赋值,调用函数的时候可以不传递参数。
// 默认参数
func test6(name: String = "Swift", age: Int = 18) -> String {
    return "Hello, \(name)! You are \(age) years old."
}

可变参数

  • 可变参数:一个函数最多只能有一个可变参数,而且可变参数必须是最后一个参数。
// 可变参数
func test7(names: String...) -> String {
    var str = ""
    for name in names {
        str += name
    }
    return str
}

引用参数

  • 引用参数:默认情况下,函数的参数是值传递,如果想要引用传递,需要在参数前面加inout关键字。
// 引用参数
func test8(name: inout String) {
    name = "Swift"
}

方法重载

  • 方法重载:在同一个作用域下,允许存在多个同名函数,只要它们的参数个数或者参数类型不同即可。
// 方法重载
func test9(name: String) -> String {
    return "Hello, \(name)!"
}

func test9(age: Int) -> String {
    return "You are \(age) years old."
}

闭包

  • 闭包是自包含的函数代码块,可以在代码中被传递和使用。Swift 中的闭包与 C 和 Objective-C 中的代码块(blocks)以及其他一些编程语言中的 lambdas 函数比较相似。

  • 闭包的定义格式如下:

    { (参数名: 参数类型, 参数名: 参数类型, ...) -> 返回值类型 in
        // 代码块
        return 返回值
    }
    

闭包使用

// 闭包使用
let closure = { (name: String) -> String in
    return "Hello, \(name)!"
}
print(closure("Swift"))

// 定义网络请求类
class NetworkTool {
    func loadData(completion: @escaping (_ result: [String]) -> ()) {
        DispatchQueue.global().async {
            print("发送网络请求:\(Thread.current)")
            Thread.sleep(forTimeInterval: 1.0)
            let json = ["头条", "八卦", "娱乐"]
            DispatchQueue.main.async {
                print("获取到数据,并且已经解析完成,\(Thread.current)")
                completion(json)
            }
        }
    }
}

// 创建对象
let tool = NetworkTool()
// 调用方法
tool.loadData { (result) in
    print("获取到数据:\(result)")
}

// 闭包简写
tool.loadData(completion: { (result) in
    print("获取到数据:\(result)")
})

闭包循环引用

  • 闭包循环引用:如果在闭包中使用了self,需要注意循环引用的问题。
// 闭包循环引用
class Person {
    var name: String = ""
    lazy var closure: () -> () = {
        print("Hello, \(self.name)!")
    }
    init(name: String) {
        self.name = name
        print("Person init")
    }
    deinit {
        print("Person deinit")
    }
}

var p: Person? = Person(name: "Swift")
p?.closure()
p = nil

懒加载

  • 懒加载:懒加载是指当第一次使用到某个对象的时候才会去创建这个对象,而不是一开始就创建这个对象。
// 懒加载
class Person {
    var name: String = ""
    lazy var closure: () -> () = {
        print("Hello, \(self.name)!")
    }
    init(name: String) {
        self.name = name
        print("Person init")
    }
    deinit {
        print("Person deinit")
    }
}

var p: Person? = Person(name: "Swift")
p?.closure()
p = nil

  • 类是一种复合型的数据类型,它由属性和方法组成。

  • 类的定义格式如下:

    class 类名 {
        属性和方法
    }
    
  • 类的属性和方法

    class Person {
        // 属性
        var name: String = ""
        var age: Int = 0
    
        // 方法
        func run() {
            print("Person run")
        }
    }
    
  • 类的使用

    // 创建对象
    let p = Person()
    // 设置属性
    p.name = "Swift"
    p.age = 18
    
    // 调用方法
    p.run()
    
  • 类的构造函数

    class Person {
        // 属性
        var name: String = ""
        var age: Int = 0
    
        // 构造函数
        init(name: String, age: Int) {
            self.name = name
            self.age = age
        }
    
        // 方法
        func run() {
            print("Person run")
        }
    }
    
  • 类的析构函数

    class Person {
        // 属性
        var name: String = ""
        var age: Int = 0
    
        // 构造函数
        init(name: String, age: Int) {
            self.name = name
            self.age = age
        }
    
        // 析构函数
        deinit {
            print("Person deinit")
        }
    
        // 方法
        func run() {
            print("Person run")
        }
    }
    
  • 类的继承

    // 父类
    class Person {
        // 属性
        var name: String = ""
        var age: Int = 0
    
        // 构造函数
        init(name: String, age: Int) {
            self.name = name
            self.age = age
        }
    
        // 析构函数
        deinit {
            print("Person deinit")
        }
    
        // 方法
        func run() {
            print("Person run")
        }
    }
    
    // 子类
    class Student: Person {
        // 属性
        var score: Int = 0
    
        // 构造函数
        init(name: String, age: Int, score: Int) {
            self.score = score
            super.init(name: name, age: age)
        }
    
        // 析构函数
        deinit {
            print("Student deinit")
        }
    
        // 方法
        func study() {
            print("Student study")
        }
    }
    
  • 监听属性变化

    // 父类
    class Person {
        // 属性
        var name: String = "" {
            // 属性即将发生改变
            willSet {
                print("willSet: \(newValue)")
            }
            // 属性已经发生改变
            didSet {
                print("didSet: \(oldValue)")
            }
        }
        var age: Int = 0
    
        // 构造函数
        init(name: String, age: Int) {
            self.name = name
            self.age = age
        }
    
        // 析构函数
        deinit {
            print("Person deinit")
        }
    
        // 方法
        func run() {
            print("Person run")
        }
    }
    
    // 子类
    class Student: Person {
        // 属性
        var score: Int = 0
    
        // 构造函数
        init(name: String, age: Int, score: Int) {
            self.score = score
            super.init(name: name, age: age)
        }
    
        // 析构函数
        deinit {
            print("Student deinit")
        }
    
        // 方法
        func study() {
            print("Student study")
        }
    }
    
    // 创建对象
    let s = Student(name: "Swift", age: 18, score: 100)
    // 设置属性
    s.name = "Hello"
    

逻辑分支

  • 逻辑分支:根据条件判断来执行不同的代码。

  • if 语句

    let age = 18
    if age >= 18 {
        print("成年人")
    } else {
        print("未成年人")
    }
    
  • switch 语句

    let age = 18
    switch age {
    case 0..<18:
        print("未成年人")
    case 18..<60:
        print("成年人")
    default:
        print("老年人")
    }
    
  • guard 语句

    let age = 18
    guard age >= 18 else {
        print("未成年人")
        return
    }
    print("成年人")
    
    • guard 语句的特点

      • guard 语句必须带有else语句,它的语句只有在条件为false的时候才会被执行,通常用来处理不符合条件的情况,需要提前退出的情况。
      • guard 语句必须在函数体内部,guard语句后面的大括号里面必须要有一条语句,即使是一条空语句。
  • 三目运算符

    let age = 18
    age >= 18 ? print("成年人") : print("未成年人")
    

循环

  • 循环:重复执行某些代码。

  • for-in 循环

    for i in 0..<10 {
        print(i)
    }
    
  • while 循环

    var i = 0
    while i < 10 {
        print(i)
        i += 1
    }
    
  • repeat-while 循环

    var i = 0
    repeat {
        print(i)
        i += 1
    } while i < 10
    

参考资料