Swiftc 常用命令

  • swiftc -o main.out main.Swift
  • swiftc AST swiftc main.Swift -dump-ast
  • swiftc SIL swiftc main.Swift -emit-sil
  • swiftc LLVM IR swiftc main.Swift -emit-ir
  • swiftc Language swiftc main.Swift -emit-assembly

变量和常量

声明

  • let 声明常量
  • var 声明变量

常量声明后,不可以修改值

let constPi = 3.14159
var number = 3

Swift 中可以在一行定义多个常量和变量

let x = 0.0, y = 0.0, z = "123"

类型声明

Swift类型使用:来声明类型

let name : String

数值类型

  • Int 与当前平台的原生字相同的长度
  • UInt 与当前平台原生字相同的无符号整数
类型 大小(字节数) 区间值
Int8 1 字节 -128~127
UInt8 1 字节 0~255
Int32 4 字节 -2147483638~2147483647
UInt32 4 字节 0~4294967295
Int64 8 字节 -9223372036954775808~...
UInt64 8 字节 0~18446744073709551615
Float 4 字节 1.2E-38~3.4E+38(~6.digits)
Double 8 字节 2.3E-308~1.7E+308(~15digits)

Bool

Swift 的类型安全机制会组织使用非布尔值替换Bool

类型别名

为已存在类型定义的一个可选择的名字

typealias AudioSample = UInt8
let sample: AudioSample = 32

Tuple

定义

  • 元组把多个值合并成单一的复合型的值
  • 元组内的值可以使任何类型,而且可以不必是同一类型
let error = (1, "没有权限")
print(error.0)
print(error.1)

元组内的元素也可以命名,调用时可以直接使用 .name的方式调用

let error = (errorCode: 1, errorMessage: "没有权限")
print(error.errorCode)
print(error.errorMessage)

修改

  • var 定义的元组是可变元组,let 定义的是不可变元组
  • 不管是可变还是不可变元组,创建后门就不能增加和删除元素
  • 可以对可变元祖的元素进行修改,但是不能改变其类型
  • any 类型可以改为任何类型
var error:(Any, String) = (1, "没有权限")
error.0 = 2
error.0 = "abc"

分解

  • 可以将一个元组的内容分解成单独的常量或变量
  • 如果只需要使用其中的一部分数据,不需要的数据可以用下划线 _ 代替
let error = (1, "没有权限")
let (errcode, errorMessage) = error
print(errcode)
print(errorMessage)
let error = (1, "没有权限")
let (_, errorMessage) = error
print(errorMessage)

函数返回值

  • 可以使用元组作为函数的多个返回值
  • 返回值可以在函数返回类型中被命名
func writeToFile(content: String) -> (errorCode: Int, errorMessage: String) {
    return (1, “没有权限")
}

Optional

定义

  • 通过在变量类型后面添加?表示这里有值等于x,或者为nil
  • 在 Swift 中 nil 不是指针,是一个值缺失的特殊类型,任何类型的可选项都可以设置成 nil 而不仅仅是对象类型

使用

  • 可选项定义的变量是不可以直接使用的
  • 需要用 ! 展开之后才能使用
var str: String? = "abc"
if str != nil {
    let count = str!.count
    print(count)
}

绑定

  • 可以使用可选项绑定来判断可选项是否包含值,如果包含就把值赋给一个临时的变量或者常量
  • 可选绑定可以与 ifwhile 的语句使用来检查可选项内部的值,并赋值给一个变量或常量
  • 同一个 if 语句中包含多可选项绑定,用都好分割即可。如果任一可选绑定结果是 nil 或者布尔值为 false,那么整个 if 判断会被看做 false
var str: String? = "abc"
if let actualStr = str {
    let count = actualStr.count
    print(count)
}

隐式展开

  • 有些可选项一旦被设定值之后,就会一直拥有值,在这种情况下, 就可以去掉检查的需求,也不必每次访问的时候都进行展开
  • 通过在声明的类型后边添加一个叹号 String! 而非问号 String? 来书写隐式展开的选项
  • 隐式展开可选项主要被用在 Swift 类的初始化过程中
var str: String! = "abc"
let count = str.count
print(count)

可选链

  • 可选项后面加问号
  • 如果可选项不为 nil,返回一个可选结果,否则返回 nil
var str: String? = "abc"
let count = str?.count
if count != nil {
    let lastIndex = count! - 1
    print(lastIndex)
}

字符串

定义

  • 字面量
  • 初始化器语法
  • isEmpty 检查是否为空串
var emptyString = ""
var anotherEmptyString = String()
if emptyString.isEmpty {
    print("is empty")
}
  • 多行字面量使用 """来表示
  • 打印时,换行会和 Code 中一致,如果不想换行,需要在结尾处添加 \
  • 多行的空格逻辑见下图

-w1012

特殊字符

定义 含义
\0 空字符
\ 反斜线
\t 水平制表符
\n 换行符
\r 回车符
\" 双引号
\' 单引号
  • Unicode\u{n}来表示,n代表 Unicode 的合法值
let dollarSign = "\u{24}"

Raw String (扩展字符串分隔符)

  • 在字符串字面量中放置扩展分隔符来在字符串中包含特殊字符而不让他们真的生效
  • 把字符串放在双引号内,并由 # 包裹
  • 如果字符串里面有 # 则收尾需要两个 ##
  • 如果需要字符串中某个特殊符号的效果,使用匹配你包裹的井号数量的井号,并在前面写转移符号 \

-w533

String 是值类型

  • String 值在传递给方法或者函数的时候会被复制过去
  • 复制给常量或者变量的时候也一样
  • Swift 编辑器优化了字符串使用的资源,实际上拷贝只会在确实需要的时候才进行

-w728

操作字符

  • for-in 循环遍历 String 中的每一个独立的 Character
  • Character 类型
  • String 值可以通过传入 Character 数组来构造

-w662

字符串拼接

  • 使用加运算符 + 创建新字符串
  • 使用加赋值符号 += 在已存在的 String 值末尾追加一个 String
  • 使用 String 类型的 append() 方法可以给一个 String 变量的末尾追加 Character

我们还可以使用如下方式,对变量或常量进行字符串拼接

-w817

字符串索引

访问

  • 每一个 String 值都有相关的索引类型, String.Index 它相当于每个 Character 在字符串中的位置
  • startIndex 属性来访问 String 中第一个 Character 的位置, endIndex 属性就是 String 中最后一个字符后的位置
  • endIndex 属性并不是字符串下标脚本的合法实际参数
  • 如果 String 为空,则 startIndexendIndex 相等

-w538


字符串不可以使用数字下标的方式进行访问,这里的实现原理是一个 struct

-w926


  • 使用 index(before:)index(after:) 方法来访问给定索引的前后
  • 要访问给定索引更远的索引,可以使用 index(_:offsetBy:)
  • 使用 indices 属性来访问字符串中每个字符的索引

-w828


插入

  • 插入字符使用 insert(_:at:) 方法
  • 插入另一个字符串的内容到特定的索引,使用 insert(contentsOf:at:) 方法

-w666


删除

  • 移除字符,使用 remove(at:) 方法
  • 移除一小段特定范围的字符串,使用 removeSubrange(_:) 方法

-w940


子字符串

  • 使用下标或者类似 prefix(_:) 的方法得到的子字符串是 Substring 类型
  • Substring 拥有 String 的大部分方法
  • Substring 可以转成 String 类型

-w956


  • 子字符串重用一部分原字符串的内存
  • 修改字符串或者子字符串之前都不需要花费拷贝内存的代价
  • StringSubstring 都遵循 StringProtocol 协议,也就是说它基本上能很方便的兼容所有接受 StringProtocol 值的字符串操作函数

-w508


字符串比较

  • 字符串和字符相等性 ==!=
  • 前缀相等性 hasPrefix(_:)
  • 后缀相等性 hasSuffix(_:)

-w788



What doesn’t kill you makes you stronger.