Использование метода класса в качестве параметра по умолчанию в Swift - PullRequest
2 голосов
/ 15 мая 2019

Я хочу создать метод класса, который принимает некоторые параметры и функцию.И я хочу, чтобы этот параметр функции имел значение по умолчанию.Итак, я делаю:

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, который имеет смысл.

Но есть ли способ выразить этот метод как функцию?

IМожно определить внешнюю функцию, например:

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 ]

2 голосов
/ 15 мая 2019

В

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

add оценивается как Calculator.add, который имеет тип

 (Calculator) -> (Int, Int) -> Int

как описано в Методы экземпляра являются «каррированными» функциями в 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
    }
}
0 голосов
/ 15 мая 2019

Если вы попробуете это:

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 »в качестве параметра по умолчанию».

Причина в том, что в swift вы не можетеиспользовать переменные экземпляра в объявлениях функций.

Надеюсь, это поможет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...