Swift|Swift 起步
原文来自Swift官方网站查看版本
$ swift --version
Apple Swift version 2.2-dev (LLVM ..., Clang ..., Swift ...)
REPL 如果想运行没有参数的Swift指令,你可以使用REPL(Read-eval-print-loop 交互式解释器),swift的交互解释器可以直接读取、计算、打印你输入的swift代码。
$ swift
Welcome to Apple Swift version 2.2. Type :help for assistance.
1>
- Xcode的Playground正是基于REPL来实时解释运行实现的。
Darwin
(Darwin 是MacOS的底层核心):1> import Darwin
2> arc4random_uniform(10)
$R0: UInt32 = 4
打包指令 Swift的包管理器提供了一整套符合开发者习惯的系统用来构建包、可执行文件、和使用不同的package分享代码。当本地的swift开发包安装完成,你就可以直接调用包管理工具了:
swift package, swift run, swift build and swift test
:$ swift package --help
OVERVIEW: Perform operations on Swift packages
...
1.创建一个包 第一步:创建一个文件夹,命名为Hello:
$ mkdir Hello
$ cd Hello
第二步:每个包都要有一个manifest文件叫做
Package.swift
放在根目录,即此时的Hello文件夹。也可以命令生成一个最低配置的包:swift package init
init命令默认生成如下的包目录结构:
├── Package.swift
├── README.md
├── Sources
│└── Hello
│└── Hello.swift
└── Tests
├── HelloTests
│└── HelloTests.swift
└── LinuxMain.swift
2.构建一个包 【Swift|Swift 起步】然后可以使用
swift build
命令来构建一个包,指令会下载、分解、编译配置文件manifest中引入的依赖文件:swift build
Compile Swift Module 'Hello' (1 sources)
测试运行包:
swift test
Compile Swift Module 'HelloTests' (1 sources)
Linking ./.build/x86_64-apple-macosx10.10/debug/HelloPackageTests.xctest/Contents/MacOS/HelloPackageTests
Test Suite 'All tests' started at 2016-08-29 08:00:31.453
Test Suite 'HelloPackageTests.xctest' started at 2016-08-29 08:00:31.454
Test Suite 'HelloTests' started at 2016-08-29 08:00:31.454
Test Case '-[HelloTests.HelloTests testExample]' started.
Test Case '-[HelloTests.HelloTests testExample]' passed (0.001 seconds).
Test Suite 'HelloTests' passed at 2016-08-29 08:00:31.455.
Executed 1 test, with 0 failures (0 unexpected) in 0.001 (0.001) seconds
Test Suite 'HelloPackageTests.xctest' passed at 2016-08-29 08:00:31.455.
Executed 1 test, with 0 failures (0 unexpected) in 0.001 (0.001) seconds
Test Suite 'All tests' passed at 2016-08-29 08:00:31.455.
Executed 1 test, with 0 failures (0 unexpected) in 0.001 (0.002) seconds
3.构建可执行文件 一个构建目标target如果包含了
main.swift
那这个target就会被当做一个可执行文件,包管理器会编译这个main文件到一个二进制可执行文件中。下面做一个栗子,这个包会生成一个叫Hello的可执行文件,执行完成输出“Hello, world!”。
第一步:创建并进入目录
$ mkdir Hello
$ cd Hello
第二步:初始化包,指定为可执行文件类型
swift package init --type executable
第三步:使用
swift run
指令构建并执行上面初始化后的可执行文件swift run Hello
- 提示:由于这个包目录里只有一个可执行文件,我们可以省略执行文件的名字,直接使用
swift run
。
swift build
命令先编译这个包,再在 .build 目录下运行二进制文件:$ swift build
Compile Swift Module 'Hello' (1 sources)
Linking ./.build/x86_64-apple-macosx10.10/debug/Hello>$ .build/x86_64-apple-macosx10.10/debug/Hello
Hello, world!
下面我们在一个新的源文件来定义一个方法
sayHello(name:)
,并让可执行文件来执行我们定义的这个方法。构建接收外部参数的包 第一步:在
Sources/Hello
目录创建一个新文件Greeter.swift
,输入如下代码:func sayHello(name: String) {
print("Hello, \(name)!")
}
- 这个
sayHello(name:)
方法接收一个字符串作为参数并拼接"Hello, "后打印。
main.swift
文件,替换里面的代码为:if CommandLine.arguments.count != 2 {
print("Usage: hello NAME")
} else {
let name = CommandLine.arguments[1]
sayHello(name: name)
}
比起之前用硬编码的方式,
main.swift
现在从命令行读取参数,并传入sayHello(name:)
方法中处理后再输出。第三步:再次运行
swift run
,生成新版本的Hello执行文件:$ swift run Hello `whoami`
- 如需要学习Swift包管理器,包括怎么构建模块、引入依赖和索引到系统自带的库,请参考Swift Package Manager。
LLDB
调试器一步一步运行swift程序,设置断点,检查和修改程序状态。举个栗子,以下代码定义了一个
factorial(n:)
方法,调用后打印执行结果:func factorial(n: Int) -> Int {
if n <= 1 { return n }
return n * factorial(n: n - 1)
}let number = 4
print("\(number)! is equal to \(factorial(n: number))")
创建一个
Factorial.swift
文件,将上面的代码copy到文件,然后运行swiftc
命令,把这个文件的文件名作为参数,跟一个-g
选项来生成调试信息。执行后会在当前目录生成一个名为Factorial的可执行文件。$ swiftc -g Factorial.swift
$ ls
Factorial.dSYM
Factorial.swift
Factorial(Unix可执行文件)
使用
swiftc
命令(类似javac和gcc的编译工具)编译swift文件同时可以输出编译信息。然后,我们不适用run
指令直接执行程序,而是换成LLDB来运行,使用LLDB调试器需要把程序作为参数输入lldb指令后面:$ lldb Factorial
(lldb) target create "Factorial"
Current executable set to 'Factorial' (x86_64).
(lldb) ...等待输入调试指令...
然后会出现一个交互式控制台让我们来运行lldb命令。
- 更多LLDB信息请参考LLDB Tutorial.。
b
指令(breakpoint set)在factorial(n:)
方法的第二行设置断点,然后每次执行到这一行代码时都会获取到程序间歇。(lldb) b 2
Breakpoint 1: where = Factorial`Factorial.factorial (Swift.Int) -> Swift.Int + 12 at Factorial.swift:2, address = 0x0000000100000e7c
使用
r
指令(run)运行程序,输入r并回车以后程序会运行起来并停止在factorial(n:)
方法的调用栈:(lldb) r
Process 40246 resuming
Process 40246 stopped
* thread #1: tid = 0x14dfdf, 0x0000000100000e7c Factorial`Factorial.factorial (n=4) -> Swift.Int + 12 at Factorial.swift:2, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x0000000100000e7c Factorial`Factorial.factorial (n=4) -> Swift.Int + 12 at Factorial.swift:2
1func factorial(n: Int) -> Int {
-> 2if n <= 1 { return n }
3return n * factorial(n: n - 1)
4}
5
6let number = 4
7print("\(number)! is equal to \(factorial(n: number))")
使用
p
指令(print)来查看参数 n 的值:(lldb) p n
(Int) $R0 = 4
-
p
指令也能计算swift表达式:
(lldb) p n * n
(Int) $R1 = 16
使用
bt
指令(backtrace)来查看通向factorial(n:)
的框架:(lldb) bt
* thread #1: tid = 0x14e393, 0x0000000100000e7c Factorial`Factorial.factorial (n=4) -> Swift.Int + 12 at Factorial.swift:2, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
* frame #0: 0x0000000100000e7c Factorial`Factorial.factorial (n=4) -> Swift.Int + 12 at Factorial.swift:2
frame #1: 0x0000000100000daf Factorial`main + 287 at Factorial.swift:7
frame #2: 0x00007fff890be5ad libdyld.dylib`start + 1
frame #3: 0x00007fff890be5ad libdyld.dylib`start + 1
使用
c
指令(continue)来继续程序,直到遇到下一个断点:(lldb) c
Process 40246 resuming
Process 40246 stopped
* thread #1: tid = 0x14e393, 0x0000000100000e7c Factorial`Factorial.factorial (n=3) -> Swift.Int + 12 at Factorial.swift:2, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x0000000100000e7c Factorial`Factorial.factorial (n=3) -> Swift.Int + 12 at Factorial.swift:2
1func factorial(n: Int) -> Int {
-> 2if n <= 1 { return n }
3return n * factorial(n: n - 1)
4}
5
6let number = 4
7print("\(number)! is equal to \(factorial(n: number))")
再次使用
p
指令来查看参数 n 的值:(lldb) p n
(Int) $R2 = 3
使用
br di
指令(breakpoint disable)关闭所有断点,然后用c
指令继续程序:(lldb) br di
All breakpoints disabled. (1 breakpoints)
(lldb) c
Process 40246 resuming
4! is equal to 24
Process 40246 exited with status = 0 (0x00000000)
#结语
现在已经介绍完了Swift的REPL、构建系统、调试器,如果需要更深一步的学习,这里有一些建议供参考:
- Swift构建系统和包管理器深入学习
- 在Swift社区活跃
- Apple的Swift开发资源
推荐阅读
- 二、抱朴守拙|二、抱朴守拙 涉世之法
- 操作系统|[译]从内部了解现代浏览器(1)
- Swift中willSet和didSet的简述
- Hacking|Hacking with iOS: SwiftUI Edition - SnowSeeker 项目(一)
- LeetCode算法题-11.|LeetCode算法题-11. 盛最多水的容器(Swift)
- iOS-Swift-map|iOS-Swift-map filter reduce、函数式编程
- Swift|Swift ----viewController 中addChildViewController
- SwiftUI|SwiftUI iOS 瀑布流组件之仿CollectionView不规则图文混合(教程含源码)
- 一切顺利、一路平安
- Swift高级应用|Swift高级应用 -01