在Swift中使用类的方法作为默认参数

时间:2019-05-15 08:49:27

标签: swift

我想创建一个带有一些参数和一个函数的类方法。我希望该函数参数具有默认值。所以我在做:

class Calculator {

    func operate(n1: Int, n2: Int, _ f: ((Int, Int) -> Int)? = add) -> Int {
        return (f ?? add)(n1, n2)
    }

    func add(n1: Int, n2: Int) -> Int {
        return n1 + n2
    }
}

在这里,f是可以传递的函数参数(或不能传递,因为它是可选的)。我希望添加为f的默认值,所以如果您这样做:

Calculator().operate(n1: 10, n2: 20)
// not passing f causes add to be called

问题:此问题无法编译,它告诉我f的正确类型应为:(Calculator) -> (Int, Int) -> Int。也就是说:add是Calculator类的一种方法,很有意义。

但是有没有办法将该方法表示为函数?

我可以定义一个外部函数,例如:

func externalAdd(n1: Int, n2: Int) -> Int {
    return n1 + n2
}

然后一切正常,只要更改f的默认值即可:

class Calculator {

    func operate(n1: Int, n2: Int, _ f: ((Int, Int) -> Int)? = externalAdd) -> Int {
        return (f ?? add)(n1, n2)
    }

    func add(n1: Int, n2: Int) -> Int {
        return n1 + n2
    }
}

想法?这可能吗?

2 个答案:

答案 0 :(得分:2)

func operate(n1: Int, n2: Int, _ f: ((Int, Int) -> Int)? = add) -> Int 

add被评估为类型为

Calculator.add
 (Calculator) -> (Int, Int) -> Int

Instance Methods are “Curried” Functions in Swift中所述。

一种选择是使用nil作为默认值(因为以后无论如何都要进行可选的链接):

class Calculator {

    func operate(n1: Int, n2: Int, _ f: ((Int, Int) -> Int)? = nil) -> Int {
        return (f ?? add)(n1, n2)
    }

    func add(n1: Int, n2: Int) -> Int {
        return n1 + n2
    }
}

另一种选择是使默认函数成为static方法,并且函数参数为非可选:

class Calculator {

    func operate(n1: Int, n2: Int, _ f: ((Int, Int) -> Int) = add) -> Int {
        return f(n1, n2)
    }

    static func add(n1: Int, n2: Int) -> Int {
        return n1 + n2
    }
}

答案 1 :(得分:0)

如果您尝试这样做:

class Calculator {
  var addFunction: ((Int, Int) -> Int) {
    return add
  }

  func operate(n1: Int, n2: Int, _ f: ((Int, Int) -> Int)? = addFunction) -> Int {
    func add(n1: Int, n2: Int) -> Int {
      return n1 + n2
    }

    return (f ?? add)(n1, n2)
  }

  func add(n1: Int, n2: Int) -> Int {
    return n1 + n2
  }
}

编译器错误将为“无法使用实例成员'addFunction'作为默认参数”。

原因是,您不能迅速在函数声明中使用实例变量。

希望有帮助