问题
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
?
回答1:
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")
来源:https://stackoverflow.com/questions/64529932/make-instance-of-struct-with-a-generic-when-the-generic-has-a-default-value