我使用下面的逻辑来使用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))发布于 2018-09-01 02:42:26
是的,所以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你是否认为值得,这是你的决定。
发布于 2018-09-01 14:54:20
还有另外两种选择,通过处理错误避免双重可选。
首先将错误交给调用方。
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 }
}发布于 2018-09-01 11:24:32
我想出了另一个解决方案,我想你可能会更喜欢:
infix operator ???: NilCoalescingPrecedence
func ???<T>(opt: T??, val: @autoclosure () -> T) -> T {
return ((opt ?? val()) ?? val())
}以上将使您可以简单地:
return (try? subject.verifier.toBlocking().first()) ??? 0我试着给操作符一个比try?更高的优先级,这样就不需要父母了,但是我找不到一个方法。
https://stackoverflow.com/questions/52123969
复制相似问题