如何使用参数作为参数传递闭包并执行它?

时间:2016-07-12 20:58:06

标签: swift function closures

A的初始化程序将可选闭包作为参数:

class A {
   var closure: ()?

   init(closure: closure()?) {
      self.closure = closure
      self.closure()
   }
}

我想传递一个带参数的函数作为闭包:

class B {
    let a = A(closure: action(1)) // This throws the error: Cannot convert value of type '()' to expected argument type '(() -> Void)?'

    func action(_ i: Int) {
       //...
    }
}

A应该使用参数action执行闭包i

我不确定如何正确编写,请参阅上面的代码注释中的错误。有什么需要改变?

4 个答案:

答案 0 :(得分:6)

问题是closure()?不是类型()?是一种类型,但它可能不是您想要的类型。

如果您希望var closure具有某种功能的值,则需要在声明中使用该功能的类型,例如

var closure: (Int) -> Void

同样,如果您希望init(closure:)将某个函数作为其参数,则需要在声明中使用该函数的类型,例如

init(closure: (Int) -> Void) {

答案 1 :(得分:5)

请将您的“现在有什么”代码免费提供。

假设您的班级/* ID: harry47341 PROG: crypt1 LANG: C++ */ #include<iostream> #include<fstream> #include<vector> #include<algorithm> using namespace std; vector<int> digits; int a, b, c, d, e, abc, de; bool oneof1(int n) { int count1 = 1; while (true) { if (count1 > n)break; else { count1 = count1 * 10; int digit = n%count1 / (count1 / 10); if (!count(digits.begin(), digits.end(), digit) ){ return false; } n = n - n%count1; } } } bool check() { int n = abc*e; int n1 = abc*d; if (n > 999 || n < 100)return false; if (n1 > 999 || n1 < 100)return false; if ((n1 * 10 + n) > 9999 || (n1 * 10 + n) < 1000)return false; if (oneof1(n) && oneof1(n1) && oneof1(n1 * 10 + n)) { return true; } } int main() { ofstream fout("crypt1.out"); ifstream fin("crypt1.in"); int count = 0; int n; fin >> n; for (int i = 0; i < n; i++) { int f; fin >> f; digits.push_back(f); } for (int i = 0; i < n; i++) { a = digits[i]; for (int i1 = 0; i1 < n; i1++) { b = digits[i1]; for (int i2 = 0; i2 < n; i2++) { c = digits[i2]; for (int i3 = 0; i3 < n; i3++) { d = digits[i3]; for (int i4 = 0; i4 < n; i4++) { e = digits[i4]; abc = a * 100 + b * 10 + c; de = d * 10 + e; if (check()) { count++; } } } } } } fout << count << endl; return 0; } 是这样的:

A

如上所述class A { typealias ClosureType = ()->Void var closure: ClosureType? init(closure: ClosureType?) { self.closure = closure //`closure` would be used later. } //To use the closure in class A func someMethod() { //call the closure self.closure?() } } ,您需要将您的班级A重写为:

B

答案 2 :(得分:2)

我认为您尝试的方法之一是使用以下代码:

class ViewController: UIViewController {

    override func viewDidLoad() {
        let _  = A.init(){Void in self.action(2)}
    }

    func action(i: Int) {
        print(i)
    }
}


class A: NSObject {
    var closure : ()?

    init(closure: (()->Void)? = nil) {
        // Notice how this is executed before the  closure
        print("1")
        // Make sure closure isn't nil
        self.closure = closure?()
    }
}

答案 3 :(得分:2)

类型作为参数

在Swift中,每个对象都有一个类型。例如,IntString等可能是您非常熟悉的所有类型。

因此,当您声明一个函数时,应指定任何参数的显式类型(或有时是协议)。

func swallowInt(number: Int) {}

复合类型

斯威夫特也有复合类型的概念。其中一个例子是Tuples。元组只是其他类型的集合。

let httpStatusCode: (Int, String) = (404, "Not Found")

函数可以很容易地将元组作为其参数:

func swallowStatusCode(statusCode: (Int, String)) {}

另一种复合类型是函数类型。函数类型由参数元组和返回类型组成。因此,上面的swallowInt函数将具有以下函数类型:(Int) -> Void。同样,接受IntString并返回Bool的函数将具有以下类型:(Int, String) -> Bool

作为参数的函数类型

因此我们可以使用这些概念重写函数A:

class A {
    var closure: (() -> Void)?

    init(closure: (() -> Void)?) {
        self.closure = closure
        self.closure()
    }
}

传递一个参数就是:

func foo(closure: (Int) -> Void) {
    // Execute the closure
    closure(1)
}