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 调试器 可以使用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开发资源

    推荐阅读