ios - 如何在 Swift 5.1 (Xcode 11 Playground) 中实现可选的泛型和非泛型函数签名的重载?
问题描述
import Foundation
enum Errors: Error {
case badParse
}
public typealias JSONDictionary = [String: Any]
public func decode(_ dictionary: JSONDictionary, key: String) throws -> URL {
guard let string = dictionary[key] as? String else {
throw Errors.badParse
}
if let url = URL(string: string) {
return url
}
throw Errors.badParse
}
public func decode<T>(_ dictionary: JSONDictionary, key: String) throws -> T {
guard let value = dictionary[key] else {
throw Errors.badParse
}
guard let attribute = value as? T else {
throw Errors.badParse
}
return attribute
}
let url: URL = try decode(["url":"test/url"], key: "url") // url: test/url
let urlOptional: URL? = try? decode(["url":"test/url"], key: "url") // nil
只要您正在解码非可选代码,上面的代码就可以工作。调用特定的非泛型解码函数并构造 URL。
但是,如果您有一个可选类型变量并对其进行解码,它将不会使用正确的函数。在 swift 4.2 中,可选项和非可选项都将使用正确的非泛型函数,但是自从我更新到 Xcode 11 swift 5.1 后,已经看到了这种行为。
任何帮助将不胜感激!
我不希望使用可选返回来制作函数签名,例如
public func decode(_ dictionary: JSONDictionary, key: String) throws -> URL? {
因为它是不可扩展的......而且它曾经在没有它的情况下工作。
解决方案
显然,类型推断的工作方式在 Swift 5 中发生了一些变化。如果你只想让它使用正确的重载,你只需要稍微推动一下:
let urlOptional: URL? = try? decode(["url":"test/url"], key: "url") as URL
通过as URL
在最后添加。
推荐阅读
- c# - 将“+”转换为求值运算符
- postgresql - 如何在从 postgres 中的另一个函数返回的函数中获取 refcursor?
- python - 有没有办法停止 pycurl perform() 执行?
- spring - jhispter 自定义 webflux 安全异常
- php - 带有来自 dbase 的 if 和 else 条件值的滑动条 php
- javascript - 无法让 Mapbox SDK 识别 geocodeForward 请求中的模糊匹配属性
- javascript - 使用 JavaScript 将任何日期格式转换为 en-US(mm/dd/yyyy hh:mm:ss)
- javascript - 如何解决 window.open() 的选项在 Edge 上不起作用
- javascript - 根据百分比拒绝输入
- php - 定义与同一模型的关系(自连接)Laravel - 找不到类'App\Models\App\Models\Contact_cats' laravel 8