TL;博士
是否可以实例化具有Void
类型关联值的通用Swift 4枚举成员?
背景
我使用简单的结果枚举(类似于antitypical Result):
enum Result<T> {
case success(T)
case error(Error?)
}
现在我想使用这个枚举来表示不产生实际结果值的操作的结果;操作是成功或失败。为此,我将类型定义为Result<Void>
,但我在如何创建结果实例方面苦苦挣扎,let res: Result<Void> = .success
和let res: Result<Void> = .success()
都无效。
答案 0 :(得分:56)
在Swift 3中,您可以省略类型Void
的相关值:
let res: Result<Void> = .success()
在Swift 4中,您必须传递类型为Void
的关联值:
let res: Result<Void> = .success(())
// Or just:
let res = Result.success(())
答案 1 :(得分:27)
在Swift 4中,具有Void
关联值的枚举案例不再等同于具有关联值的空列表的枚举案例。
我相信这是as Martin says,SE-0029的结果,你不能再将一个参数元组传递给一个函数并让它们&#34; splat&#34;跨参数(虽然提案已在Swift 3中标记,但我相信这个特殊情况后来在Swift 4的SE-0110实现中被提到。)
因此,这意味着您无法再在Swift 4中将(Void) -> T
称为() -> T
。您现在必须明确地传递Void
:
let result = Result.success(())
然而,我觉得这很难看,所以我通常会实现这样的扩展:
extension Result where T == Void {
static var success: Result {
return .success(())
}
}
这可以让你说出这样的话:
var result = Result.success
result = .success
值得注意的是,这种解决方法并不仅限于枚举案例,它也可以与一般的方法一起使用。例如:
struct Foo<T> {
func bar(_ a: T) {}
}
extension Foo where T == Void {
func bar() { bar(()) }
}
let f = Foo<Void>()
// without extension:
f.bar(())
// with extension:
f.bar()
答案 2 :(得分:4)
Swift 5 已将“结果”更新为需要“失败”参数,但仍需要关联的值:
let res: Result<Void, Error> = .success(())
答案 3 :(得分:3)
Void是空元组的简单类型:()所以你可以使用它作为以下任何一种:
let res1: Result<Void> = .success(())
let res2 = Result<Void>.success(())
let res3 = Result.success(() as Void)
let res4 = Result.success(())
答案 4 :(得分:2)
我发现.success(Void())
更具描述性和简单性。