无法访问 1.2.0

无法访问 1.2.0

测试测试过
语言语言 SwiftSwift
许可证 MIT
发布最后发布2017年7月
SwiftSwift 版本3.1.1
SPM支持 SPM

Nikolai Vazquez 维护。



codebeat badge

Unreachable 是一个 Swift µ框架,它允许编译器知道当代码路径无法到达时的情况。

构建状态

分支 状态
master

安装

兼容性

  • 平台
    • macOS 10.9+
    • iOS 8.0+
    • watchOS 2.0+
    • tvOS 9.0+
    • Linux
  • Xcode 8.0+
  • Swift 3.0+ & 4.0

使用 Swift 包管理器安装

Swift 包管理器 是一个用于 Swift 的去中心化依赖管理器。

  1. 将项目添加到您的 Package.swift 中。

    import PackageDescription
    
    let package = Package(
        name: "MyAwesomeProject",
        dependencies: [
            .Package(url: "https://github.com/nvzqz/Unreachable.git",
                     majorVersion: 1)
        ]
    )
  2. 导入 Unreachable 模块。

    import Unreachable

手动安装

只需将 Unreachable.swift 添加到您的项目中。

使用说明

亲自试试吧!下载仓库并打开 'Unreachable.playground'。

动态循环退出

在某些情况下,函数返回值的唯一方式是从循环中返回,但编译器可能没有足够的信息知道这一点。

func getValue() -> Int {
    for i in 0... {
        if i == 20 {
            return i
        }
    }
    assertUnreachable()
}

switch 条件

switch 声明可能应用于其分支的条件使其详尽无遗,但这可能对编译器来说不明显。

func sign(of value: Double?) -> FloatingPointSign? {
    switch value {
    case let x? where x >= 0:
        return .plus
    case let x? where x < 0:
        return .minus
    case .some:
        assertUnreachable()
    case .none:
        return nil
    }
}

安全性

unreachable() 调用是 未定义行为。为了防止这种情况,建议使用 assertUnreachable()

使用 assertUnreachable(),如果调用了此函数,则调试版本将通过致命错误退出。在优化构建中,这与调用 unreachable() 没有什么不同。

不可达与 fatalError()

assertUnreachable() 函数可以用作 fatalError() 的一种替代品。在调试模式下,它们产生相似的指令。然而,在编译时进行优化,assertUnreachable() 允许其父函数产生极少的指令。

这里我们正在检查一个 UnicodeScalar 的值是否在低端或高端范围内。因为我们知道这些是唯一的有效范围,我们可以让编译器知道第三个分支是不可达的。如果某个时刻 x 的值不在这两个范围之内,它将在非优化构建中发射断言失败。

不可达的情况下

func isLowerRange(_ x: UnicodeScalar) -> Bool {
    switch x.value {
    case 0...0xD7FF:
        return true
    case 0xE000...0x10FFFF:
        return false
    default:
        assertUnreachable()
    }
}

汇编输出

        .globl  __T011Unreachable12isLowerRangeSbs7UnicodeO6ScalarVF
        .p2align        4, 0x90
__T011Unreachable12isLowerRangeSbs7UnicodeO6ScalarVF:
        pushq   %rbp
        movq    %rsp, %rbp
        cmpl    $55296, %edi
        setb    %al
        popq    %rbp
        retq

使用 fatalError()

func isLowerRange(_ x: UnicodeScalar) -> Bool {
    switch x.value {
    case 0...0xD7FF:
        return true
    case 0xE000...0x10FFFF:
        return false
    default:
        fatalError("Unreachable")
    }
}

汇编输出

        .globl  __T011Unreachable12isLowerRangeSbs7UnicodeO6ScalarVF
        .p2align        4, 0x90
__T011Unreachable12isLowerRangeSbs7UnicodeO6ScalarVF:
        .cfi_startproc
        movb    $1, %al
        cmpl    $55296, %edi
        jb      LBB4_3
        addl    $-57344, %edi
        cmpl    $1056768, %edi
        jae     LBB4_4
        xorl    %eax, %eax
LBB4_3:
        retq
LBB4_4:
        pushq   %rbp
Lcfi0:
        .cfi_def_cfa_offset 16
Lcfi1:
        .cfi_offset %rbp, -16
        movq    %rsp, %rbp
Lcfi2:
        .cfi_def_cfa_register %rbp
        subq    $48, %rsp
        leaq    L___unnamed_2(%rip), %rax
        movq    %rax, (%rsp)
        movl    $0, 32(%rsp)
        movq    $56, 24(%rsp)
        movl    $2, 16(%rsp)
        movq    $69, 8(%rsp)
        leaq    L___unnamed_3(%rip), %rdi
        leaq    L___unnamed_4(%rip), %rcx
        movl    $11, %esi
        movl    $2, %edx
        movl    $11, %r8d
        xorl    %r9d, %r9d
        callq   __T0s17_assertionFailures5NeverOs12StaticStringV_SSAE4fileSu4lines6UInt32V5flagstFTfq4nxnnn_n
        subq    $40, %rsp
        .cfi_endproc

许可证

Unreachable 的所有源代码均根据 MIT 许可证发布。

Unreachable 的资源根据 CC BY-SA 4.0 许可证发布,并可以在 assets 分支中找到。