当泛型具有默认值时,使用泛型制作struct的实例 [英] Make instance of struct with a generic when the generic has a default value

查看:52
本文介绍了当泛型具有默认值时,使用泛型制作struct的实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将 ListStyle 存储在 SupportOpts 内的属性中,所以我添加了< S> 其中S:ListStyle 到结构声明(来自此

我应该在这里放什么?

 让选项:SupportOpts = SupportOpts< ListStyle>(标题:标题")///错误:协议类型"ListStyle"的值不符合"ListStyle";只有struct/enum/class类型可以符合协议let选项:SupportOpts = SupportOpts< S>(标题:"Title")///错误:在范围内找不到类型"S"(这很明显...)let选项:SupportOpts = SupportOpts< InsetGroupedListStyle>(标题:标题")///这行得通... 

即使我已经在 SupportOpts 中设置了默认值,我是否也必须指定 SupportOpts< InsetGroupedListStyle>(标题:标题")?

解决方案

当您需要添加 as!时,您可以说出问题了.那不是正确的方法.考虑有人选择其他 S 的情况:

 让选项= SupportOpts< InsetListStyle>(标题:标题") 

这将不得不崩溃.

相反,您想要扩展程序来使事情变得更方便.

  struct SupportOpts< S>其中S:ListStyle {var title:字符串=占位符";var listStyle:S//这里没有默认值} 

您的目标是拥有一个仅带有标题的 init ,因此您要添加:

 扩展SupportOpts其中S == InsetGroupedListStyle {init(title:字符串){self.init(title:标题,listStyle:InsetGroupedListStyle())}} 

然后进行类型推断就可以解决其余问题:

 让选项= SupportOpts(标题:标题") 

I wanted to store ListStyle in a property inside SupportOpts, so I added the <S> and where S: ListStyle to the struct declaration (from this 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
}

I can make an instance of it like this:

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

But, when I remove InsetGroupedListStyle() (I already set a default value inside SupportOpts):

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

I get:

Generic parameter 'S' could not be inferred, Explicitly specify the generic arguments to fix this issue [Fix]

So I pressed the Fix button, and it's now expecting a S: ListStyle:

What should I put here?

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...

Do I have to specify SupportOpts<InsetGroupedListStyle>(title: "Title"), even if I already set a default inside SupportOpts?

解决方案

You can tell that something has gone wrong when you needed to add as!. That isn't the right approach. Consider the case if someone chose a different S:

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

This would have to crash.

Instead, you want an extension to make things more convenient.

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

Your goal is to have an init that just takes title, so you add that:

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

And type inference will work out the rest:

let options = SupportOpts(title: "Title")

这篇关于当泛型具有默认值时,使用泛型制作struct的实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆