具有Void关联类型的Generic Swift 4枚举

时间:2017-08-23 11:02:47

标签: swift enums swift4

TL;博士

是否可以实例化具有Void类型关联值的通用Swift 4枚举成员?

背景

我使用简单的结果枚举(类似于antitypical Result):

enum Result<T> {
  case success(T)
  case error(Error?)
}

现在我想使用这个枚举来表示不产生实际结果值的操作的结果;操作是成功失败。为此,我将类型定义为Result<Void>,但我在如何创建结果实例方面苦苦挣扎,let res: Result<Void> = .successlet res: Result<Void> = .success()都无效。

5 个答案:

答案 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 saysSE-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())更具描述性和简单性。