Добрый день, ребята поделитесь своим опытом, кто как изучал Closure? Что нужно сделать, чтобы получить ясное понимания алгоритма работы и использования Closure.
Closure - осознать, понять и полюбить
Не страшно: все сначала не понимают и просто копи-пастят. Со временем и практикой всё придёт. Здесь в курсах где-то Иван довольно понятно объяснял.
Все спасибо за ответы.
Я сам себе говорю что нужно время для понимания, но когда читаешь документацию по Closure начинается боль
Видео смотрел, некоторые моменты понятные некоторые нет. Пока очень сырое понимание, особенно трудно читать код.
Пример
func makeIncrementer() -> (Int) -> Int {
func addOne(number: Int) -> Int {
return 1 + number
}
return addOne
}
var increment = makeIncrementer()
increment(7)
Как правильно читать этот код?
Так
Функция makeIncrementer котороя не чего напринимает, но возвращает функцию которая принимает Int и возвращает Int.
Правильно ли я прочитал код?
Спасибо за ответ.
Может поможете прочитать это:
var addClosure: (Int, Int) -> Int = { $0 + $1 } func returnClosure() -> (Int, Int) -> Int { return addClosure } returnClosure returnClosure()(10, 20)
addClosure - это переменная с типом (Int, Int) -> Int
которая принимает Closure?
returnClosure - это функция которая не чего не принимает, но возвращает Closure который который принимает переменную, которая принимает функцию?
Я немного запутался…
Как я понимаю, closure это блок кода, который передается в качестве параметра в другую функцию, а не в качестве возвращаемого значения.
Функция calculatorFunc, принимает в качестве параметров 2 переменные типа Int, а также функцию для вычисления значений этих переменных.
Пример 1:
func sumFunc(a: Int, b: Int) -> Int { return a + b }
func subtractFunc(a: Int, b: Int) -> Int { return a - b }
func multiplyFunc(a: Int, b: Int) -> Int { return a * b }
func divideFunc(a: Int, b: Int) -> Int { return a / b }
func calculatorFunc(a: Int, b: Int, funcToCalculate: (Int, Int) -> Int) -> Int { return funcToCalculate(a, b) }
let sumResult = calculatorFunc(a: 1, b: 2, funcToCalculate: sumFunc)
let subtractResult = calculatorFunc(a: 1, b: 2, funcToCalculate: subtractFunc)
let divideResult = calculatorFunc(a: 10, b: 5, funcToCalculate: divideFunc)
let multiplyResult = calculatorFunc(a: 5, b: 5, funcToCalculate: multiplyFunc)
Важно обратить внимание на следующее:
Если написать calculatorFunc(a: 1, b: 2, funcToCalculate: sumFunc ()), то в парметр funcToCalculate: будет передана не ссылка на блок кода с именем sumFunc, а значение, возвращаемое этой функцией, что вызовет ошибку компиляции.
В примере 1 для вычисления значений были объявлены 4 функции, если в будущем понадобятся дополнительные операции вычисления, то придется создавать еще функции и еще и еще.
Пример 2. С замыканием:
func calculatorFuncVersion2(a: Int, b: Int, closure: (Int, Int) -> Int ) -> Int { return closure(a, b) }
let sumResultVer2 = calculatorFuncVersion2(a: 4, b: 5, closure: { (a, b) -> Int in return a + b })
let substractResultVer2 = calculatorFuncVersion2(a: 10, b: 3, closure: { (a, b) -> Int in return a - b })
let divideResultVer2 = calculatorFuncVersion2(a: 20, b: 10, closure: { (a, b) -> Int in return a / b})
let multiplyResultVer2 = calculatorFuncVersion2(a: 5, b: 5) { (a, b) -> Int in return a * b }
В примере 2, в качестве параметра closure: передается не ссылка на ранее объявленную функцию, передается сам блок кода, и в дальнейшем, если понадобиться добавить новые операции вычисления, достаточно написать эти вычисления в блоке кода замыкания без необходимости создавать для этого новые функции.
Спасибо за разъяснения, крутой пример. Я с ним поработал немного и у меняя получилось еще сократить код.
Пример:
let multiplyResultVer2 = calculatorFuncVersion2(a: 5, b: 5) { $0 * $1 }
сокращение кода хорошо, когда это уместно)
В моем примере важно понять сам смысл замыканий)
Несовсем. Это безымянная функция. Например, вычисляемая переменная - это тоже клоужер.
При этом клоужер может передаваться в другую функцию, как вы указали. Тогда клоужер выполняется после завершения функции в которую он передан.
Согласен. Получается функция может вернуть функцию и/или может вернуть блок кода в виде замыкания.
Верно. В первом случае это просто возвращаемое значение. А если на вход подать безымянную функцию, то это и есть клоужер, который выполниться после основной функции.
Вот тут я не совсем понял. Покажите пожалуйста на примере что значит подать замыкание на вход.
func someFunc(closure: () -> ()) {
//some main actions
closure()
}
someFunc() {
//some actions after main actions
}