Swift初看
2022年5月6日 • ... • ☕️ 3 min read
Swift
出来有几年了,之前使用过React native
做混合开发,老实说,客户端APP还是一个黑盒。最近突发奇想,试试看不同的开发流程,能不能有新的感悟。作为第一次上手,不免要和自己认知以内的事物做对比,例如JavaScript
、TypeScript
,和一些更基础的函数式编程、闭包、重载、范型等概念。
以既定的概念去认识新事物,肯定有偏颇,后面能结合新知识加以修正,问题也不大。
Swift
和React
或者Flutter
一样,使用声明式或者函数式的方式进行界面开发。Swift
是支持头等函数(first class function)的编程语言。
// 首页,入口是@main
import SwiftUI
@main
struct MemorizeApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
struct ContentView: View {
var body: some View {
Text("Hello, world!")
}
}
声明之后,框架会按照View
的结构,以合适的方式渲染。
闭包
闭包是在支持头等函数的编程语言里,实现词法绑定的一种技术。闭包首先表现为一个结构体,存储了一个函数和一个关联环境(上下文环境),环境里是一些key:value
形式的键值对应关系,包括函数内部变量和自由变量。
链式调用
Swift
使用链式调用修改对象。在View
定义里随处可见链式调用。
var body: some View {
return RoundedRectangle(cornerRadius: 25)
.stroke(lineWidth: 3)
.padding(.horizontal)
}
变量
Swift
使用var
定义变量,然后使用type
进行类型约束。例如
var i: Int
var s: String
由于Swift
是一种类型推断语言,所以变量可以从存储的值推断类型。和TypeScript
是一样的。
let player = "Jack"
print(player) // 自动推断为string类型
可选类型Optional
表示可能包含某个类型,或者不包含任何类型。注意这里是包含,不是类型判断。他其实是一个包装类型。要取得包含的值,就需要进行解包,在Swift
里,需要用!来强制解包,注意强制解包是一种很危险的行为,一旦解包失败,就有崩溃的可能,所以安全的解包行为应该是通过if let
或者guard let
来进行。
func getHeight(_ height: Float?) -> Float? {
if let unwrapedHeight = height {
return unwrapedHeight / 100
}
return nil
}
// or
func getHeight(_ height: Float?) -> Float? {
guard let unwrapedHeight = height else {
return nil
}
return unwrapedHeight / 100
}
Swift
里只有Optional
类型可以赋值为nil
。
协议
协议的定义方法和类、结构体、枚举定义看起来类似:
protocol SomeProtocol {
// protocol定义
}
某个类、结构体和枚举都可以遵循协议,并为协议定义的这些要求提供具体实现。
View
View
是一个视图协议,任何自定义视图都应该遵循该协议,并实现协议属性body
来提供具体的视图内容和行为。它属于Swift
的核心协议。它包含associatedtype
,所以会作为类型约束使用,它声明的是数据结构的描述。理解上,有点类似TypeScript里的范型。
当内部的状态发生改变的时候,框架会调用声明的代码,重新计算结果,和之前的View
进行diff,然后框架重新绘制变更的部分。
返回内容虽然是一个Text函数的调用返回,但是类型不能是Text
,只能是some View
,就是因为associatedtype
做了限制。
some View
some View
表示的是,这个东西返回的不知道是什么,但是肯定是遵守View
的东西。让编译器自己去进行类型推论,如果返回类型冲突,会报错。