Swift初看

2022年5月6日 ... ☕️ 3 min read

Swift出来有几年了,之前使用过React native做混合开发,老实说,客户端APP还是一个黑盒。最近突发奇想,试试看不同的开发流程,能不能有新的感悟。作为第一次上手,不免要和自己认知以内的事物做对比,例如JavaScriptTypeScript,和一些更基础的函数式编程、闭包、重载、范型等概念。

以既定的概念去认识新事物,肯定有偏颇,后面能结合新知识加以修正,问题也不大。

SwiftReact或者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的东西。让编译器自己去进行类型推论,如果返回类型冲突,会报错。

#Swift

SideEffect is a blog for front-end web development.
Code by Axiu / rss