2

我今天又玩了 Swift,需要一个undefined()函数。基本上是一个函数,可以是您想要的任何类型,但在实际运行/评估时会崩溃。如果您还没有时间实现某个表达式但想查看程序类型是否检查,这将非常有用。

我还实现了一个Result<T>和一个(有问题的)函数,如果不成功则chain返回 left ,否则返回 right 。因此,签名是。我将右边定义为因为如果左边是失败的,则不需要评估它。Result<>Result<>chain<L,R>(l : Result<L>, r : @autoclosure () -> Result<R>) -> Result<R>Result<>@autoclosure

我对其中任何一个的有用性(或改进)不感兴趣,我只是对为什么我的程序在标记的行中崩溃感兴趣[L3]

请注意

  • 正如预期的那样[L1]工作正常(||被懒惰评估)
  • [L2]工作正常(chain在正确的论点中也很懒惰)

但是,奇怪的是

  • [L3]使评估程序崩溃undefined()

根据我的理解,L2 和 L3 在运行时应该是等价的:L3 只是告诉类型检查器它已经知道的东西......如果你将类型更改undefined() -> Result<T>(而不是() -> T),同样的效果也会发生,那么它甚至都可以工作没有as Result<String>.

这是我的所有代码:

import Foundation

enum Result<T> {
    case Success(@autoclosure () -> T);
    case Failure(@autoclosure () -> NSError)
}

func undefined<T>(file:StaticString=__FILE__, line:UWord=__LINE__) -> T {
    fatalError("undefined", file:file, line:line)
}

func chain<L,R>(l : Result<L>, r : @autoclosure () -> Result<R>) -> Result<R> {
    switch(l) {
    case .Failure(let f):
        return .Failure(f())
    case .Success(let _):
        return r()
    }
}

func testEvaluation() {
    let error = NSError(domain: NSPOSIXErrorDomain, code: Int(ENOENT), userInfo: nil)
    let failure : Result<String> = .Failure(error)
    assert(true || undefined() as Bool) // [L1]: works
    let x : Result<String> = chain(failure, undefined() as Result<String>) // [L2]: works
    print("x = \(x)\n")
    let y : Result<String> = chain(failure, undefined()) // [L3]: CRASHES THE PROGRAM EVALUATING undefined()
    print("y = \(y)\n")
}

testEvaluation()

信不信由你,程序的输出是:

x = (Enum Value)
fatal error: undefined: file main.swift, line 27
Illegal instruction: 4

这不可能!为什么as Result<String>(这是 L2 和 L3 之间的唯一区别)会改变程序的输出?这应该完全在类型检查器中处理,这意味着在编译时,不是吗?编译器错误?

您重现此问题的最快方法应该是:

  1. 将我所有的代码复制到剪贴板
  2. cd /tmp
  3. pbpaste > main.swift
  4. xcrun -sdk macosx swiftc main.swift
  5. ./main

实际输出:

x = (Enum Value)
fatal error: undefined: file main.swift, line 27
Illegal instruction: 4

预期输出:

x = (Enum Value)
y = (Enum Value)
4

1 回答 1

0

Swift 开发者 Joe Groff通过 Twitter确认为 bug 。

于 2015-01-19T16:29:38.820 回答