代码之家  ›  专栏  ›  技术社区  ›  aheze But I'm Not A Wrapper Class

当泛型具有默认值时,使用泛型生成结构的实例

  •  1
  • aheze But I'm Not A Wrapper Class  · 技术社区  · 4 年前

    我想储存 ListStyle SupportOpts ,所以我添加了 <S> where S: ListStyle answer

    struct SupportOpts<S> where S: ListStyle {
        var title: String = "Placeholder"
        var listStyle: S = InsetGroupedListStyle() as! S /// had to put an `as! S` or else it couldn't compile
    }
    

    我可以这样举个例子:

    let options: SupportOpts = SupportOpts(
        title: "Title",
        listStyle: InsetGroupedListStyle()
    )
    

    InsetGroupedListStyle() (我已经在里面设置了一个默认值 支持选项

    let options: SupportOpts = SupportOpts(
        title: "Title"
    )
    

    我得到:

    所以我按下了修复按钮,它现在期望 S: ListStyle error "Cannot find type '<#S: ListStyle#>' in scope"

    let options: SupportOpts = SupportOpts<ListStyle>(title: "Title")
    /// Error: Value of protocol type 'ListStyle' cannot conform to 'ListStyle'; only struct/enum/class types can conform to protocols
    
    let options: SupportOpts = SupportOpts<S>(title: "Title")
    /// Error: Cannot find type 'S' in scope (well that's kind of obvious...)
    
    let options: SupportOpts = SupportOpts<InsetGroupedListStyle>(title: "Title")
    /// this works...
    

    我必须具体说明吗 SupportOpts<InsetGroupedListStyle>(title: "Title") ,即使我已经在里面设置了默认值 ?

    1 回复  |  直到 4 年前
        1
  •  1
  •   Rob Napier    4 年前

    当你需要补充的时候,你可以看出有些地方出了问题 as! . 这不是正确的方法。如果有人选择了不同的 S :

    let options = SupportOpts<InsetListStyle>(title: "Title")
    

    相反,您需要一个扩展,使事情更方便。

    struct SupportOpts<S> where S: ListStyle {
        var title: String = "Placeholder"
        var listStyle: S     // No default value here
    }
    

    init 这只是标题,所以你加上:

    extension SupportOpts where S == InsetGroupedListStyle {
        init(title: String) {
            self.init(title: title, listStyle: InsetGroupedListStyle())
        }
    }
    

    类型推断将解决剩下的问题:

    let options = SupportOpts(title: "Title")