2016-02-29 54 views
3

也许这是一个愚蠢的问题,但我找不到任何解决办法呢。所以,我的问题是,是有这样的功能的事件发射协议:迅速闭合不能覆盖任何

mutating func on(eventName:String, action:((Any?)->())) { 
    //.. 
} 

而且我想使用它,每当一个事件被触发了一些信息,告知听众。 例如,用于“登录”事件的访问令牌。

appSessionHadler.on("login") { (weak data: String?) in 
    //... 
} 

而且比我得到一个错误,我不能援引“上的”使用类型是参数列表。当然,它适用于任何:

appSessionHadler.on("login") { (weak data: Any?) in 
    //... 
} 

一切符合任何,所以我是一个,但困惑。有人可以解释这一点,请!

我可以用一个通用的协议解决这个问题,但它仍然让我很沮丧,它不喜欢这个作品。

回答

2

你正在做一个承诺,编译器无法保持。 on函数可以随意调用action以及任何类型的数据。但是您传递的函数只接受String。什么是应该做的,如果on包括下面的代码(直接或间接)系统:

action(1) 

1不是String,所以类型安全将被打破。编译器不能让你这样做。

另一种方式来思考这是on需要F类型的函数,你传递一个超的F而非亚型FStringAny的子类型。但功能参数以相反的顺序工作。 (String)->Void(Any)->Void的超类型。因此,这是与传递Any类型的变量到需要String的功能。从形式上讲,我们认为函数在参数上是逆变的,在返回值中是协变的。你可以阅读Type Variance in Swift

当你怀疑,仿制药是这里的正确答案。 Any几乎总是错误的工具。而且Any?是Swift中使用最困难的类型之一,所以我绝对会不惜一切代价避免使用这个类型。 (Optional本身就是Any一个亚型,而斯威夫特具有自动晋升为Optional,所以当你有Any?开始越来越双选配更糟的是很常见的。)

+0

非常感谢,我思前想这是完全清楚后: )现在,它的工作,如:'变异对 FUNC(:字符串,动作:eventName的?((T) - >()))' – gujci