MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

Swift基础语法入门指南

2024-08-221.9k 阅读

1. 变量与常量

在Swift中,变量和常量用于存储值。变量的值可以改变,而常量一旦被赋值就不能再改变。

1.1 声明变量

使用var关键字来声明变量。例如:

var myVariable = 42
var anotherVariable: String = "Hello, Swift!"

在第一个例子中,Swift通过初始值42推断出myVariable的类型为Int。在第二个例子中,明确指定了anotherVariable的类型为String

1.2 声明常量

使用let关键字来声明常量。例如:

let myConstant = 3.14
let greeting: String = "Welcome"

常量一旦声明并赋值,就不能再被修改。试图修改常量会导致编译错误。

2. 数据类型

Swift拥有丰富的数据类型,包括基本数据类型和复合数据类型。

2.1 基本数据类型

  • 整数类型:Swift提供了不同大小的整数类型,如Int8Int16Int32Int64,还有平台无关的Int类型,它的大小与当前平台的原生整数大小相同(在64位平台上是Int64,在32位平台上是Int32)。同样,有UInt(无符号整数)及其对应大小的类型。
let anInt: Int = 10
let aUInt: UInt = 20
let anInt8: Int8 = -128
  • 浮点数类型Float(32位浮点数)和Double(64位浮点数)。Double精度更高,在大多数情况下推荐使用。
let aFloat: Float = 3.14159
let aDouble: Double = 3.141592653589793
  • 布尔类型Bool,只有truefalse两个值。
let isDone: Bool = true
  • 字符类型Character,用于表示单个字符。
let aChar: Character = "A"

2.2 复合数据类型

  • 数组:有序的相同类型元素的集合。可以使用字面量语法创建数组。
var numbers: [Int] = [1, 2, 3, 4]
var strings = ["apple", "banana", "cherry"]

可以通过索引访问数组元素,并且可以修改数组的内容。

print(numbers[0]) // 输出 1
numbers[1] = 20
  • 字典:无序的键值对集合,其中键的类型必须是可哈希的(即遵守Hashable协议)。
var person: [String: Any] = ["name": "John", "age": 30, "isStudent": false]
print(person["name"]) // 输出 Optional("John")
  • 元组:可以将多个不同类型的值组合成一个复合值。
let httpResponse = (404, "Not Found")
print(httpResponse.0) // 输出 404
print(httpResponse.1) // 输出 Not Found

还可以给元组的元素命名:

let anotherResponse = (statusCode: 200, message: "OK")
print(anotherResponse.statusCode) // 输出 200

3. 运算符

Swift支持多种运算符,包括算术运算符、比较运算符、逻辑运算符等。

3.1 算术运算符

  • 加法+
  • 减法-
  • 乘法*
  • 除法/
  • 取余%
let sum = 5 + 3
let difference = 10 - 7
let product = 4 * 6
let quotient = 15 / 3
let remainder = 17 % 5

3.2 比较运算符

  • 等于==
  • 不等于!=
  • 大于>
  • 小于<
  • 大于等于>=
  • 小于等于<=
let isEqual = 5 == 5
let isNotEqual = 3 != 4
let isGreater = 7 > 5
let isLess = 2 < 4
let isGreaterOrEqual = 6 >= 6
let isLessOrEqual = 4 <= 5

3.3 逻辑运算符

  • 逻辑与&&
  • 逻辑或||
  • 逻辑非!
let a = true
let b = false
let andResult = a && b
let orResult = a || b
let notResult =!a

3.4 赋值运算符

  • 简单赋值=
  • 复合赋值:如+=-=*=/=
var num = 5
num += 3 // num 现在是 8
num *= 2 // num 现在是 16

4. 控制流

控制流语句用于控制程序执行的顺序。

4.1 if - else语句

if - else语句用于根据条件执行不同的代码块。

let score = 85
if score >= 90 {
    print("A")
} else if score >= 80 {
    print("B")
} else {
    print("C or below")
}

4.2 switch - case语句

switch - case语句用于对一个值进行多条件匹配。

let day = 3
switch day {
case 1:
    print("Monday")
case 2:
    print("Tuesday")
case 3:
    print("Wednesday")
default:
    print("Other day")
}

Swift的switch - case语句非常灵活,支持多种匹配方式,如区间匹配:

let number = 5
switch number {
case 1...3:
    print("Small number")
case 4...6:
    print("Medium number")
case 7...10:
    print("Large number")
default:
    print("Other number")
}

4.3 for - in循环

for - in循环用于遍历一个序列,如数组、范围等。

let numbers = [1, 2, 3, 4, 5]
for number in numbers {
    print(number)
}

可以使用stride函数来创建自定义步长的范围。

for i in stride(from: 0, to: 10, by: 2) {
    print(i)
}

4.4 while循环

while循环在条件为真时重复执行代码块。

var count = 0
while count < 5 {
    print(count)
    count += 1
}

repeat - while循环先执行一次代码块,然后在条件为真时继续重复执行。

var anotherCount = 0
repeat {
    print(anotherCount)
    anotherCount += 1
} while anotherCount < 5

5. 函数

函数是一段可重复使用的代码块,用于执行特定的任务。

5.1 定义函数

函数使用func关键字定义,有参数列表和返回类型(如果有返回值)。

func addNumbers(a: Int, b: Int) -> Int {
    return a + b
}
let result = addNumbers(a: 3, b: 5)

5.2 无参数和无返回值的函数

func sayHello() {
    print("Hello!")
}
sayHello()

5.3 有默认参数值的函数

func greet(name: String = "Guest") {
    print("Hello, \(name)!")
}
greet() // 输出 Hello, Guest!
greet(name: "John") // 输出 Hello, John!

5.4 可变参数函数

可变参数允许函数接受不确定数量的参数。

func sumOf(numbers: Int...) -> Int {
    var total = 0
    for number in numbers {
        total += number
    }
    return total
}
let sum = sumOf(numbers: 1, 2, 3, 4, 5)

5.5 函数类型

函数在Swift中是一等公民,可以作为参数传递给其他函数,也可以作为返回值。

func multiply(a: Int, b: Int) -> Int {
    return a * b
}
func operate(a: Int, b: Int, operation: (Int, Int) -> Int) -> Int {
    return operation(a, b)
}
let resultOfOperation = operate(a: 4, b: 5, operation: multiply)

6. 闭包

闭包是自包含的代码块,可以在代码中传递和使用。

6.1 闭包表达式

闭包表达式是一种简洁的创建闭包的方式。

let numbers = [1, 2, 3, 4, 5]
let squaredNumbers = numbers.map { (number) -> Int in
    return number * number
}

闭包表达式可以根据上下文推断参数类型和返回类型,从而进一步简化。

let doubledNumbers = numbers.map { $0 * 2 }

6.2 尾随闭包

当闭包是函数的最后一个参数时,可以使用尾随闭包语法。

let sortedNumbers = numbers.sorted { $0 < $1 }

7. 类与对象

类是一种用户定义的引用类型,用于封装数据和功能。对象是类的实例。

7.1 定义类

class Person {
    var name: String
    var age: Int

    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }

    func introduce() {
        print("Hi, I'm \(name) and I'm \(age) years old.")
    }
}

7.2 创建对象

let john = Person(name: "John", age: 30)
john.introduce()

7.3 类的继承

类可以继承自其他类,继承类会继承父类的属性和方法。

class Student: Person {
    var studentID: String

    init(name: String, age: Int, studentID: String) {
        self.studentID = studentID
        super.init(name: name, age: age)
    }

    override func introduce() {
        print("Hi, I'm \(name), a student with ID \(studentID) and I'm \(age) years old.")
    }
}
let mary = Student(name: "Mary", age: 20, studentID: "S12345")
mary.introduce()

8. 结构体

结构体是一种值类型,它也可以封装数据和功能。

8.1 定义结构体

struct Point {
    var x: Int
    var y: Int

    func moveBy(x: Int, y: Int) {
        self.x += x
        self.y += y
    }
}

8.2 创建结构体实例

var point = Point(x: 5, y: 10)
point.moveBy(x: 3, y: 2)

与类不同,结构体是值类型,当传递或赋值时,会进行值拷贝。

9. 枚举

枚举用于定义一组相关的命名值。

9.1 定义枚举

enum Weekday {
    case monday
    case tuesday
    case wednesday
    case thursday
    case friday
    case saturday
    case sunday
}

9.2 使用枚举

let today = Weekday.tuesday
switch today {
case .monday:
    print("It's Monday")
case .tuesday:
    print("It's Tuesday")
// 其他情况类似
default:
    break
}

枚举还可以关联值,例如:

enum Contact {
    case phoneNumber(String)
    case email(String)
}
let myContact = Contact.phoneNumber("123 - 456 - 7890")

10. 协议

协议定义了方法、属性和其他要求的蓝图,类、结构体和枚举可以遵守协议并实现这些要求。

10.1 定义协议

protocol Identifiable {
    var id: String { get }
}

10.2 遵守协议

class User: Identifiable {
    var id: String
    var name: String

    init(id: String, name: String) {
        self.id = id
        self.name = name
    }
}
let user = User(id: "U123", name: "Alice")

协议还可以继承其他协议,并且一个类型可以遵守多个协议。

11. 扩展

扩展用于为现有类型添加新的功能,包括属性、方法、下标等。

11.1 扩展类

class Animal {
    var name: String

    init(name: String) {
        self.name = name
    }
}
extension Animal {
    func speak() {
        print("\(name) makes a sound.")
    }
}
let dog = Animal(name: "Buddy")
dog.speak()

11.2 扩展结构体

struct Rectangle {
    var width: Int
    var height: Int
}
extension Rectangle {
    var area: Int {
        return width * height
    }
}
let rect = Rectangle(width: 5, height: 10)
print(rect.area)

11.3 扩展枚举

enum CompassPoint {
    case north
    case south
    case east
    case west
}
extension CompassPoint {
    func opposite() -> CompassPoint {
        switch self {
        case .north:
            return .south
        case .south:
            return .north
        case .east:
            return .west
        case .west:
            return .east
        }
    }
}
let north = CompassPoint.north
let south = north.opposite()

12. 错误处理

Swift提供了一套强大的错误处理机制,用于处理程序运行时可能出现的错误。

12.1 定义错误

使用枚举来定义错误类型。

enum FileError: Error {
    case fileNotFound
    case permissionDenied
}

12.2 抛出错误

函数可以通过throws关键字声明可能抛出错误,并使用throw关键字抛出错误。

func readFile(atPath path: String) throws -> String {
    if path.isEmpty {
        throw FileError.fileNotFound
    }
    // 实际的文件读取逻辑
    return "File content"
}

12.3 处理错误

使用trytry?try!来处理错误。

do {
    let content = try readFile(atPath: "validPath")
    print(content)
} catch FileError.fileNotFound {
    print("File not found")
} catch FileError.permissionDenied {
    print("Permission denied")
} catch {
    print("Other error: \(error)")
}
let optionalContent = try? readFile(atPath: "invalidPath")
if let content = optionalContent {
    print(content)
} else {
    print("Error occurred")
}
// try! 用于确定不会抛出错误的情况,否则会导致运行时崩溃
let content = try! readFile(atPath: "alwaysValidPath")

13. 泛型

泛型允许编写可以适用于多种类型的代码,提高代码的复用性。

13.1 泛型函数

func swapValues<T>(_ a: inout T, _ b: inout T) {
    let temp = a
    a = b
    b = temp
}
var num1 = 5
var num2 = 10
swapValues(&num1, &num2)
var str1 = "Hello"
var str2 = "World"
swapValues(&str1, &str2)

13.2 泛型类型

struct Stack<T> {
    private var items: [T] = []

    mutating func push(_ item: T) {
        items.append(item)
    }

    mutating func pop() -> T? {
        return items.popLast()
    }
}
var intStack = Stack<Int>()
intStack.push(10)
let poppedInt = intStack.pop()
var stringStack = Stack<String>()
stringStack.push("Apple")
let poppedString = stringStack.pop()

13.3 类型约束

可以对泛型类型添加约束,限制可以使用的类型。

func findIndex<T: Equatable>(of element: T, in array: [T]) -> Int? {
    for (index, value) in array.enumerated() {
        if value == element {
            return index
        }
    }
    return nil
}
let numbers = [10, 20, 30]
let index = findIndex(of: 20, in: numbers)

通过以上内容,你已经对Swift的基础语法有了较为全面的了解,可以开始编写简单的Swift程序,并逐步深入学习更高级的特性。