草庐IT

swift - 解释 Swift Closure 语法

coder 2023-09-13 原文

我是 Swift 和闭包的新手,并且正在寻求一些关于到底发生了什么的帮助。

示例 1:

func getData(completionHandler: ((NSArray?, NSError?) -> Void)?) -> Void {

那么函数getData,有一个completion handler,其中NSArray + NSError 是传递给函数的可选参数?以下位 -> Void) 吗? 返回类型是否为 void,即没有设置要返回且整个闭包是可选的?

然后我不确定下面的 -> Void 是什么意思 在这种情况下?

示例 2:

let task = session.dataTaskWithURL(url!, completionHandler: {data, response, error -> Void in
... do something
}

在这种情况下,completionHandler 数据、响应和错误在 block 内分配给常量 task。那是对的吗?我不确定 -> Void inerror 的关系,尤其是附加的 in

我花了一段时间查看各种代码,甚至自己编写了一些代码来熟悉语法,但很容易混淆,因为我发现了 http://fuckingclosuresyntax.com/

最佳答案

您对方法签名的看法是正确的。 -> Void)? 表示传入完成处理程序是可选的。 Void 表示该 block 不应返回供其调用者使用的值,这毫无意义。完成处理程序类型有一个闭包(匿名函数)类型,它正好接受 2 个参数:一个可选的 NSArray 类型和一个可选的 NSError 类型(所以要么/两者都可能为零)。它不会向调用者返回任何内容。

在你的第二个例子中,你实际上是在创建一个完成处理程序来传递给 dataTaskWithURL 方法,使用 data, response, error 作为参数(更多关于语法少量)。 -> Void 与之前相同,表明您的 block 不返回任何内容,尽管它位于 error 旁边。 in 只是用作编译器的分隔符,用于将闭包的参数与其主体分开。这种语法甚至有一点简写。我通常总是在 block 参数周围使用括号,但我想这取决于个人风格/品味/其他。因此,您的 completionHandler 定义也可能如下所示:

{ (data: NSData!, response: NSURLResponse!, error: NSError!) -> Void in // code, end with a }

现在发生了什么变得更清楚了。 Swift 做了很多推理,让你写得漂亮而紧凑,但如果你不熟悉代码,它可能会隐藏一些意义。这是定义一个闭包,它接受 3 个隐式展开的可选值作为参数:一个是 NSData! 类型,一个是 NSURLResponse!,一个是 NSError!。它不返回任何内容 (-> Void)。闭包的主体,即无论你想做什么,都在 in 之后直到下一个 。因为该方法准确地定义了将要传递到 block 中的类型,所以在实现中,参数可以通过省略类型注释来简单地推断它们的类型,从而从 data: NSData! 到 just 数据。同样在 Swift 中,省略闭包参数周围的括号是有效的,留下原始代码行。

关于swift - 解释 Swift Closure 语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29321223/

有关swift - 解释 Swift Closure 语法的更多相关文章

  1. ruby - 树顶语法无限循环 - 2

    我脑子里浮现出一些关于一种新编程语言的想法,所以我想我会尝试实现它。一位friend建议我尝试使用Treetop(Rubygem)来创建一个解析器。Treetop的文档很少,我以前从未做过这种事情。我的解析器表现得好像有一个无限循环,但没有堆栈跟踪;事实证明很难追踪到。有人可以指出入门级解析/AST指南的方向吗?我真的需要一些列出规则、常见用法等的东西来使用像Treetop这样的工具。我的语法分析器在GitHub上,以防有人希望帮助我改进它。class{initialize=lambda(name){receiver.name=name}greet=lambda{IO.puts("He

  2. ruby-on-rails - 使用 Sublime Text 3 突出显示 HTML 背景语法中的 ERB? - 2

    所以我在关注Railscast,我注意到在html.erb文件中,ruby代码有一个微弱的背景高亮效果,以区别于其他代码HTML文档。我知道Ryan使用TextMate。我正在使用SublimeText3。我怎样才能达到同样的效果?谢谢! 最佳答案 为SublimeText安装ERB包。假设您安装了SublimeText包管理器*,只需点击cmd+shift+P即可获得命令菜单,然后键入installpackage并选择PackageControl:InstallPackage获取包管理器菜单。在该菜单中,键入ERB并在看到包时选择

  3. ruby - 有人可以帮助解释类创建的 post_initialize 回调吗 (Sandi Metz) - 2

    我正在阅读SandiMetz的POODR,并且遇到了一个我不太了解的编码原则。这是代码:classBicycleattr_reader:size,:chain,:tire_sizedefinitialize(args={})@size=args[:size]||1@chain=args[:chain]||2@tire_size=args[:tire_size]||3post_initialize(args)endendclassMountainBike此代码将为其各自的属性输出1,2,3,4,5。我不明白的是查找方法。当一辆山地自行车被实例化时,因为它没有自己的initialize方法

  4. ruby - 覆盖相似的方法,更短的语法 - 2

    在Ruby类中,我重写了三个方法,并且在每个方法中,我基本上做同样的事情:classExampleClassdefconfirmation_required?is_allowed&&superenddefpostpone_email_change?is_allowed&&superenddefreconfirmation_required?is_allowed&&superendend有更简洁的语法吗?如何缩短代码? 最佳答案 如何使用别名?classExampleClassdefconfirmation_required?is_a

  5. ruby 语法糖 : dealing with nils - 2

    可能已经问过了,但我找不到它。这里有2个常见的情况(对我来说,在编程Rails时......)用ruby​​编写是令人沮丧的:"astring".match(/abc(.+)abc/)[1]在这种情况下,我得到一个错误,因为字符串不匹配,因此在nil上调用[]运算符。我想找到的是比以下内容更好的替代方法:temp="astring".match(/abc(.+)abc/);temp.nil??nil:temp[1]简而言之,如果不匹配,则简单地返回nil而不会出错第二种情况是这样的:var=something.very.long.and.tedious.to.writevar=some

  6. ruby - Ruby 语法糖有 "rules"吗? - 2

    我正在学习Ruby的基础知识(刚刚开始),我遇到了Hash.[]method.它被引入a=["foo",1,"bar",2]=>["foo",1,"bar",2]Hash[*a]=>{"foo"=>1,"bar"=>2}稍加思索,我发现Hash[*a]等同于Hash.[](*a)或Hash.[]*一个。我的问题是为什么会这样。是什么让您将*a放在方括号内,是否有某种规则可以在何时何地使用“it”?编辑:我的措辞似乎造成了一些困惑。我不是在问数组扩展。我明白了。我的问题基本上是:如果[]是方法名称,为什么可以将参数放在括号内?这看起来几乎——但不完全是——就像说如果你有一个方法Foo.d

  7. ruby - 如何让Ruby捕获线程中的语法错误 - 2

    我正在尝试使用ruby​​编写一个双线程客户端,一个线程从套接字读取数据并将其打印出来,另一个线程读取本地数据并将其发送到远程服务器。我发现的问题是Ruby似乎无法捕获线程内的错误,这是一个示例:#!/usr/bin/rubyThread.new{loop{$stdout.puts"hi"abc.putsefsleep1}}loop{sleep1}显然,如果我在线程外键入abc.putsef,代码将永远不会运行,因为Ruby将报告“undefinedvariableabc”。但是,如果它在一个线程内,则没有错误报告。我的问题是,如何让Ruby捕获这样的错误?或者至少,报告线程中的错误?

  8. ruby -::在 Ruby 语法中是什么意思? - 2

    这个问题在这里已经有了答案:WhatisRuby'sdouble-colon`::`?(12个答案)关闭8年前。什么是::?@song||=::TwelveDaysSong.new

  9. ruby - ruby 乘法语句中星号中断语法前的空格 - 2

    在添加一些空格以使代码更具可读性时(与上面的代码对齐),我遇到了这个:classCdefx42endendm=C.new现在这将给出“错误数量的参数”:m.x*m.x这将给出“语法错误,意外的tSTAR,期待$end”:2/m.x*m.x这里的解析器到底发生了什么?我使用Ruby1.9.2和2.1.5进行了测试。 最佳答案 *用于运算符(42*42)和参数解包(myfun*[42,42])。当你这样做时:m.x*m.x2/m.x*m.xRuby将此解释为参数解包,而不是*运算符(即乘法)。如果您不熟悉它,参数解包(有时也称为“spl

  10. ruby - 解释为局部变量会覆盖方法名称吗? - 2

    如thisquestion,当在其自己的赋值中使用未定义的局部变量时,它的计算结果为nil。x=x#=>nil但是当局部变量的名称与现有的方法名称冲突时,就比较棘手了。为什么下面的最后一个示例返回nil?{}.instance_eval{a=keys}#=>[]{}.instance_eval{keys=self.keys}#=>[]{}.instance_eval{keys=keys}#=>nil 最佳答案 在Ruby中,因为可以在没有显式接收器和括号的情况下调用方法,所以在局部变量引用和无接收器无参数方法调用之间存在语法歧义:f

随机推荐