也许这是一个愚蠢的问题,但我还找不到任何解决方案。所以,我的问题是,有一个具有如下功能的事件发射器协议(protocol):
mutating func on(eventName:String, action:((Any?)->())) {
//..
}
我想用它来通知监听器,只要有一些信息触发了事件。 例如“登录”事件的访问 token 。
appSessionHadler.on("login") { (weak data: String?) in
//...
}
然后我得到一个错误,我不能用该类型的参数列表调用“on”。当然它适用于任何:
appSessionHadler.on("login") { (weak data: Any?) in
//...
}
一切都符合Any,所以我很困惑。请有人解释一下!
我可以用通用协议(protocol)解决这个问题,但它不能像这样工作,这仍然让我感到沮丧。
最佳答案
您正在做出编译器无法兑现的 promise 。 on 函数可以使用任何类型的数据自由调用 action。但是你传递的函数只接受 String。如果 on 包含以下代码(直接或间接),系统应该做什么:
action(1)
1 不是 String,因此会破坏类型安全。编译器不允许您这样做。
另一种思考方式是 on 接受类型为 F 的函数,并且您传递的是 的父类(super class)型 F 而不是 F 的子类型。 String 是 Any 的子类型。但是函数参数以相反的顺序工作。 (String)->Void 是 (Any)->Void 的父类(super class)型。所以这与将 Any 类型的变量传递给需要 String 的函数是一样的。形式上我们说函数在它们的参数上是逆变的,在它们的返回值上是协变的。您可以在 Type Variance in Swift 中阅读更多相关信息.
如您所料,泛型是这里的正确答案。 Any 几乎总是错误的工具。 Any? 是 Swift 中最难处理的类型之一,所以我绝对会不惜一切代价避免使用它。 (Optional 本身是 Any 的子类型,Swift 会自动提升为 Optional,所以当你有 Any 时很常见? 开始获得双重可选甚至更糟。)
关于ios - 快速关闭不能覆盖任何,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35697569/
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah
我试图在索引页中创建一个超链接,但它没有显示,也没有给出任何错误。这是我的index.html.erb代码。ListingarticlesTitleTextssss我检查了我的路线,我认为它们也没有问题。PrefixVerbURIPatternController#Actionwelcome_indexGET/welcome/index(.:format)welcome#indexarticlesGET/articles(.:format)articles#indexPOST/articles(.:format)articles#createnew_articleGET/article
我在pry中定义了一个函数:to_s,但我无法调用它。这个方法去哪里了,怎么调用?pry(main)>defto_spry(main)*'hello'pry(main)*endpry(main)>to_s=>"main"我的ruby版本是2.1.2看了一些答案和搜索后,我认为我得到了正确的答案:这个方法用在什么地方?在irb或pry中定义方法时,会转到Object.instance_methods[1]pry(main)>defto_s[1]pry(main)*'hello'[1]pry(main)*end=>:to_s[2]pry(main)>defhello[2]pry(main)
这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下
在Ruby类中,我重写了三个方法,并且在每个方法中,我基本上做同样的事情:classExampleClassdefconfirmation_required?is_allowed&&superenddefpostpone_email_change?is_allowed&&superenddefreconfirmation_required?is_allowed&&superendend有更简洁的语法吗?如何缩短代码? 最佳答案 如何使用别名?classExampleClassdefconfirmation_required?is_a
我正在处理旧代码的一部分。beforedoallow_any_instance_of(SportRateManager).toreceive(:create).and_return(true)endRubocop错误如下:Avoidstubbingusing'allow_any_instance_of'我读到了RuboCop::RSpec:AnyInstance我试着像下面那样改变它。由此beforedoallow_any_instance_of(SportRateManager).toreceive(:create).and_return(true)end对此:let(:sport_
我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI
我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的
下面的代码在我第一次运行它时就可以正常工作:require'rubygems'require'spreadsheet'book=Spreadsheet.open'/Users/me/myruby/Mywks.xls'sheet=book.worksheet0row=sheet.row(1)putsrow[1]book.write'/Users/me/myruby/Mywks.xls'当我再次运行它时,我会收到更多消息,例如:/Library/Ruby/Gems/1.8/gems/spreadsheet-0.6.5.9/lib/spreadsheet/excel/reader.rb:11