例如:
func f(x: Int) -> Int { return x }我期望它打印出
func h(f: @escaping (Int) -> Any) { if (f is (Int) -> Int) { print(f(1)) } else { print("无效") } }
h(f: f)
1
,但实际上它打印出了无效
。
如果 f(1) 是 Int {
- vacawamaf
中,Any
包装的实例的类型无法被编译器推断出来,除非调用了f
。在编译器的眼中,f
是一个形式为{ arg in; /*...*/; return someInstanceOfTypeAny }
的闭包。无论someInstanceOfTypeAny
实际上是否为Int
类型,只有通过实际研究由闭包f
返回的实际实例的类型(例如如@vacawama上面建议的那样),才能确定。下面的答案使用模板解决方法,在每次调用h
时,T
实际上是一个具体类型而不是运行时包装! - dfribf
传递给h
时,编译器知道f
的类型是(Int) -> Int
,我想知道为什么它不能将(Int) -> Any
缩小为子类型(Int) -> Int
?f
不是没有类型注释的匿名闭包。f
已经被很好地注释了。 - weakishAny
不是一个类型占位符(它持有任何符合Any
的类型),就像下面答案中使用的泛型类型占位符T
一样。如果你尝试将你的示例中的Any
替换为自定义类Base
,并将func f (...
的返回类型替换为Derived
(派生自Base
),并测试提供的闭包是否为(Int) -> Derived
,你会发现当向h
提供(Int) -> Derived
闭包时,仍然会进入"invalid"
主体,因为h
中的参数f
明确地被类型注释为(Int) -> Base
(即使提供了(Int) -> Derived
)。 - dfrib