iOS RxSwift - 如何解包一个 `Optional<Optional<T>>` 或 `T??`?
iOS RxSwift - How to unwrap an `Optional<Optional<T>>` or `T??`?
我正在使用以下逻辑使用 RxBlocking 检查我的主题的状态。我从 try? subject.verifier.toBlocking().first()
中得到了一个奇怪的值 Int??
。
下面的语法让编译器满意,但让我的眼睛流血。
如何从 RXBlocking 期望值中获取解包值?
func checkSubjectState() -> Int
{
let updatedChecksum = try? subject.verifier.toBlocking().first() ?? 0
return updatedChecksum ?? 0
}
let expectedCheckSum = checkSubjectState()
expect(expectedCheckSum).to(equal(knownValue))
是的,所以 first()
可以抛出 和 它 return 是一个可选类型,所以 try? first()
return 是一个Optional<Optional<Int>>
或 Int??
。坦率地说,我认为 first()
函数写得不好。它应该抛出 或 return 可选,而不是两者都抛出。
你可以写一个 flattened
运算符:
public protocol OptionalType {
associatedtype Wrapped
var value: Wrapped? { get }
}
extension Optional: OptionalType {
public var value: Wrapped? {
return self
}
}
extension Optional where Wrapped: OptionalType {
var flattened: Wrapped.Wrapped? {
switch self {
case let .some(opt):
return opt.value
case .none:
return nil
}
}
}
您可以这样做:
let expectedCheckSum = (try? subject.verifier.toBlocking().first()).flattened ?? 0
值不值由你说了算
我想出了另一个你可能更喜欢的解决方案:
infix operator ???: NilCoalescingPrecedence
func ???<T>(opt: T??, val: @autoclosure () -> T) -> T {
return ((opt ?? val()) ?? val())
}
以上内容可以让您简单地:
return (try? subject.verifier.toBlocking().first()) ??? 0
我试图为运算符提供比 try?
更高的优先级,这样就不需要括号了,但我找不到办法做到这一点。
这是一个不需要您定义任何您自己的函数的答案:
return (try? subject.verifier.toBlocking().first()).flatMap { [=10=] } ?? 0
还有另外两种方法可以通过处理错误来避免双重可选
先把错误交给调用者
func checkSubjectState() throws -> Int
{
return try subject.verifier.toBlocking().first() ?? 0
}
第二个添加一个do - catch
块
func checkSubjectState() -> Int
{
do { return try subject.verifier.toBlocking().first() ?? 0 }
catch { return 0 }
}
我正在使用以下逻辑使用 RxBlocking 检查我的主题的状态。我从 try? subject.verifier.toBlocking().first()
中得到了一个奇怪的值 Int??
。
下面的语法让编译器满意,但让我的眼睛流血。
如何从 RXBlocking 期望值中获取解包值?
func checkSubjectState() -> Int
{
let updatedChecksum = try? subject.verifier.toBlocking().first() ?? 0
return updatedChecksum ?? 0
}
let expectedCheckSum = checkSubjectState()
expect(expectedCheckSum).to(equal(knownValue))
是的,所以 first()
可以抛出 和 它 return 是一个可选类型,所以 try? first()
return 是一个Optional<Optional<Int>>
或 Int??
。坦率地说,我认为 first()
函数写得不好。它应该抛出 或 return 可选,而不是两者都抛出。
你可以写一个 flattened
运算符:
public protocol OptionalType {
associatedtype Wrapped
var value: Wrapped? { get }
}
extension Optional: OptionalType {
public var value: Wrapped? {
return self
}
}
extension Optional where Wrapped: OptionalType {
var flattened: Wrapped.Wrapped? {
switch self {
case let .some(opt):
return opt.value
case .none:
return nil
}
}
}
您可以这样做:
let expectedCheckSum = (try? subject.verifier.toBlocking().first()).flattened ?? 0
值不值由你说了算
我想出了另一个你可能更喜欢的解决方案:
infix operator ???: NilCoalescingPrecedence
func ???<T>(opt: T??, val: @autoclosure () -> T) -> T {
return ((opt ?? val()) ?? val())
}
以上内容可以让您简单地:
return (try? subject.verifier.toBlocking().first()) ??? 0
我试图为运算符提供比 try?
更高的优先级,这样就不需要括号了,但我找不到办法做到这一点。
这是一个不需要您定义任何您自己的函数的答案:
return (try? subject.verifier.toBlocking().first()).flatMap { [=10=] } ?? 0
还有另外两种方法可以通过处理错误来避免双重可选
先把错误交给调用者
func checkSubjectState() throws -> Int
{
return try subject.verifier.toBlocking().first() ?? 0
}
第二个添加一个do - catch
块
func checkSubjectState() -> Int
{
do { return try subject.verifier.toBlocking().first() ?? 0 }
catch { return 0 }
}