Swift-如何在函数中实现协议方法

Swift-如何在函数中实现协议方法,swift,Swift,在android中,可以在函数调用期间实现接口方法。例如,接口和函数的声明: //interface interface exampleCallback { void success(String response); void error(String error); } //function void exampleFunction(exampleCallback cb) { //do something } 以及函数调用: exampleFunction(new

在android中,可以在函数调用期间实现接口方法。例如,接口和函数的声明:

//interface
interface exampleCallback {
    void success(String response);
    void error(String error);
}

//function
void exampleFunction(exampleCallback cb) {
    //do something
}
以及函数调用:

exampleFunction(new exampleCallback() {
    @Override
    public void success(String response) {
        //custom method implementation
    }
    @Override
    public void error(String error) {
        //custom method implementation
    }
});
也就是说,可以为exampleFunction的每个函数调用自定义成功/错误方法。
然而,在一些google搜索之后,我只能在类或结构声明中找到实现协议方法的示例代码,在这些代码中,这些方法不再可以自定义。我知道我可以将转义闭包作为函数参数传递,以实现目标,即为每个函数调用自定义回调函数。但我只是想知道我是否可以使用协议来做类似的事情…

Java中的匿名类实际上只是一个“解决方案”,因为它没有作为“第一类公民”的函数

在swift中,函数是第一类公民,因此实际上不需要传递实现单个方法的匿名类。您只需传递该方法(有点类似于Java8的lambdas)

这在Java中是:

interface ActionListener {
    void actionPerformed();
}
只能用Swift中的闭包类型表示:

() -> Void
someMethod { ... }
而不是这样做:

someMethod(new ActionListener() {
    public void actionPerformed() { ... }
});
您可以使用Swift执行此操作:

() -> Void
someMethod { ... }

如果Java中的接口有多个方法要实现呢

在这种情况下,不能使用一个闭包来表示所有闭包。你要么

  • 创建具有多个方法的协议,并在结构或类中实现它。您在
    UIKit
    中经常看到这种模式。视图和视图控制器通常具有
    XXXDelegate
  • 传递闭包的元组

您可以创建带有关联值的枚举:

enum Result {
    case success(String)
    case error(CustomError)
}
enum CustomError: Error {
    case expired(String)
}
并使用方法的完成处理程序中的枚举案例传递自定义字符串:

func exampleFunction(completion: @escaping (Result) -> ()) {
    if condition {
        completion(.success("Success String"))
    } else {
        completion(.error(.expired("Error String"))) 
    }
}
调用方法时,您可以切换枚举并在其中执行自定义实现,还可以使用回调中返回的关联值:

exampleFunction { result in
    switch result {
    case let .success(response):
        // custom method implementation
        // use your (response) string here
    case let .error(error):
        // custom method implementation
        // use your (error.localizedDescription) string here
    }
}

Swift没有匿名对象。要实现回调,请阅读有关闭包的内容。为什么要在
Result
Error
的故障情况下调用
Callback
。如果OP需要,它可以使用
LocalizedError将
String
错误转换为实际的
error
我使用了命名,试图匹配OP在问题中使用的名称。当然,我可以创建一个枚举错误,将字符串作为要传递的关联值,而不是错误案例中的字符串,但OP不是这样要求的here@Lamar更新了游乐场样本以反映我刚才指出的你的建议,既然关联的枚举看起来类似于
结果
,我想为什么不直接命名它并遵循它的名称呢requirement@Lamar同时更新答案中的代码。我试着让它尽可能的简单