0

我正在尝试将选项扩展为可读的内容,并且到目前为止实现了这一点:

@discardableResult
    func isNotNil(_ handler: (Wrapped) -> Void) -> Optional {
        switch self {
        case .some(let value):
            handler(value)
            return self
        case .none:
            return self
        }
    }
    
    @discardableResult
    func isNil(_ handler: () -> Void) -> Optional {
        switch self {
        case .some:
            return self
        case .none:
            handler()
            return self
        }
    }

这样我就可以在可选的情况下调用我的函数,例如:

viewModel?.title.isNotNil { _ in
   //do something
}.isNil {
  //handle error
}

问题是,我想重用这些函数来返回特定类型,我无法实现或遗漏了一些东西。例如:

let vm: MyViewModel = dataSource?.heading.isNotNil {
  return MyViewModel(title: $0.title, subtitle: $0.subtitle)
}

我一直在集思广益,希望能得到一些帮助。

谢谢!

4

2 回答 2

0

您在示例中所做的操作会引发错误。归结为

let vm: MyViewModel
if let heading = dataSource?.heading  {
   _ = MyViewModel(heading.title, heading.subtitle)
  vm = heading
}

所以你试图分配headingvm(我假设它们是不同的类型)并且你只是 MyViewModel在闭包中构造和删除你构造的

更好的选择是沿着这些思路:

func mapOptionalOrNot<T>(notNil: (Wrapped) -> T, isNil: () -> T) -> T {
    switch self {
    case .some(let value):
        return notNil(value)
    case .none:
        return isNil()
    }
}

你当然可以给这两个函数默认参数,这样你就可以把它们排除在外。

使用 Swift 5.3s 新的多重闭包,您可以执行类似的操作

let vm: MyViewModel = dataSource?.heading.mapOptionalOrNot { value in
    // Map if we have a value
    return MyViewModel(title: value.title, subtitle: value.subtitle)
} isNil: {
    // Map if we don't have a value
    return MyViewModel(title: "Empty", subtitle: "Empty")
}
于 2020-07-08T11:22:02.817 回答
0

Optional是通用的,并且有一个相关的类型,你也可以在你的扩展中使用。它被称为Wrapped

以下是一些可以粘贴到 Playground 中的示例代码:

import UIKit

extension Optional {
    @discardableResult
    func isNil(_ handler: () -> Void) -> Wrapped? { // <-- We are returning Wrapped, wich is a generic concrete type
        switch self {
        case .some:
            return self
        case .none:
            handler()
            return self
        }
    }
}

let str: String? = nil

// The function is used and the return value is assigned to the variable handled
let handled = str.isNil { 
    print("Handling nil value")
}

print(type(of: handled))
// Prints "Optional<String>

另请注意,您尝试构建的内容大部分已经存在:https ://developer.apple.com/documentation/swift/optional/1539476-map

您可能应该只使用 Swift 的地图而不是您自己的实现。

于 2020-07-08T11:19:04.943 回答