gpt4 book ai didi

ios - 从使用的类型泛型之一推断泛型类型

转载 作者:行者123 更新时间:2023-12-01 19:30:21 32 4
gpt4 key购买 nike

我有一个非常复杂的结构,Generic types在我的应用程序中。这可行,但有一个问题,在这个链的末尾,我需要指定一些类型 2 次,因为它们需要用作某个类的泛型,而这些泛型类型之一也需要泛型类型。它们总是与之前的类型相同。它是这样的<A, B, C<A, B>>这使它使用起来有点不愉快。有没有办法让它推断AB来自 C这是示例代码,具有剥离的功能:

// MARK: - Base classes that Im using, stripped from funcionalities.

// This one is a base for performing some detection. It can return any type as a result of scanning.
class DetectionPerformer<ResultType> {}

// This one adds possibility to load some model needed to perform scanning from the disk.
class LocalFileDetectionPerformer<ResultType, LocalModelType>: DetectionPerformer<ResultType> {
required init(localModelURL: URL) {}
}

// This one adds possibility to download this model and store it on the disk before loading.
class DownloadableDetectionPerformer<ResultType, LocalModelType>: LocalFileDetectionPerformer<ResultType, LocalModelType> {}

// This one wraps LocalFileDetectionPerformer inside DownloadableDetectionPerformer, and use them together.
class RemoteFileDetectionPerformer<ResultType, LocalModelType, LocalFileDetectionPerformerType: DownloadableDetectionPerformer<ResultType, LocalModelType>>: DetectionPerformer<ResultType> {

private let localFileDetectionPerformer: LocalFileDetectionPerformerType

init(remoteModelURL: URL) {
let localModelURL = Self.localModelURL(for: remoteModelURL)
localFileDetectionPerformer = LocalFileDetectionPerformerType(localModelURL: localModelURL)
}

static func localModelURL(for url: URL) -> URL {
url.appendingPathExtension("local")
}
}

// Detector is main object in application. It takes some type of Detector as init parameter, and works on it.
class Detector<ResultType, DetectionPerformerType: DetectionPerformer<ResultType>> {
let performer: DetectionPerformerType

init(performer: DetectionPerformerType) {
self.performer = performer
}
}

// Now I can implement some specific performers, whcich will do real work. For example:
class SamplePerformer: DownloadableDetectionPerformer<Int, String> {}

// And I'm able to create Detector with any type of Performer:

let detectorA = Detector(performer: SamplePerformer(localModelURL: URL(string: "")!))

// The problem begins, when I want to wrap Performer into RemoteFileDetectionPerformer

let detectorB = Detector(performer: RemoteFileDetectionPerformer<Int, String, SamplePerformer>(remoteModelURL: URL(string: "")!))

// Here I need to specify all 3 generic types of RemoteFileDetectionPerformer, even tough two first are always the same as generic types of SamplePerformer. I can't even specify different ones, as this would create an error.
// Is there some way for RemoteFileDetectionPerformer to infer these first two generic types from LocalFileDetectionPerformerType? Maybe I need to construct these some differently?

最佳答案

我觉得您在代码块的前半部分显示的类应该是协议(protocol)。也就是说,DetectionPerformer , LocalFileDetectionPerformer , DownloadableDetectionPerformer应该都是协议(protocol)。它们似乎没有任何真正的实现,正如您的评论“现在我可以实现一些特定的表演者,这将做真正的工作”中显而易见的那样。如果您有任何想要放入其中的实现,大多数时候您可以将其放入扩展中。为什么使它们成为协议(protocol)可以解决问题?因为那时我们可以使用关联类型而不是类型参数。

protocol DetectionPerformer {
associatedtype ResultType
}

// This one adds possibility to load some model needed to perform scanning from the disk.
protocol LocalFileDetectionPerformer: DetectionPerformer {
associatedtype LocalModelType
init(localModelURL: URL)
}

// This one adds possibility to download this model and store it on the disk before loading.
protocol DownloadableDetectionPerformer: LocalFileDetectionPerformer {}

// This one wraps LocalFileDetectionPerformer inside DownloadableDetectionPerformer, and use them together.
class RemoteFileDetectionPerformer<LocalFileDetectionPerformerType: DownloadableDetectionPerformer>: DetectionPerformer {
typealias ResultType = LocalFileDetectionPerformerType.ResultType
private let localFileDetectionPerformer: LocalFileDetectionPerformerType

init(remoteModelURL: URL) {
let localModelURL = Self.localModelURL(for: remoteModelURL)
localFileDetectionPerformer = LocalFileDetectionPerformerType(localModelURL: localModelURL)
}

static func localModelURL(for url: URL) -> URL {
url.appendingPathExtension("local")
}
}

class Detector<DetectionPerformerType: DetectionPerformer> {
let performer: DetectionPerformerType

init(performer: DetectionPerformerType) {
self.performer = performer
}
}

class SamplePerformer: DownloadableDetectionPerformer {
required init(localModelURL: URL) {

}

typealias ResultType = Int
typealias LocalModelType = String
}
这允许您执行以下操作:
let detectorB = Detector(performer: RemoteFileDetectionPerformer<SamplePerformer>(remoteModelURL: URL(string: "")!))

关于ios - 从使用的类型泛型之一推断泛型类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63174268/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com