swift – 通用约束类型的默认值

swift – 通用约束类型的默认值,第1张

概述请考虑以下代码: protocol JSONParserType { associatedtype Element}// MARK: - Entitiesstruct Item {}// MARK: - Parsersstruct OuterParser<T: JSONParserType where T.Element == Item>: JSONParserType { 请考虑以下代码:

protocol JsONParserType {    associatedtype Element}// MARK: - EntitIEsstruct Item {}// MARK: - Parsersstruct OuterParser<T: JsONParserType where T.Element == Item>: JsONParserType {    typealias Element = Item    let innerParser: T    init(innerParser: T = InnerParser()) {        self.innerParser = innerParser    }}struct InnerParser: JsONParserType {    typealias Element = Item}

OuterParser有一个子解析器,应该被约束到一个特定的类型.不幸的是,在初始化程序中(或在属性定义本身中)提供默认值会导致编译器抛出“类型为’InnerParser’的默认参数值’无法转换为类型’T’”.

如果我删除默认值赋值并只是实例化显式提供InnerParser的OuterParser,一切都很好.

let outerParser = OuterParser(innerParser: InnerParser())

我的问题是,提供实际满足约束的默认值的方法不起作用的原因是什么.

解决方法 问题是T的实际类型不是由类定义的 – 它是由使用该类的代码定义的.因此,在您在类中执行任何 *** 作(在实例或静态级别)之前,将对其进行定义.因此,您无法将InnerParser分配给T,因为T已经被该点定义为给定类型,这可能不是InnerParser.

例如,让我们考虑你有另一个解析器结构:

struct AnotherParser: JsONParserType {    typealias Element = Item}

我们假设你当前的代码编译.现在考虑一下当你这样做时会发生什么:

let parser = OuterParser<AnotherParser>()

您已将泛型类型定义为AnotherParser – 但初始化程序将尝试将InnerParser分配给您的属性(现在类型为AnotherParser).这些类型不匹配,因此无法工作.

遵循相同的逻辑,此实现也将不起作用:

struct OuterParser<T: JsONParserType where T.Element == Item>: JsONParserType {    typealias Element = Item    let innerParser: T    init() {        self.innerParser = InnerParser()    }    init(innerParser: T) {        self.innerParser = innerParser    }}

因为不能保证泛型类型T与InnerParser的类型相同.当然,你可以强制转发为T – 但如果类型不兼容,这只会让你的代码崩溃.

不幸的是,这个问题没有真正干净的解决方案.我认为最好的选择可能是创建两个工厂方法来创建OuterParser实例.

enum Parser {    static func createParser() -> OuterParser<InnerParser> {        return OuterParser(innerParser:InnerParser())    }    static func createParser<T>(innerParser:T) -> OuterParser<T> {        return OuterParser(innerParser:innerParser)    }}
let innerParser = Parser.createParser() // OuterParser<InnerParser>let anotherParser = Parser.createParser(AnotherParser()) // OuterParser<AnotherParser>

我们在这里使用无壳枚举来避免使用额外函数污染全局命名空间.

虽然这不是很快,但出于这个原因,我也建议我们重新思考你如何定义解析器的逻辑.

总结

以上是内存溢出为你收集整理的swift – 通用约束类型的默认值全部内容,希望文章能够帮你解决swift – 通用约束类型的默认值所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1003136.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-22
下一篇 2022-05-22

发表评论

登录后才能评论

评论列表(0条)

保存