我只是将Xcode更新为6.3,并且现在没有编译用于在Xcode 6.2中编译的Swift代码。
import Foundation
public enum Result<T> {
case Success(@autoclosure() -> T)
case Failure(NSError)
case Cancelled
public init(_ value: T) {
self = .Success(value)
}
public init(_ error: NSError) {
self = .Failure(error)
}
public init() {
self = .Cancelled
}
public var failed: Bool {
switch self {
case .Failure(let error):
return true
default:
return false
}
}
public var error: NSError? {
switch self {
case .Failure(let error):
return error
default:
return nil
}
}
public var value: T? {
switch self {
case .Success(let value):
return value()
default:
return nil
}
}
}
这一行:
case Success(@autoclosure() -> T)
产生错误:'autoclosure' attribute is only allowed on parameters, not on enum cases
删除@autoclosure
并不能解决问题。
答案 0 :(得分:3)
正确。这已被删除,明确是为了防止您提供的情况。 Autoclosures并不打算以这种方式使用,Swift团队故意删除了这样做的能力。在Result
类型中,这很危险,因为每次访问时都会重新关闭闭包。如果关闭中存在副作用,这可能会产生相当惊人的影响。即使它只是非平凡的,它也会产生令人惊讶的性能影响。
这里的正确工具是Box
。请参阅Rob Rix的Result
以获得此类型的良好实现。
答案 1 :(得分:1)
我认为我找到了解决方案。您只需在原始实现中更改2行即可使其正常工作:
case Success(() -> T)
和
public init(@autoclosure(escaping) _ value: () -> T) {
答案 2 :(得分:0)
对于那些只需要简单解决方案而无需导入外部框架的人:
public enum Result<T> {
case Success(Box<T>)
case Failure(String)
public init(_ value: T) {
self = .Success(Box(value))
}
public init(_ error: String) {
self = .Failure(error)
}
}
// Due to current swift limitations, we have to include this Box in Result.
final public class Box<T> {
public let unbox: T
public init(_ value: T) { self.unbox = value }
}
public func success<T>(value: T) -> Result<T> {
return .Success(Box(value))
}
public func failure<T>(error: String) -> Result<T> {
return .Failure(error)
}