iOS RxSwift - 如何打开`可选 >`或`T ??`?

问题描述 投票:1回答:4

我正在使用下面的逻辑来检查使用RxBlocking的主题的状态。我从Int??得到奇怪的try? subject.verifier.toBlocking().first()值。

下面的语法令编译器满意,但让我的眼睛流血。

如何从RXBlocking期望中获得未包装的值?

func checkSubjectState() -> Int
    {
      let updatedChecksum = try? subject.verifier.toBlocking().first() ?? 0
      return updatedChecksum ?? 0
    }

let expectedCheckSum = checkSubjectState()
expect(expectedCheckSum).to(equal(knownValue))
swift unit-testing swift4 rx-swift rx-blocking
4个回答
2
投票

这是一个答案,不需要您定义任何自己的功能:

return (try? subject.verifier.toBlocking().first()).flatMap { $0 } ?? 0

2
投票

是的,所以first()可以扔,它返回一个可选类型,所以try? first()返回一个Optional<Optional<Int>>Int??。坦率地说,我认为first()功能写得不好。它应该抛出或返回可选,而不是两者。

你可以写一个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

无论你认为它值得与否,都是你的号召。


2
投票

还有另外两种方法可以通过处理错误来避免双重可选

第一个将错误移交给调用者

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 }
}

1
投票

我提出了另一种我认为你可能更喜欢的解决方案:

infix operator ???: NilCoalescingPrecedence
func ???<T>(opt: T??, val: @autoclosure () -> T) -> T {
    return ((opt ?? val()) ?? val())
}

以上将允许您简单地:

return (try? subject.verifier.toBlocking().first()) ??? 0

我试图给操作员一个比try?更高的优先级,所以不需要父母,但我找不到办法做到这一点。

© www.soinside.com 2019 - 2024. All rights reserved.