```Swift 的到来```
Advent of Swift

原始链接: https://leahneukirchen.org/blog/archive/2025/12/advent-of-swift.html

## Swift 与 2025 年 Advent of Code:学习体验 本报告总结了通过 2025 年 Advent of Code 的 12 天学习 Swift 的过程。最初的障碍是在 Void Linux 上设置 Swift 6.2 环境,由于 Python 3.13 兼容性问题,需要从头开始编译。尽管如此,工具链总体来说令人满意,具有快速的解释器和有用的代码格式化工具 (`swift-format`)。调试依赖于编译成二进制文件并使用 `lldb`,因为解释器回溯存在局限性。 Swift 本身感觉现代且易于学习,它借鉴了 C 系列的灵感,但语法比 Rust 更简洁。它提供了灵活的错误处理(检查异常、Optionals、Results)以及文档完善的标准库,具有强大的字符串处理和序列抽象。然而,在使用正则表达式时遇到了性能问题,需要重写。 一些奇怪之处包括不寻常的运算符优先级以及元组的限制(不可哈希)和模式匹配(不支持数组)。该语言的带写时复制优化的值语义很方便,但类型检查错误可能很慢且令人困惑。总的来说,Swift 在这些任务中表现令人愉快,但 macOS 之外的库可用性以及持续的语言变化仍然是大型项目的考虑因素。

## Hacker News 上关于 Swift 的讨论 一场 Hacker News 讨论围绕着 Swift 的优势和劣势,尤其关注字符串操作。 许多评论者争论 Swift 的 `String` API 设计,一些人批评其在需要字节级访问或索引时过于复杂,而另一些人则认为它正确地优先考虑了基于字素的字符串处理,以满足典型应用开发用例。 对话涉及使用 `Array` 或 `UInt8` 数组等替代方案来满足特定需求,并承认正则表达式性能问题。 虽然 Swift 因其易用性和内存管理而受到赞扬,但有些人认为其局限性阻碍了其在 Apple 生态系统之外的更广泛应用。 用户分享了当前的 Swift 应用,包括原生 iOS/macOS 应用、服务器端开发(使用 Vapor 和 Hummingbird 等框架)、嵌入式设备控制平面,甚至作为 AppleScript 的替代品进行脚本任务。 尽管 Swift for TensorFlow 项目已被取消,但人们对该语言的热情依然存在,许多人欣赏其整体设计和潜力。
相关文章

原文

This year, I decided to use Advent of Code to learn the language Swift. Since there were only 12 days of tasks for 2025, here is my summary of experiences. Also check out my solutions.

Tooling

I used Swift 6.2 on Void Linux, which I compiled from scratch since there were no prebuilt binaries that worked with a Python 3.13 system (needed for lldb). It’s possible to bootstrap Swift from just a clang++ toolchain, so this wasn’t too tedious, but it still required looking up Gentoo ebuilds how to pass configuration properly. As an end user, this should not worry you too much.

Tooling in general is pretty nice: there’s an interpreter and you can run simple “scripts” directly using swift foo.swift. Startup time is short, so this is great for quick experiments. There’s also a REPL, but I didn’t try it yet. One flaw of the interpreter (but possibly related to my setup) is that there were no useful backtraces when something crashed. In this case, I compiled a binary and used the included lldb, which has good support for Swift.

There’s also a swift-format tool included to format source code. It uses 2 spaces by default, but most code in the wild uses 4 spaces curiously. I’m not sure when that changed.

Since I only write simple programs using a single source file, I didn’t bother looking at swift-build yet.

By default, programs are linked dynamically against the standard library and are thus super compact. Unfortunately, many modern languages today don’t support this properly. (Statically linking the standard library costs roughly 10MB, which is fair too.)

The language

In general, the language feels modern, comfy, and is easy to pick up. However, I found some traps as well.

The syntax is inspired by the C family and less symbol-heavy than Rust’s. There’s a block syntax akin to Ruby for passing closures.

Error handling can be done using checked exceptions, but there are also Optional types and Result types like in Rust, and syntactic shortcuts to make them convenient.

The standard library has many practical functions, e.g. there’s a function Character.wholeNumberValue that works for any Unicode digit symbol. There’s a Sequence abstraction over arrays etc. which has many useful functions (e.g. split(whereSeparator:), which many other standard libraries lack). The standard library is documented well.

The string processing is powerful, but inconvenient when you want to do things like indexing by offsets or ranges, due to Unicode semantics. (This is probably a good thing in general.) I switched to using arrays of code-points for problems that required this.

On Day 2, I tried using regular expressions, but I found serious performance issues: first I used a Regexp literal (#/.../#) in a loop, which actually resulted in creating a new Regexp instance on each iteration; second, Regexp matching itself is quite slow. Before I extracted the Regexp into a constant, the program was 100x as slow as Ruby(!), and after it still was 3x as slow. I then rewrote the solution to not use Regexps.

Prefix (and suffix) operators need to “stick” to their expression, so you can’t write if ! condition. This is certainly a choice: you can define custom prefix and suffix operators and parsing them non-ambiguously is easier, but it’s probably not a thing I would have done.

Swift functions often use parameter names (probably for compatibility with Objective-C). They certainly help readability of the code, but I think I prefer OCaml’s labeled arguments, which can be reordered and permit currying.

The language uses value semantics for collections and then optimizes them using copy-on-write and or by detecting inout parameters (which are updated in-place). This is quite convenient when writing code (e.g day 4) Garbage collection is done using reference counting. However, some AoC tasks turned out to make heavy use of the garbage collector, where I’d have expected the compiler to use a callstack or something for intermediate values. Substrings are optimized by a custom type Substring, if you want to write a function to operate on either strings or substrings, you need to spell this out:

func parse<T>(_ str: T) -> ... where T: StringProtocol

There’s a library swift-algorithms adding even more sequence and collection algorithms, which I decided not to use.

Downsides

The compiler is reasonably fast for an LLVM-based compiler. However, when you manage to create a type checking error, error reporting is extremely slow, probably because it tries to find any variant that could possibly work still. Often, type checking errors are also confusing.

(Error messages unrelated to type checking are good and often really helpful, e.g. if you accidentally use ''-quotes for strings or try to use [] as an empty map, it tells you how to do it right.)

Ranges can be inclusive ... or right-exclusive ..<. Constructing a range where the upper boundary is smaller than the lower boundary results in a fatal error, whereas in other languages it’s just an empty range.

Some “obvious” things seem to be missing, e.g. tuples of Hashable values are not Hashable currently (this feature was removed in 2020, after trying to implement the proposal that introduced it, and no one bothered to fix it yet?), which is pretty inconvenient.

Likewise, the language has pattern matching for algebraic data types and tuples, but unfortunately not for arrays/sequences, which is inconvenient at times.

Since I was just picking up Swift, I had to search stuff online a lot and read Stack Overflow. I noticed I found many answers for prior versions of Swift that changed in the mean time (even for basic tasks). For a language that’s been around for over 10 years, this seems like quite some churn. I hope the language manages to stabilize better and doesn’t just get new features bolted on continuously.

In general, using Swift was fun and straight-forward for these programming tasks. For writing serious applications on non-MacOS systems, there’s also the question of library availability. Some parts of the language still feel unfinished or unpolished, in spite of being around for quite some time.

NP: Adrianne Lenker—Promise is a Pendulum

联系我们 contact @ memedata.com