[英]swift convenience init and generic class
I have a problem creating a convenience init method that then calls a designated init on a class with generic type parameters. 我在创建一个方便的init方法时遇到问题,然后在具有泛型类型参数的类上调用指定的init。 Here is the swift 3.1 XCode Version 8.3.2 (8E2002) playground
这是swift 3.1 XCode版本8.3.2(8E2002)游乐场
protocol A {
var items: [String] { get set }
func doSomething()
}
struct Section : A {
var items: [String] = []
func doSomething() {
print("doSomething")
items.forEach { print($0) }
}
}
class DataSource<T: A> {
var sections: [T]
init(sections: [T]) {
self.sections = sections
}
func process() {
sections.forEach { $0.doSomething() }
}
convenience init() {
var section = Section()
section.items.append("Goodbye")
section.items.append("Swift")
self.init(sections: [section])
}
}
/*: Client */
var section = Section()
section.items.append("Hello")
section.items.append("Swift")
let ds = DataSource(sections: [section])
ds.process()
If no convenience init exists, then the code beneath the /*: Client */ section compiles and executes without issue. 如果不存在便利init,那么/ *:Client * /部分下面的代码将编译并执行而不会出现问题。 If I add in the convenience init I get the following compilation error:
如果我添加了方便init,我得到以下编译错误:
cannot convert value of type '[Section]' to expected argument type '[_]'
self.init(sections: [section])
I wouldn't think that this would be an issue since in the convenience init I am creating a Section struct which implements the protocol A which satisfies the generic constraint on the DataSource class. 我不认为这会是一个问题,因为在方便初始化我创建了一个Section结构,它实现了满足DataSource类的通用约束的协议A. The convenience init is performing the same operations as the client code, yet it is unable to convert a [Section] into a [A].
便利init正在执行与客户端代码相同的操作,但它无法将[部分]转换为[A]。 Is this an initialization sequencing issue?
这是初始化排序问题吗?
Generic placeholders are satisfied at the usage of the given generic type – therefore inside your convenience init
, you cannot assume that T
is a Section
. 通用占位符对给定泛型类型的使用感到满意 - 因此在您的
convenience init
,您不能假设 T
是一个Section
。 It's an arbitrary concrete type that conforms to A
. 它是符合
A
的任意具体类型。
For example, it would be perfectly legal for the caller to define a 例如,调用者定义a是完全合法的
struct SomeOtherSection : A {...}
and then call your convenience initialiser with T
being SomeOtherSection
. 然后使用
T
为SomeOtherSection
调用您的便利初始化程序。
The solution in this case is simple, you can just add your convenience initialiser in an extension of DataSource
, where T
is constrained to being Section
– therefore allowing you to 在这种情况下的解决方案很简单,您只需在
DataSource
的扩展中添加便利初始化器,其中T
被约束为Section
- 因此允许您
call init(sections:)
with a [Section]
: 用
[Section]
调用init(sections:)
:
extension DataSource where T == Section {
convenience init() {
var section = Section()
section.items.append("Goodbye")
section.items.append("Swift")
self.init(sections: [section])
}
}
// ...
// compiler will infer that T == Section here.
let ds = DataSource()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.