如何与合并运算符一起使用try?

时间:2019-03-06 10:47:46

标签: swift

我正在尝试从函数x分配一个值给f,该函数需要一个参数(字符串)并抛出。

会抛出当前范围,因此我认为不需要do ... catch

我正在尝试将try与合并运算符??一起使用,但出现此错误:'try' cannot appear to the right of a non-assignment operator

guard let x = try f("a") ??
              try f("b") ??
              try f("c") else {
    print("Couldn't get a valid value for x")
    return
}

如果我将try更改为try?

guard let x = try? f("a") ??
              try? f("b") ??
              try? f("c") else {
    print("Couldn't get a valid value for x")
    return
}

我收到警告Left side of nil coalescing operator '??' has non-optional type 'String??', so the right side is never used和错误:'try?' cannot appear to the right of a non-assignment operator

如果我每次都尝试?在方括号中:

guard let x = (try? f("a")) ??
              (try? f("b")) ??
              (try? f("c")) else {
    print("Couldn't get a valid value for x")
    return
}

它可以编译,但是x是可选的,我希望将其解包。

如果我删除问号:

guard let x = (try f("a")) ??
              (try f("b")) ??
              (try f("c")) else {
    print("Couldn't get a valid value for x")
    return
}

我收到错误Operator can throw but expression is not marked with 'try'

我正在使用Swift 4.2(在撰写本文时,这是Xcode中的最新版本)。

x中获取未包装值的正确方法是什么?

更新:* f()的返回类型为String?。我认为这是一个可选字符串这一事实很重要。

1 个答案:

答案 0 :(得分:4)

单个try可以覆盖整个表达式,因此您可以说:

  guard let x = try f("a") ?? f("b") ?? f("c") else {
    print("Couldn't get a valid value for x")
    return
  }

try?也一样:

  guard let x = try? f("a") ?? f("b") ?? f("c") else {
    print("Couldn't get a valid value for x")
    return
  }

尽管请注意,在Swift 4.2中,x将是String?,这是因为您正在将try?应用于一个已经可选的值,从而为您提供了一个双重包装的可选选项,其中{ {1}}只会解开一层。

要解决此问题,您可以合并为guard let

nil

但是在Swift 5中,由于SE-0230,这是不必要的, guard let x = (try? f("a") ?? f("b") ?? f("c")) ?? nil else { print("Couldn't get a valid value for x") return } 将由编译器自动展平为单个可选值。