【问题标题】:Swift 4 equivalent of Kotlin "anonymous class" notationSwift 4 等效于 Kotlin“匿名类”表示法
【发布时间】:2018-07-31 11:59:48
【问题描述】:

我用 Kotlin 写了一段时间,我习惯使用下一个模式:

variable.addSomething(object: TargetType() { ...code... })

var variable = object: TargetType() { ...code... }

(如果我没有遗漏什么)

是否有可能在 Swift 中以某种方式使用这种模式?它是怎么称呼的? :)

编辑: 我真正想做的 - 将预先配置的 RxSwift.SingleEvent 存储在对象内部的 let / var 中,并在以后多次重复使用。

在代码中,我想应该是这样的:

private var observer = SingleEvent<Response>(ok_callback, error_callback) { 
      override success(el: Element) {
             ok_callback(el)
             super.success(el)
    }
      override error(er: Error) {
           self.onErrorRetry(er, callback)
    }
}

如果在一些神奇的作品之后重试 - 只需调用我的回调并返回 :)

【问题讨论】:

  • 这个“对象:闭包”被称为“匿名类”。
  • Anonymous class in swift的可能重复
  • @user28434 14 年使用的语言发生了很大变化。实际上 Swift 4 与标记答案中使用的完全不同(尽管它在编译时抛出错误)
  • @Pawel 在 Java 中会这样称呼,但在 Kotlin 中则是"object expression"
  • 我认为 Swift 4 中没有等效的概念,即使有方法可以模拟它,如@user28434 链接的问题中所描述的那样。你最好的选择是使用一个简单的、旧的、无聊的结构/类来实现你感兴趣的协议/接口

标签: android ios swift kotlin


【解决方案1】:

它似乎是尾随关闭。改编自Swift programming language - Closures

如果您需要将闭包表达式作为 函数的 final 参数 并且闭包表达式很长,它可以 将其写为尾随闭包会很有用。尾随 闭包写在函数调用的括号之后,即使 它仍然是函数的参数。当你使用尾随 闭包语法,你不要将闭包的参数标签写为 函数调用的一部分。

让我们编码吧:

简单地说,你所要做的就是创建一个函数,它的最后一个参数是一个闭包:

func doSomething(firstParameter: Any, closure: () -> Void) { }

因此您可以将其称为:

doSomething(firstParameter: "whatever") {
    // ...
}

这里没有什么特别之处,它是 Swift 语言的一个很酷的功能,可以“跟踪”closure 参数,如果它是函数签名中的最后一个参数。

在初始化的情况下,几乎是一样的:

struct MyObject {
    init(firstParameter: Any, closure: () -> Void) { }
}

let variable = MyObject(firstParameter: "whatever") {  }

当然,语言中的许多其他功能都遵循此模式,但这里是 Dictionary 的merge 方法的示例,您可以认识到如何以多种方式键入它,如答案中提到的那样作者:Map Dictionary Keys to add values - Swift


更新:

如果您打算将其用作常量/变量 - 例如传递给函数 - 您可以这样做:

let variable: (String) -> Void = { name in
    print("The name is: \(name)!")
}

此时,variable 类型为(String) -&gt; Void,这意味着它是一个可以传递到其他地方的常量;考虑以下方法:

func doSomething(closure: (String) -> Void) {
    closure("Nikita")
}

因为doSomething 采用(String) -&gt; Void 类型的参数,您可以这样做:

doSomething(closure: variable) // The name is: Nikita!

而不是将其称为:

doSomething { name in
    print("The name is: \(name)!")
}

这会阻止样板代码。

【讨论】:

  • 实际上,它并不完全相同,因为尾随闭包,在调用函数内部你只能“调用”这个闭包,但是正如@Pawel 提到的,匿名类 - 你会收到一个完整的对象在调用函数内部,你可以选择你想用它做什么,而不是调用它的方法或设置参数。
  • @NikitaYankov mmm,我好像误会了什么,请您详细说明一下?
  • 我编辑了我的问题 - 无法在评论中格式化代码:C
  • Kotlin 有尾随闭包语法,但这个问题没有显示出来。这是关于声明一个完整的对象,该对象实现给定接口(不一定是 SAM 接口)的所有方法,并且还可能包含属性声明。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-23
  • 1970-01-01
相关资源
最近更新 更多