- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我今天又开始玩 Swift 并且需要一个 undefined()
功能。基本上,一个函数可以是您想要的任何类型,但在实际运行/评估时会崩溃。如果您还没有时间实现某个表达式但想查看程序类型是否检查,这将很有用。
我还实现了一个 Result<T>
和一个(有问题的)函数 chain
返回左边的 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 之间唯一的区别)改变程序的输出?这应该完全在类型检查器中处理,这意味着在编译时,不是吗?编译器错误?
重现此内容的最快方法应该是:
cd /tmp
pbpaste > main.swift
xcrun -sdk macosx swiftc main.swift
./main
实际输出:
x = (Enum Value)
fatal error: undefined: file main.swift, line 27
Illegal instruction: 4
预期输出:
x = (Enum Value)
y = (Enum Value)
最佳答案
已被 Swift 开发人员 Joe Groff 确认为错误 via Twitter .
关于Swift @autoclosure 评估受类型注释的影响? (编译器错误?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28004126/
对这个有点惊讶。在 Swift 3 中,这段代码编译... class func test(foo:@autoclosure () -> Void) { } 但这不... typealias Void
考虑以下函数: func whatever(foo: @autoclosure () -> Int) { let x = foo() print(x) } 当然,我们可以这样调用它: what
??的定义运算符是: public func ??(optional: T?, defaultValue: @autoclosure () throws -> T) rethrows -> T 为什么
我今天又开始玩 Swift 并且需要一个 undefined()功能。基本上,一个函数可以是您想要的任何类型,但在实际运行/评估时会崩溃。如果您还没有时间实现某个表达式但想查看程序类型是否检查,这将很
考虑这样的代码: func log(_ msg: @autoclosure @escaping () -> Any?) { print(msg) } class Foo { let b
我注意到在 Swift 中编写 assert 时,第一个值被键入为 @autoclosure() -> Bool 使用重载方法返回通用 T 值,通过 LogicValue protocol 测试是否存
我想知道是否有等同于 Swift's @autoclosure feature 的东西 本质上,我希望能够在一个函数或构造函数/初始化器中创建一个参数,它可以接受另一个接受参数的函数,并执行它: cl
我正在使用 Xcode 8 将代码转换为 Swift,但编译器警告在一些已在 Swift 2.3 中使用闭包语法创建的嵌套函数中添加 @escape。我还发现了一些其他关键字 @noescape 和
我在 Swift 周围闲逛,发现 fatalError 有这个签名: @noreturn public func fatalError(@autoclosure message: () -> Stri
我刚刚将 Xcode 更新到 6.3,以前在 Xcode 6.2 中编译的 Swift 代码现在无法编译。 import Foundation public enum Result { cas
既然 @autoclosure 是参数声明的一部分而不是类型,那么如何声明函数采用可变数量的自动闭包? 之前: public func coalesce(all : @autoclosure () -
我想在 dispatch_async block 中调用一个@autoclosure 参数。 func myFunc(@autoclosure condition: () -> Bool) { d
我是一名优秀的程序员,十分优秀!