本文源自本人的学习记录整理与理解,其中参考阅读了部分优秀的博客和书籍,尽量以通俗简单的语句转述。引用到的地方如有遗漏或未能一一列举原文出处还望见谅与指出,另文章内容如有不妥之处还望指教,万分感谢。
Swift的编译与OC对比
可以看出:OC编译器前端是Clang
,而Swift的编译器前端是swiftc
Swift的编译过程
如何生成
Swift
的抽象语法树 ?
终端打印:swift -dump-ast main.swift
终端导出到文件:swift -dump-ast main.swift -o main.ast
main.ast : 文件名和格式
如何生成简洁的SIL代码 ?
使用命令:swiftc -emit-sil main.swift
如何生成LLVM IR代码 ?
使用命令:swiftc -emit-ir main.swift
导出:swiftc -emit-ir main.swift -o main.ll
如何生成汇编代码 ?
使用命令:swiftc -emit-assembly main.swift
导出: swiftc -emit-assembly main.swift -o main.s
对汇编代码进行分析,可以真正掌握编程语言的本质
!!!
基础语法
- 不用编写main函数,Swift将全局范围内的首句可执行代码作为程序入口;但依然还是有main函数的,只不过不用我们写
- 一句代码尾部可以省略分号(;),多句代码写到同一行时必须用分号(
;
)隔开 - 用
var
定义变量,let
定义常量,编译器能自动推断出变量或常量的类型 -
Playground
可以快速预览代码效果,是学习语法的好帮手 -
Command + Shift + Enter
: 运行整个Playground -
Shift + Enter
: 运行截止到某一行代码
- liveView可以赋值给view, 也可以给一个vc
Playground支持添加多页面
Playground支持markup语法,和markdown类似
注意
:markup只在Playground有效
单行注释写法---
// : 发飙妹
-----------
多行注释写法
/*:
## 逍遥侯
### 城主
*/
//: [上一页](@previous)
//: [下一页](@next)
- swift支持注释多行嵌套
常量
- 只能赋值一次,不允许第二次赋值
- 它的值不要求在编译时期确定,但使用之前必须赋值一次;一旦没有赋值就使用,会直接报错;从这一点上也体现出比OC安全,OC这种写法是不会报错的,只会警告⚠️
oc语言是要求编译时期必须确定常量的值
let age int //可以不用直接赋值,给一个类型;后边赋值也可以
age = 30
---------
var num = 20
num +=10
//num的值在运行时才可以确定,赋值给一个常量。不会编译报错
let age = num
定义一个方法
/*
func: 表示定义一个方法
config:方法名
Int:返回值类型
*/
func config() -> Int {
return 10
}
标识符
- 标识符(比如常量名、变量名、函数名)几乎可以使用任何字符
- 标识符不能以数字开头,不能包含空白字符、制表符、箭头等特殊字符
func 😁() -> Int {
return 168
}
let 🚀 = “火箭”
常见数据类型
- swift中的数据类型被分为两大类:值类型、引用类型,不存在OC中的基本数据类型这样的概念
疑问:Int 为什么要被定义为一个结构体 ?有什么优势
被定义为结构体使用起来更加方便,都知道结构体是可以拥有成员的,也就是说int类型可以像OC对象一样使用点语法。这样开发起来会更加的便捷 !比如想知道一个Int16的最大值,可以直接使用 Int16.max ; 说白了就是 Int 可以调用方法,变的更加强大
字面量:直接写出的值就是字面量
//布尔
//true和false就是字面量
let bool = true //取反是false
-------------------------
//字符串
let string = "逍遥候"
//字符(可存储ASCII字符、Unicode字符)
字符类型必须写清楚是 Character类型,因为字符和字符串都是使用双引号
let chstr: Character = "息"
字符类型必须写清楚是 Character
类型,因为字符和字符串都是使用双引号
- 整数字面量
let intDecimal = 17 //十进制
let intBinary = 0b10001 //二进制
let intOctal = 0o21 //八进制
let intHex = 0x11 //十六进制
整数和浮点数可以添加额外的零或者添加下划线来增强可读性
比如:100_00000、1_000_000_111_000
- 浮点数字面量
//十进制 等价于1.25e2 -- > 1.25✖️10的2次方 ;
// e :10 ;2:2次方
let doubleDecimal = 125.0
//十六进制 等价于15x2^2 相当于十进制的60
p: 代表乘以 ✖️
let doubleHexdecimal1 = 0xFp2
//十六进制 等价于15x2^-2(负二次方) 相当于十进制的60
let doubleHexdecimal2 = 0xFp-2
- 数组和字典
let array = [1,3,5,7,9]
let dictionary = ["age": 50, "hei":168]
字典和数组都使用中括号
- 类型转换
整数类型转换,定义两个不同类型的整数,相加时需要把低类型的整数转换成高类型的整数
let int1: UInt16 = 200
let int2:UInt8 = 2
let int3 = int1 + Uint16(int2)
整数和浮点数转换, 需要把整数转换成浮点数在做运算
let int = 2
let double = 2.006
let pd = Double(int) + double
注意:有没有发现常量名、变量名的定义是可以直接写 int double 这是不会报错的哦
- 数字字面量
没有明确类型
之前可以相加,一旦明确类型就不能够相加
let resu = 3 + 0.14159
元组 (tuple) : 由多种类型组合而成的数据类型
- 元组和元组之间可以直接赋值
注意:元组不是结构体,是两种不同的数据结构
//定义元组
let status = (200, "succeed")
//访问元组通过下标
status.0
status.1
//元组间赋值
//接收两个
let status(st, msg) = status
//只接收第一个的值
let status(st, _) = status
//定义元组同时定义名称
let status = (sta: 200, msg: "succeed")
//访问元组通过名称
status.sta
status.msg