Swift 笔记-1 基本类型,集合类型,控制流与基本函数

发布时间 2023-12-22 13:47:54作者: 我听不见

最近对 iOS 开发有兴趣,学习 SwiftUI,主要跟的是 hackingwithswift 的 swiftui 教程,这个教程做的非常棒
在这里简单记录一下

基本类型

变量与常量

变量 var 常量 let
swift 的常量控制更加严格,像结构体声明为常量是无法修改内部的值的,不像 js 的 const 对象还可以修改内部值,不过 struct 定义也不是引用类型
声明带有自动类型推导,就像 golang 中的 a := 3,但是自动推导有时候会产生误导,所以需要明确指定类型

var number: Double = 2 // 如果用自动推导就会得到一个整型

字符串

单行

let str1 = "A"
let str2 = "A \(str1)" // 插值表达式,类似于 js 中的 `abc ${variable}`,python 中的 `name = f"hello {variable}"`

多行

let movie = """
A day in
the life of an
Apple engineer
"""

类似于 python 中的注释语法

类似于 php 的 heredoc 语法,php 的末尾的符号必须贴边,swift 不用,但是不得超过字符起始位置

$a = <<<DOC

DOC;

字符串像是被装箱过的,可以直接在字符串上调用方法

str.hasPrefix("ABC")
str.hasSuffix("ABC")

整型

这个 Int 型细分种类(U)Int (U)Int8 (U)Int16 (U)Int32 (U)Int64,但是官方建议通常只使用 Int,除非特别清楚自己在干什么

let cost = 18
print(cost.isMultiple(of: 6))

基本类型都带一种装箱功能

浮点

一样的,绝大大部分现代语言最佳实践都是强烈建议用 Double,把 Float 扔了吧

let height = 185.5 // 自动类型推导默认也是 Double 类型

布尔值

var timeout = false
timeout.toggle() // true

集合类型

数组

var games = ["factorio", "gta5", "diablo"]
// 非推导形式类型声明 1
// var games: Array<String> = ["factorio", "gta5", "diablo"]
// 非推导形式类型声明 2
// var games: [String] = ["factorio", "gta5", "diablo"]
// 空数组创建
// var foo = [String]()
// var bar: [String] = []
games.append("starcraft") // 所有数组项数据类型必须一致
print(games.count()) // 4
games.remove(at: 0) // 注意到 `at:` 了吗,这个非常有意思
games.contains("gta5") // true

字典 Dictionaries

和 js 差不多,除了括号不一样

let book = [
	"name": "the c programming language",
	"isbn": "xxx",
]
// 非推导形式类型声明 1
// let book: Dictionary<String, String> = [
	// "name": "the c programming language",
	// "isbn": "xxx",
// ]
// 非推导形式类型声明 2
// let book: [String: String] = [
	// "name": "the c programming language",
	// "isbn": "xxx",
// ]
print(book[name, default: "empty"]) // 数组访问 [index] 外还支持 `defualt: "value"` 语法糖,类似于 optional 的 `book[name] ?? "empty"`

集合 Sets

不能重复,不保证有序的类型
js 也在 es6 引入了这种类型,去重挺好用

var colors = Set(["Red", "Black", "White"])
// 非推导形式类型声明
// var colors: Set<String> = Set(["Red", "Black", "White"])
print(colors)
colors.insert("Blue")
colors.contains("Black") // 

contains 在 Set 中是一个查找算法复杂度优势的操作(相比于数组)

even a set with 10,000,000 items will respond instantly

枚举 Enums

swift 中的枚举是强化过的,可以带方法

enum Version {
	case A, B, C, D
}

var gv = Version.A
gv = .B // 直接忽略了前置调用对象
gv = .D

var gv2: Version = .A

控制流

条件判断

类似 golang 的判断语法格式

if a < 10 {
	print(10)
} else if a < 20 {
	print(20)
} else {
	print(30)
}

switch 特殊一点,不需要 break,必须完全枚举所有可能性,无法穷举的值类型就使用 default:

let variable = 10
switch variable {
	case 1:
		print(1)
	case 2:
		print(2)
	default:
		print(3)
}

有三元操作符

循环

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

// 这种写法于 ruby 一样,... 与 .. 的区别来控制是否包含末尾的值
for c in 1...3 { // 含有3本身
	print(c)
}
for d in 1..< 3 { // 不含 3
	print(d)
}

使用下划线对值进行忽略

var timer = 10
while timer > 0 {
	timer -= 1
}

循环同样支持国际惯例的 continuebreak

代码块抽象结构

函数

声明函数

使用 func

func foo(number: Int) {
    print(number)
}
foo(number: 10) 

函数的参数名 number 必须在调用的时候明确指明,除非你使用 _ 表示忽略

func foo(_ number: Int) {
    print(number)
}
foo(number: 10) 

swift 函数拥有参数别名这种东西

返回类型声明

func foo(number: Int) -> Int {
    return number
}
// 只有一行可以不写 return
func foo(number: Int) -> Int {
    number
}

返回多个值

func getPoint() -> (x: Int, y: Int) {
	(x: 10, y: 20)
}
let point = getPoint()
print("x: \(point.x)" y: \(point.y))

可以使用 _ 忽略多值返回中的某个值

自定义参数标签

增强函数语境上下文,name 给调用方使用,str 函数内部使用

func printUser(name str: String) {
	print(str)
}

printUser(name: "Alice")

函数参数默认值

func printUser(name: String = "Bob") {
	print(name)
}
printUser()

函数与错误

声明

enum HttpError: Error {
	case ClientError, ServerError
}

func check(_ statusCode: Int) throws -> String {
	if statusCode == 400 {
		throw HttpError.ClientError
	}

	if statusCode == 500 {
		throw HttpError.ServerError
	}

	return "OK"
}

调用

let code = 300

do {
	let res = try check(code)
	print("response is \(res)")	
} catch HttpError.ClientError {
	print("client error")						   
} catch {
	print("error")	 
}