无法将自身(实现协议)传递给 class 实例化的 init 方法。(Swift)
Not able to pass self (which implements a protocol) to init method of a class instantiation.(Swift)
我有这样的协议
public protocol FooProtocol {
associatedType someType
func doFoo(fooObject:someType) -> Void
}
我有一个 class 实现了这个协议
public class Foo<T> : FooProtocol {
private let _doFoo : (T) -> Void
init<P : FooProtocol where P.someType == T>(_dep : P) {
_doFoo = _dep.doFoo
}
public func doFoo(fooObject: T) {
_doFoo(fooObject)
}
}
到这里为止的一切对我来说都很好,现在在另一个 class 中,我使用 someType = MyType
实现 FooProtocol,然后当我尝试初始化 Foo
class 时T = MyType
通过在 Foo
的 init 方法中传递 self
class 我得到一个编译错误,我在这里做错了什么?
错误信息:
" Cannot invoke init with an argument list of type (_dep: NSObject -> () -> MyView)
"
public class MyView : UIViewController, FooProtocol {
func doFoo(fooObject : MyType) {
...
}
// Here I want to initialize the Foo<T> class
let fooInstant : Foo<MyType> = Foo.init(_dep : self)
// I get the error message on the above line the error
// message reads "Cannot invoke init with an argument list
// of type `(_dep: NSObject -> () -> MyView)`
}
不符合 someType == MyType
的 FooProtocol,因为我正在尝试用 T == MyType
初始化一个 Foo
对象,这在技术上应该可行吗?
看来这行得通
public class MyView : UIViewController, FooProtocol {
var fooInstant : Foo<MyType>!
public func initializeFooInstant(){
fooInstant = Foo.init(_dep : self)
}
func doFoo(fooObject : MyType) {
...
}
}
我认为系统不允许您访问 self 来初始化 let 属性,因为无法保证在您的 let 属性 初始化时 self 已完全初始化。
在上述情况下,您只需确保 fooInstance 在访问之前已初始化,否则程序将崩溃。
希望对您有所帮助。
理解self
的上下文是非常重要的。在这种情况下,self
并不意味着 MyView
.
的实例
你可以,但是通过这样做让它工作:
let fooInstant : Foo<String> = Foo.init(_dep : MyView())
如果不明白你想在这里做什么,我就不能多说了。
这实际上似乎与您的泛型或协议一致性没有任何关系。这只是您在 self
初始化之前尝试在 属性 赋值中访问 self
(默认 属性 值在 期间被赋值 初始化).
因此,解决方案是使用惰性 属性,如下所示:
lazy var fooInstant : Foo<MyType> = Foo(_dep : self)
这将在首次访问时创建,因此在 self
初始化后创建。
我有这样的协议
public protocol FooProtocol {
associatedType someType
func doFoo(fooObject:someType) -> Void
}
我有一个 class 实现了这个协议
public class Foo<T> : FooProtocol {
private let _doFoo : (T) -> Void
init<P : FooProtocol where P.someType == T>(_dep : P) {
_doFoo = _dep.doFoo
}
public func doFoo(fooObject: T) {
_doFoo(fooObject)
}
}
到这里为止的一切对我来说都很好,现在在另一个 class 中,我使用 someType = MyType
实现 FooProtocol,然后当我尝试初始化 Foo
class 时T = MyType
通过在 Foo
的 init 方法中传递 self
class 我得到一个编译错误,我在这里做错了什么?
错误信息:
" Cannot invoke init with an argument list of type
(_dep: NSObject -> () -> MyView)
"
public class MyView : UIViewController, FooProtocol {
func doFoo(fooObject : MyType) {
...
}
// Here I want to initialize the Foo<T> class
let fooInstant : Foo<MyType> = Foo.init(_dep : self)
// I get the error message on the above line the error
// message reads "Cannot invoke init with an argument list
// of type `(_dep: NSObject -> () -> MyView)`
}
不符合 someType == MyType
的 FooProtocol,因为我正在尝试用 T == MyType
初始化一个 Foo
对象,这在技术上应该可行吗?
看来这行得通
public class MyView : UIViewController, FooProtocol {
var fooInstant : Foo<MyType>!
public func initializeFooInstant(){
fooInstant = Foo.init(_dep : self)
}
func doFoo(fooObject : MyType) {
...
}
}
我认为系统不允许您访问 self 来初始化 let 属性,因为无法保证在您的 let 属性 初始化时 self 已完全初始化。
在上述情况下,您只需确保 fooInstance 在访问之前已初始化,否则程序将崩溃。
希望对您有所帮助。
理解self
的上下文是非常重要的。在这种情况下,self
并不意味着 MyView
.
你可以,但是通过这样做让它工作:
let fooInstant : Foo<String> = Foo.init(_dep : MyView())
如果不明白你想在这里做什么,我就不能多说了。
这实际上似乎与您的泛型或协议一致性没有任何关系。这只是您在 self
初始化之前尝试在 属性 赋值中访问 self
(默认 属性 值在 期间被赋值 初始化).
因此,解决方案是使用惰性 属性,如下所示:
lazy var fooInstant : Foo<MyType> = Foo(_dep : self)
这将在首次访问时创建,因此在 self
初始化后创建。