开源的 Swift System 都做了什么?

Python实战社群

Java实战社群

长按识别下方二维码,按需求添加

扫码关注添加客服

进Python社群▲

扫码关注添加客服

进Java社群


作者 | Michael Ilseman 
来源 | swift.org

今年 6 月,Apple 推出了 Swift System,这是 Apple 平台的一个新库,它为系统调用和底层 currency 类型提供常用的接口。今天,我很高兴地宣布我们正式开源 System,并增加了 Linux 支持!我们的愿景是使 System 最终充当所有支持 Swift 平台的底级系统接口的唯一宿主。

导入 C 接口成为历史

如今,大多数操作系统都支持使用 C 语言编写的系统接口,这些接口已有数十年历史。尽管可以直接在 Swift 中使用这些 API,但是从 C 导入的这些类型较弱的系统接口可能容易出错且难以处理。例如,open 系统调用(可在类 UNIX 的操作系统上使用)作为一对全局函数导入:

func open(_ path: UnsafePointer<CChar>, _ oflag: Int32) -> Int32
func open(_ path: UnsafePointer<CChar>, _ oflag: Int32, _ mode: mode_t) -> Int32

这些弱类型函数有几个缺点,无法利用 Swift 的表现力和类型安全性:

  • 文件描述符以及选项,命令,errno 和其他值是以 Int32 类型被导入;

  • oflag 参数实际上是一个文件访问模式和任意数量的标志的逻辑或运算,但不会以 oflag 类型捕获;

  • open 的调用者必须记住检查指示错误的负返回值,从而则检查全局变量 errno 的值以了解发生了什么错误。此外,如果出现某些信号,某些系统调用可能会被取消,要求调用者记住围绕此类调用编写循环以检查 EINTR 错误。

  • 文件路径是非托管指针,并且如果它们是从托管对象(例如 Array

    )派生的,则调用者必须确保数组始终以 null 终止。

API 的签名中没有捕获任何这些语义规则,从而阻碍了编程语言引导用户正确使用 API。

常用的 Swift 接口

System 模块带来了多种语言功能,以提高表达能力并消除出现错误的机会。例如,System 使用 FileDescriptor 命名空间中的默认参数将 open 系统调用定义为静态函数:

extension FileDescriptor {
  /// Opens or creates a file for reading or writing.
  ///
  /// - Parameters:
  ///  - path: The location of the file to open.
  ///  - mode: The read and write access to use.
  ///  - options: The behavior for opening the file.
  ///  - permissions: The file permissions to use for created files.
  ///  - retryOnInterrupt: Whether to retry the open operation
  ///    if it throws `Errno.interrupted`.
  ///    The default is `true`.
  ///    Pass `false` to try only once and throw an error upon interruption.
  /// - Returns: A file descriptor for the open file
  ///
  /// The corresponding C function is `open`.
  public static func open(
    _ path: FilePath,
    _ mode: FileDescriptor.AccessMode,
     options: FileDescriptor.OpenOptions = FileDescriptor.OpenOptions(),
     permissions: FilePermissions? = nil,
     retryOnInterrupt: Bool = true
  ) throws -> FileDescriptor
}

如果将这个版本的 open 与C的原始版本进行比较时,会发现一些明显的区别:

  • System 普遍使用原始的可表示结构和选项集。这些强类型有助于在编译时捕获错误,并且在弱 C 类型之间来回转换很容易。

  • 使用标准语言机制会引发错误,并且不会遗漏任何错误。此外,所有可被信号中断的系统调用都采用默认值为 true 的 retryOnInterrupt 参数,从而使它们在失败时重试。当结合在一起时,这两个变化极大地简化了错误和信号处理。

  • FilePath 是一个托管的,以 Null 结尾的字节包,符合 ExpressibleByStringLiteral 的要求 -- 与UnsafePointer

     相比,使用起来更加安全。

结果是代码读起来像像常用的 Swift 的一样,行为也是一样。例如,以下代码从字符串字面量创建文件路径,并使用它打开并附加到日志文件:

let message: String = "Hello, world!" + "\n"
let path: FilePath = "/tmp/log"
let fd = try FileDescriptor.open(
  path, .writeOnly, options: [.append, .create], permissions: .ownerReadWrite)
try fd.closeAfter {
  _ = try fd.writeAll(message.utf8)
}

多平台库

System 是一个多平台的库,而不是一个跨平台的库。它在每个受支持的平台上提供一组单独的 API 和行为,紧密反映了底层 OS 接口。一次导入将引入特定于目标 OS 的平台接口。

我们的近期目标是简化跨平台库和应用程序的构建,例如 SwiftNIO 和 Swift Package Manager。系统并没有消除使用 #if os() 条件来实现跨平台抽象的需求,但是它确实使使用特定于平台的部分变得更加安全和富有表现力。

下一步

System 仅处于起步阶段,目前包括少量系统调用,currency 类型和便利功能。为了扩大 API 覆盖范围,我们将努力在 Swift Package Manager 中采用 System。这将包括FilePath的增强,并增加对 Windows 上 Swift 的支持。

还有大量令人兴奋的工作要做。System 是参与 Swift 项目并帮助其成长为强大,充满活力的跨平台生态系统的绝佳机会。

程序员专栏 扫码关注填加客服 长按识别下方二维码进群

近期精彩内容推荐:  

 看黄片,起诉网站,可尼玛太秀了

 知乎高赞:35岁失业的中年人都去了哪儿?

 求求你别再用offset和limit分页了

 Python 代码实现验证码识别,很稳

在看点这里好文分享给更多人↓↓

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值