DSL on Rust: 为实际任务编写自己的语言

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Swift —— 系统编程中意想不到的英雄



当您听到“系统编程”时,通常会想到硬核的 C 语言、汇编语言,或者至少是 Rust。Swift?那个用于开发精美移动应用的语言?事实证明,是的,这并非玩笑。



Apple 在 Swift 中不仅内置了便利性和安全性,还提供了对内存、指针和系统调用的完全控制。在本文中,我们将探讨 Swift 如何成为您编写实用程序、驱动程序、网络守护进程甚至操作系统组件的主要工具。准备好感到惊喜吧 —— 代码将是真实、可运行且非常有趣的。



为什么选择 Swift?系统编程的三大支柱



系统编程需要三样东西:性能、资源控制以及“贴近硬件”工作的能力。Swift 提供了这一切,甚至更多。



  • C 级别的性能。LLVM 编译器对代码的优化不逊于 C 或 C++。在基准测试中,Swift 在 I/O 任务上通常优于 Go 和 Rust。
  • 直接内存访问。通过 UnsafePointer、UnsafeMutablePointer 和原始字节操作实现。
  • 丰富的标准库。无需拖入大量依赖项 —— 用于处理套接字、文件和进程的一切都已就绪。


同时,Swift 保持了安全性:如果您不使用 unsafe 块,编译器将保护您免受缓冲区溢出和悬空指针的影响。而当您需要时 —— 只需编写 withUnsafePointer 即可获得完全控制权。



内存操作:从字节到结构体



让我们从基础开始 —— 操作原始内存。想象一下,您需要读取一个二进制文件并将其解释为一个结构体数组。在 C 语言中,您会为 malloc 和 sizeof 而挣扎。而在 Swift 中 —— 优雅且安全。



在 Swift 中读取二进制文件



import Foundation

struct Header { let magic: UInt32 let version: UInt16 let count: UInt16}

func readBinaryFile(path: String) -> Header? { let data = try? Data(contentsOf: URL(fileURLWithPath: path)) guard let data = data else { return nil } return data.withUnsafeBytes { (ptr: UnsafeRawBufferPointer) in guard let baseAddress = ptr.baseAddress else { return nil } let headerPtr = baseAddress.assumingMemoryBound(to: Header.self) return headerPtr.pointee }}


请注意:我们没有手动分配内存。withUnsafeBytes 提供了一个临时指针,该指针仅存在于闭包内部。它安全、高效,并且读起来像优美的散文。



创建结构体并使用指针



但如果您需要在内存中创建一个结构体并将其地址传递给系统调用呢?很简单!



struct sockaddr_in {    var sin_len: UInt8 = 0    var sin_family: UInt8 = UInt8(AF_INET)    var sin_port: in_port_t = 0    var sin_addr: in_addr = in_addr(s_addr: 0)    var sin_zero: (UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8) = (0,0,0,0,0,0,0,0)}

var address = sockaddr_in()address.sin_port = CFSwapInt16HostToBig(8080)address.sin_addr.s_addr = inet_addr("127.0.0.1")

let ptr = withUnsafePointer(to: &address) { $0 }let rawPtr = UnsafeRawPointer(ptr)


这段代码是低级套接字操作的基础。我们手动定义结构体,填充字段,然后获取一个原始指针传递给 connect 或 bind。



系统调用与 POSIX API



Swift 与 POSIX 配合得很好。您可以调用 open、read、write、fork、exec —— 就像过去的美好时光一样,但使用的是 21 世纪的语法。



在 Swift 中实现 fork + exec



import Darwin

func spawnProcess(path: String, args: [Str

博客

书籍推荐