Swift 入门

入门.

如果您是 Swift 新手,请查看Swift 编程语言中的 Swift 教程,快速介绍该语言最重要的概念和功能.

安装 Swift

使用 Swift 的第一步是下载并安装编译器和其他所需组件。转到下载页面并按照适合您的目标平台的说明进行操作.

为了遵循下面的示例,请确保将 Swift 添加到您的$PATH.

在 macOS 上

macOS 上可下载工具链的默认位置是 /Library/Developer/Toolchains. 您可以使用以下命令从终端使最新安装的工具链可供使用:

$ export TOOLCHAINS=swift

要选择任何其他已安装的工具链,请在TOOLCHAINS 变量中使用其标识符。标识符可以在工具链的Info.plist文件中找到.

$ /usr/libexec/PlistBuddy -c "Print CFBundleIdentifier:" /Library/Developer/Toolchains/swift-4.0-RELEASE.xctoolchain/Info.plist
org.swift.4020170919

$ export TOOLCHAINS=org.swift.4020170919

在 Linux 上

  1. 安装所需的依赖项:
Ubuntu 18.04 Ubuntu 20.04 Ubuntu 22.04 CentOS 7 Amazon Linux 2
$ apt-get install \
          binutils \
          git \
          libc6-dev \
          libcurl4 \
          libedit2 \
          libgcc-5-dev \
          libpython2.7 \
          libsqlite3-0 \
          libstdc++-5-dev \
          libxml2 \
          pkg-config \
          tzdata \
          zlib1g-dev
$ apt-get install \
          binutils \
          git \
          gnupg2 \
          libc6-dev \
          libcurl4 \
          libedit2 \
          libgcc-9-dev \
          libpython2.7 \
          libsqlite3-0 \
          libstdc++-9-dev \
          libxml2 \
          libz3-dev \
          pkg-config \
          tzdata \
          uuid-dev \
          zlib1g-dev
$ apt-get install \
          binutils \
          git \
          gnupg2 \
          libc6-dev \
          libcurl4-openssl-dev \
          libedit2 \
          libgcc-9-dev \
          libpython3.8 \
          libsqlite3-0 \
          libstdc++-9-dev \
          libxml2-dev \
          libz3-dev \
          pkg-config \
          tzdata \
          unzip \
          zlib1g-dev
$ yum install \
      binutils \
      gcc \
      git \
      glibc-static \
      libbsd-devel \
      libedit \
      libedit-devel \
      libicu-devel \
      libstdc++-static \
      pkg-config \
      python2 \
      sqlite

      # __block conflicts with clang's __block qualifier
      sed -i -e 's/\*__block/\*__libc_block/g' /usr/include/unistd.h
$ yum install \
      binutils \
      gcc \
      git \
      glibc-static \
      gzip \
      libbsd \
      libcurl \
      libedit \
      libicu \
      libsqlite \
      libstdc++-static \
      libuuid \
      libxml2 \
      tar \
      tzdata

如果您将 Linux 上的 Swift 工具链安装到系统根目录以外的目录,则需要使用 Swift 安装的实际路径运行以下命令:

$ export PATH=/path/to/Swift/usr/bin:"${PATH}"

在 Windows 上

依赖关系

Swift 具有以下一般依赖项:

Windows 具有以下附加平台特定依赖项:

启用开发者模式

为了开发应用程序,特别是使用 Swift 包管理器,您需要启用开发人员模式。请参阅 Microsoft文档以获取启用开发人员模式的说明.

安装说明

使用 Windows 包管理器安装

Windows 包管理器 可以在App Store中找到或直接安装.

使用Scoop安装

# Optional: Needed to run a remote script the first time
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
# Command for installing scoop
Invoke-RestMethod -Url 'get.scoop.sh' | Invoke-Expression
  1. 安装所需的依赖项:

    无法通过当前支持的包管理器安装平台依赖项,因为安装规则不会安装必要的组件。它们将通过 Visual Studio 安装程序进行安装.

    使用 Winget(Windows 包管理器):

    winget install Git.Git
    winget install Python.Python.3.10
    
    curl -sOL https://aka.ms/vs/16/release/vs_community.exe
    start /w vs_community.exe --passive --wait --norestart --nocache ^
      --installPath "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Community" ^
      --add Microsoft.VisualStudio.Component.Windows10SDK.19041 ^
      --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64
    del /q vs_community.exe
    

    用 Scoop:

    # Scoop already comes pre-installed with Git, so no need to re-install it.
    scoop bucket add versions
    scoop install python310
    
    curl -sOL https://aka.ms/vs/16/release/vs_community.exe
    start /w vs_community.exe --passive --wait --norestart --nocache ^
      --installPath "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Community" ^
      --add Microsoft.VisualStudio.Component.Windows10SDK.19041 ^
      --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64
    del /q vs_community.exe
    

    启动新的命令提示符/Powershell 提示符并安装 Python 库 6.

    pip install six
    
  2. 安装 Swift:

    Swift 可以直接通过官方安装程序安装,也可以使用 Windows 包管理器安装。请注意,Windows包管理器 版本可能落后于正式版本.

    • 使用官方安装程序:
      1. 下载 最新的软件包版本.
      2. 运行包安装程序.
    • 使用 Windows 包管理器:
      winget install Swift.Toolchain
      
    • 使用 Scoop:
      scoop install swift
      

Swift 工具链将安装在%SystemDrive%\Library\Developer\Toolchains\unknown-Asserts-development.xctoolchain. 兼容的 Swift SDK 将安装在%SystemDrive%\Library\Developer\Platforms\Windows.platform\Developer\SDKs\Windows.sdk.

传统安装

注意: 5.4.2 之前的 Swift 需要传统的安装过程.

Swift 已通过Visual Studio 2019测试。您需要安装带有以下组件的 Visual Studio。Swift 安装程序可在“下载”部分中找到。Windows 上的工具链安装到%SystemDrive%\Library\Developer\Toolchains.

需要以下 Visual Studio 组件:

组件 Visual Studio ID
MSVC v142 - VS 2019 C++ x64/x86 build tools (Latest) Microsoft.VisualStudio.Component.VC.Tools.x86.x64
Windows 10 SDK (10.0.17763.0)2 Microsoft.VisualStudio.Component.Windows10SDK.17763

建议使用以下附加 Visual Studio 组件:

组件 Visual Studio ID
Git for Windows Microsoft.VisualStudio.Component.Git
Python 3 64-bit (3.7.8) Component.CPython.x64

建议使用以下附加 Visual Studio 组件:

组件 Visual Studio ID
C++ CMake tools for Windows Microsoft.VisualStudio.Component.VC.CMake.Project
支持文件

注意: 这仅适用于 5.4.2 之前的版本

您必须使用x64 Native Tools for VS2019 Command Prompt来运行以下步骤。从 Visual Studio运行x64 Native Tools for VS2019 Command Prompt脚本DevEnv,设置必要的环境变量来查找系统标头.

为了使 Swift 能够访问 Windows SDK,需要将一些文件部署到 Windows SDK 中。以下内容将修改您的 Visual Studio 安装,因此需要从(提升的)“管理员”运行x86 Native Tools for VS2019 Command Prompt.

copy /Y %SDKROOT%\usr\share\ucrt.modulemap "%UniversalCRTSdkDir%\Include\%UCRTVersion%\ucrt\module.modulemap"
copy /Y %SDKROOT%\usr\share\visualc.modulemap "%VCToolsInstallDir%\include\module.modulemap"
copy /Y %SDKROOT%\usr\share\visualc.apinotes "%VCToolsInstallDir%\include\visualc.apinotes"
copy /Y %SDKROOT%\usr\share\winsdk.modulemap "%UniversalCRTSdkDir%\Include\%UCRTVersion%\um\module.modulemap"

由于它将文件安装到 Visual Studio 映像中,因此每次更新 Visual Studio 时都需要复制这些文件.

Visual Studio 更新后修复

如果 Visual Studio 已更新,您可能需要修复安装。请参阅 Microsoft 的修复已安装程序的说明.


Swift 版本

您可以通过输入 swift 命令并传递 --version 标志来验证您运行的是预期的 Swift 版本:

$ swift --version
Apple Swift version 2.2-dev (LLVM ..., Clang ..., Swift ...)

版本号上的后缀-dev用于指示它是开发版本,而不是发布版本.

使用 REPL

如果你在没有任何其他参数的情况下运行 swift repl,你将启动 REPL,这是一个交互式 shell,它将读取、评估和打印你输入的任何 Swift 代码的结果.

$ swift repl
Welcome to Apple Swift version 5.7 (swiftlang-5.7.0.127.4 clang-1400.0.29.50).
Type :help for assistance.
  1>

与 REPL 交互是试验 Swift 的好方法。例如,如果输入表达式1 + 2,则表达式的结果3,将打印在下一行:

  1> 1 + 2
$R0: Int = 3

您可以为常量和变量赋值,并在后续行中使用它们。例如,可以将该String值Hello, world! 分配给常量greeting,然后作为参数传递给print(_:)函数:

  2> let greeting = "Hello!"
greeting: String = "Hello!"
  3> print(greeting)
Hello!

如果您输入无效的表达式,REPL 将打印一条错误,显示问题发生的位置:

let answer = "forty"-"two"
error: binary operator '-' cannot be applied to two 'String' operands
let answer = "forty"-"two"
             ~~~~~~~^~~~~~

您可以使用向上箭头键和向下箭头键(↑和↓)循环浏览之前输入到 REPL 中的行。这允许您对先前的表达式进行轻微更改,而无需重新键入整行,并且对于修复类似上一示例中的错误特别方便:

let answer = "forty-two"
answer: String = "forty-two"

REPL的另一个有用功能是它可以自动建议可以在特定上下文中使用的函数和方法。例如,如果您在字符串值的点运算符后输入 re,然后按 Tab 键 (⇥),则 REPL 将给出可用完成的列表,例如 remove(at:)和replaceSubrange(bounds:with:):

5> "Hi!".re⇥
Available completions:
	remove(at: Index) -> Character
	removeAll() -> Void
	removeAll(keepingCapacity: Bool) -> Void
	removeSubrange(bounds: ClosedRange<Index>) -> Void
	removeSubrange(bounds: Range<Index>) -> Void
	replaceSubrange(bounds: ClosedRange<Index>, with: C) -> Void
	replaceSubrange(bounds: ClosedRange<Index>, with: String) -> Void
	replaceSubrange(bounds: Range<Index>, with: C) -> Void
	replaceSubrange(bounds: Range<Index>, with: String) -> Void
	reserveCapacity(n: Int) -> Void

如果启动代码块,例如在循环中使用 for-in 循环遍历数组时,REPL 将自动缩进下一行,并将提示符从 > 更改为 "."以指示仅在计算整个代码块时计算在该行上输入的代码.

  6> let numbers = [1,2,3]
numbers: [Int] = 3 values {
  [0] = 1
  [1] = 2
  [2] = 3
}
  7> for n in numbers.reversed() {
  8.     print(n)
  9. }
3
2
1

REPL 提供了 Swift 的所有功能,从编写控制流语句到声明和实例化结构和类.

您还可以导入任何可用的系统模块,例如macOS上的Darwin和Linux上的Glibc:

在 macOS 上

1> import Darwin
2> arc4random_uniform(10)
$R0: UInt32 = 4

在 Linux 上

1> import Glibc
2> random() % 10
$R0: Int32 = 4

在 Windows 上

REPL 依赖于 Python 绑定。必须确保路径中提供 Python 3.7。以下命令将 Python 3.7 从 Visual Studio 添加到 %PATH%,以便可以使用它:

path %ProgramFiles(x86)%\Microsoft Visual Studio\Shared\Python37_64;%PATH%

因为 Windows 安装将 SDK 从工具链中分离出来,所以必须将一些额外的参数传递给 REPL。这允许您使用具有相同工具链的多个不同 SDK.

set SWIFTFLAGS=-sdk %SDKROOT% -I %SDKROOT%/usr/lib/swift -L %SDKROOT%/usr/lib/swift/windows
swift repl -target x86_64-unknown-windows-msvc %SWIFTFLAGS%

使用包管理器

Swift 包管理器提供了一个基于约定的系统,用于构建库和可执行文件,以及在不同包之间共享代码.

这些示例假设您已在路径中提供 swift;有关详细信息,请参阅安装。一旦可用,你可以调用包管理器工具:swift package、swift run、swift build 和 swift test.

$ swift package --help
OVERVIEW: Perform operations on Swift packages
...

创建包

要创建新的 Swift 包,请先创建并输入一个名为 Hello 的目录:

$ mkdir Hello
$ cd Hello

每个包的根目录中都必须有一个名为 Package.swift 的清单文件。您可以使用以下方法创建一个名为 Hello 的最小包:

$ swift package init

默认情况下,init 命令将创建一个库包目录结构

├── Package.swift
├── README.md
├── Sources
│   └── Hello
│       └── Hello.swift
└── Tests
    ├── HelloTests
    │   └── HelloTests.swift
    └── LinuxMain.swift

您可以使用 swift build 来构建包。这将下载、解析和编译Package.swift清单文件中提到的依赖项.

$ swift build
Compile Swift Module 'Hello' (1 sources)

要为包运行测试,请使用: swift test

$ 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

构建可执行文件

如果目标包含名为 main.swift 的文件,则将其视为可执行文件。包管理器会将该文件编译为二进制可执行文件.

在此示例中,包将生成一个名为 Hello 的可执行文件,该可执行文件输出“Hello, world!".

首先创建并输入一个名为 Hello 的目录:

$ mkdir Hello
$ cd Hello

现在使用可执行类型运行 swift 包的 init 命令:

$ swift package init --type executable

使用swift run命令构建并运行可执行文件:

$ swift run Hello
Compile Swift Module 'Hello' (1 sources)
Linking ./.build/x86_64-apple-macosx10.10/debug/Hello
Hello, world!

注意:由于此包中只有一个可执行文件,我们可以从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:)函数,并让可执行文件调用它而不是直接调用print(_:).

使用多个源文件

在 Sources/Hello 目录中创建一个名为 Greeter.swift 的新文件,然后输入以下代码:

func sayHello(name: String) {
    print("Hello, \(name)!")
}

该sayHello(name:)函数采用单个String参数并打印我们之前的“Hello”问候语,用函数参数替换单词“World”.

现在,再次打开main.swift,并将现有内容替换为以下代码:

if CommandLine.arguments.count != 2 {
    print("Usage: hello NAME")
} else {
    let name = CommandLine.arguments[1]
    sayHello(name: name)
}

现在,main.swift 不再像以前那样使用硬编码的名称,而是从命令行参数读取。代替直接调用 print(_:),main.swift现在调用SayHello(name:)方法。由于该方法是 Hello 模块的一部分,因此不需要导入语句.

运行swift run并尝试新版本Hello:

$ swift run Hello `whoami`

要了解 Swift 包管理器,包括如何构建模块、导入依赖项和映射系统库,请参阅网站的Swift 包管理器r 部分.

要了解有关包插件的更多信息,请参阅插件入门.

使用 LLDB 调试器

您可以使用 LLDB 调试器逐步运行 Swift 程序、设置断点以及检查和修改程序状态.

例如,考虑以下 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 的文件,并运行 swiftc 命令,将文件名作为命令行参数传递,以及 -g 选项以生成调试信息。这将在当前目录中创建一个名为Factorial的可执行文件

$ swiftc -g Factorial.swift
$ ls
Factorial.dSYM
Factorial.swift
Factorial*

不要直接运行Factorial程序,而是通过 LLDB 调试器运行它,方法是将其作为命令行参数传递给 lldb 命令.

$ lldb Factorial
(lldb) target create "Factorial"
Current executable set to 'Factorial' (x86_64).

这将启动一个交互式控制台,允许您运行 LLDB 命令.

有关 LLDB 命令的更多信息,请参阅 see the LLDB 教程.

在factorial(n:)的第 2 行设置断点具有断点set (b) 命令的函数,使进程在每次执行函数时中断.

(lldb) b 2
Breakpoint 1: where = Factorial`Factorial.factorial (Swift.Int) -> Swift.Int + 12 at Factorial.swift:2, address = 0x0000000100000e7c

使用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
   1    func factorial(n: Int) -> Int {
-> 2        if n <= 1 { return n }
   3        return n * factorial(n: n - 1)
   4    }
   5
   6    let number = 4
   7    print("\(number)! is equal to \(factorial(n: number))")

使用 print (p) 命令检查 n 参数的值.

(lldb) p n
(Int) $R0 = 4

该print命令也可以计算 Swift 表达式.

(lldb) p n * n
(Int) $R1 = 16

Use the backtrace (bt) command to show the frames leading to factorial(n:) being called.

(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

使用continue( c) 命令恢复该过程,直到再次命中断点.

(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
   1    func factorial(n: Int) -> Int {
-> 2        if n <= 1 { return n }
   3        return n * factorial(n: n - 1)
   4    }
   5
   6    let number = 4
   7    print("\(number)! is equal to \(factorial(n: number))")

再次使用 print (p) 命令检查第二次调用factorial(n:) 的 n 参数的值.

(lldb) p n
(Int) $R2 = 3

使用断点禁用 (br di) 命令禁用所有断点,使用continue (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、构建系统和调试器,以下是有关下一步操作的一些建议:

  1. Windows 二进制文件是针对 Python 3.10.2 构建的

  2. 您可以安装更新的 SDK.