[야곰] Swift 개념정리 - Closures

Judy·2022년 3월 1일
0

Swift 공부

목록 보기
5/11

클로저

이전에 이미 Swift 공부용으로 클로저 정리를 했다.
지금 보니 참고자료를 거의 복붙해서 한눈에 안들어온다...

자료는 이해를 돕기위해 참고하는 것이니 이해된 개념을 나만의 언어로 다시 쓸 수 있도록 노력하자 👻



Closure


클로저는 쉽게 말해 코드블럭이다.

클로저는 전달인자, 변수, 상수로 저장과 전달이 가능하다.

함수도 클로저의 일종으로 이름이 정의된 클로저로 생각하면 된다.

함수 = 이름이 정의된 클로저


정의

{ (매개변수 목록) -> 반환타입 in
	실행 코드
}
  • 매개변수가 없으면 빈 괄호만
  • 반환타입이 없다면 Void

예시

// Int 두 개를 매개변수로 받아 Int를 반환하는 클로저 타입으로 선언한 변수
var sum: (Int, Int) -> Int = { (a: Int, b: Int) -> Int in
	return a + b
}

함수 역시 클로저의 일종으로 같은 형식을 가진 함수라면 sum(클로저 변수)에 할당 가능하다!

사용

클로저는 보통 함수의 전달인자로 잘 사용된다.

// 클로저를 전달인자로 받는 함수
func calculate(a: Int, b: Int, method: (Int, Int) -> Int) -> Int{
	return method(a, b)
}

var result = calculate(10, 20, sum)

클로저 표현

클로저는 다양한 방법을 통해 간단하게 표현할 수 있다.

1. 후행 클로저

함수의 마지막 매개변수가 클로저일 때 함수 밖에 클로저를 구현할 수 있다.

func calculate(a: Int, b: Int, method: (Int, Int) -> Int) -> Int{
	return method(a, b)
}


result = calculate(a: Int, b: Int){ (left: Int, right: Int) -> Int in 
	return left + right
}
  • 마지막 매개변수의 이름을 생략
  • 함수 소괄호 외부에 클로저를 구현

2. 반환타입 생략

컴파일러가 클로저의 타입을 유추할 수 있는 경우에는 반환타입을 생략할 수 있다.

result = calculate(a: Int, b: Int, method: { (left: Int, right: Int) in 
	return left + right
})

// 후행 클로저와 같이 사용
result = calculate(a: Int, b: Int){ (left: Int, right: Int) in 
	return left + right
}

이미 calculate 함수에서 매개변수인 클로저의 반환타입이 Int라고 명시되어 있기 때문에 컴파일러는 이 클로저의 반환타입을 유추할 수 있다.

  • 클로저의 반환타입 생략 가능 "-> 타입"
  • in 키워드는 생략할 수 없음
  • 후행 클로저와 같이 사용 가능

3. 단축 인자이름

전달인자 이름을 구분할 필요가 없고, 컴파일러가 타입을 유추할 수 있다면 축약된 전달인자 이름을 사용할 수 있다.
($0, $1, $2...)

result = calculate(a: Int, b: Int, method: {
	return $0 + $1
})

// 후행 클로저와 같이 사용
result = calculate(a: Int, b: Int){
	return $0 + $1
}
  • 전달인자 차례대로 $0, $1... 부여
  • 매개변수, 반환타입과 함께 in 키워드도 생략 가능
  • 후행 클로저와 같이 사용 가능

4. 암시적 반환 표현

반환 값이 존재하는 경우 return 키워드를 쓰지 않아도 암시적으로 클로저의 마지막 줄을 반환 값으로 취급한다.

result = calculate(a: Int, b: Int){
	$0 + $1
}
  • 후행 클로저와 같이 사용 가능
  • 짧게 한줄로 표현 가능

고차함수

전달인자 함수를 받거나 실행 결과 함수를 반환하는 함수

고차함수 역시 함수(클로저)이므로 함수의 전달인자로 전달할 수 있고, 함수의 결과로 반환할 수 있다.

스위프트에서 유용하게 사용되는 함수로 스위프트 표준 라이브러리에 구현되어 있다.

1. map

컨테이너 내부 데이터를 변경해서 새로운 컨테이너를 만든다.

let numbers: [Int] = [0, 1, 2, 3, 4]

new = numbers.map({ (number: Int) -> Int in 
	return number*2
}) 
// [0, 2, 4, 6, 8]

//후행 클로저, 반환타입 생략, 단축 인자이름, 암시적 반환 표현 적용
new = numbers.map{ $0*2 }

2. filter

컨테이너 내부 데이터 중 조건에 부합하는 데이터를 새로운 컨테이너로 추출한다.

let evenNumber: [Int] = numbers.filter({ (number: Int) -> Bool in
	return number % 2 == 0
}) 
// [0, 2, 4]

//후행 클로저, 반환타입 생략, 단축 인자이름, 암시적 반환 표현 적용
let oddNumber: [Int] = numbers.filter{ $0 % 2 != 0}

3. reduce

컨테이너 내부 데이터를 하나로 통합한다.

let sum: Int = numbers.reduce(0, { (first: Int, second: Int) -> Int in
	return first + second
}) // 10

//후행 클로저, 반환타입 생략, 단축 인자이름, 암시적 반환 표현 적용
let substract: Int = numbers.reduce(0){ $0 - $1 }

첫 번째 전달인수를 기준으로 (위에선 0) 값을 구한다.



[참고자료]

Swift: Closures

profile
iOS Developer

0개의 댓글