0

一个单例类中,我正在尝试以下代码,其中包含存储在字典中的 3 个 URL:

class DownloadManager {
    static let instance = DownloadManager()
    
    let urls = [
        "en" : URL(string: "https://wordsbyfarber.com/ws/top"),
        "de" : URL(string: "https://wortefarbers.de/ws/top"),
        "ru" : URL(string: "https://slova.de/ws/top")
    ]
    
    var cancellables = Set<AnyCancellable>()

    private init() {
        getTops()
    }
    
    func getTops() {
        guard let url = urls["en"] else { return }
        
        URLSession.shared.dataTaskPublisher(for: url) // COMPILE ERROR
            .tryMap(handleOutput)
            .decode(type: TopResponse.self, decoder: JSONDecoder())
            .sink { completion in
                print(completion)
            } receiveValue: { fetchedTops in
                // ... store entities in Core Data
            }
            .store(in: &cancellables)
    }

但由于某种原因,该行guard let url = urls["en"] else { return }不足以解开该值:

截屏

发生这种情况是因为URL构造函数可能返回 nil 吗?

还是因为字典可能没有键值?

为什么守卫声明在这里还不够?

4

3 回答 3

2

urls实际上是 type [String: URL?]。请注意,值类型是可选的,因为URL.init(string:)它是可失败的。

当您尝试从该字典中获取值时,您会得到一个URL??. 唯一解开可选的guard一层。

展开嵌套可选(无论有多少层)的一种方法是使用as?

guard let url = urls["en"] as? URL else { return }
于 2021-06-13T09:53:27.807 回答
1

那是Url初始化器返回一个可选的 + 的可选包装Dictionary,如果您确定所有 url 都是有效的,那么

 guard let url = urls["en"] else { return } 
 URLSession.shared.dataTaskPublisher(for: url!) // add only !

或仅

 URLSession.shared.dataTaskPublisher(for: urls["en"]!!)   // add !!
于 2021-06-13T10:04:48.877 回答
1

发生这种情况是因为 URL 构造函数可能返回 nil 吗?

是的。

let urls = [
    "en" : URL(string: "https://wordsbyfarber.com/ws/top"),
    "de" : URL(string: "https://wortefarbers.de/ws/top"),
    "ru" : URL(string: "https://slova.de/ws/top")
]

创建带有可选 URL ( [String: URL?]) 的字典,并且您的展开仅与字典的内容有关。

利用

let urls = [
    "en" : URL(string: "https://wordsbyfarber.com/ws/top")!,
    "de" : URL(string: "https://wortefarbers.de/ws/top")!,
    "ru" : URL(string: "https://slova.de/ws/top")!
]

对于像这样的硬编码 URL,或者如果不清楚 URL 是否有效,则进行双重解包。

于 2021-06-13T09:53:37.583 回答