Swift 错误:无法转换类型 'B -> 的值(A) ->()' 到预期的参数类型 '(A) ->空白'
我有一个 Swift 程序,它产生一个我无法理解的编译器错误.它归结为以下代码片段.
I have a Swift program that produces a compiler error I cannot understand. It boils down to the following code fragment.
Class A
是一个辅助类,它在初始化时提供一个处理程序函数,稍后将被调用.这个函数有一个 A
对象作为参数.
Class A
is a helper class that is upon initialization provided with a handler function that is to be called later. This function has an A
object as an argument.
Class B
初始化一个 A
类型的对象,并有一个函数 f
应该用作处理程序.或者,可以提供匿名代码块(闭包).
Class B
initializes an object of type A
and has a function f
that should be used as the handler. Alternatively, an anonymous code block (closure) could be provided.
class A {
init(_: (A) -> Void) {}
}
class B {
let a = A(f)
func f(a: A) {}
}
这会产生以下编译器消息:
This produces the following compiler message:
error: cannot convert value of type 'B -> (A) -> ()' to expected argument type '(A) -> Void'
let a = A(f)
^
Void
和 ()
是等价的,我想.
Void
and ()
are equivalent, I suppose.
我什至不理解双 ->
的类型表达式.这是什么类型的?
I do not even understand the type expression with the double ->
. What kind of type is this?
谁能解释一下这里出了什么问题?还有,怎么做才对?
Can anyone explain what's wrong here? And, how to do it right?
在初始化实例属性(如 a
)时不能引用实例方法(如 f
)code>),因为实例正是我们正在创建的.一种解决方案是声明您的实例属性 lazy
,如下所示:
You can't refer to an instance method (like f
) while initializing an instance property (like a
), because the instance is exactly what we are in the middle of creating. One solution is to declare your instance property lazy
, like this:
class A {
init(_: (A) -> Void) {}
}
class B {
func f(a: A) {}
lazy var a : A = A(self.f)
}
这是合法的,因为 lazy
保证 a
的初始化器不会被评估,直到 later,当实例 已创建.请注意,在此上下文中绝对需要 self
(通常我建议您始终在可以使用的地方使用它).
That is legal because lazy
guarantees that the initializer for a
won't be evaluated until later, when the instance has been created. Note that self
is absolutely required in this context (and in general I recommend you always use it wherever it can be used).
另一种解决方案是将a
声明为A!
(这样它就有一个初始值,即nil
)并初始化它"真正的"稍后.例如:
Another solution is to declare a
as an A!
(so that it has an initial value, namely nil
) and initialize it "for real" later. For example:
class A {
init(_: (A) -> Void) {}
}
class B {
func f(a: A) {}
var a : A!
init() {
self.a = A(self.f)
}
}