[Swift] 클로저(Closure)

민니·2022년 7월 1일
0

Swift 문법

목록 보기
6/17

클로저 ❓

  • 일회용 함수를 작성할 수 있는 구문
  • 익명 함수라고도 부름
    일회용 함수는 한 번만 사용하면 되므로 굳이 함수의 이름을 작성할 필요가 없다

클로저 표현식

  • func 키워드, 이름 생략
{ (매개변수) -> 변환타입 in
	//실행할 구문
}



클로저 표현식과 경량 문법

  • 클로저 표현식은 주로 인자값으로 사용되는 객체인만큼, 간결성을 극대화하기 위해 필요에 따라 여러 부분을 생략함

예시를 이용하여 알아봅시다

📚 배열 하나를 작성해 보겠음

var value = [1,9,5,7,3,2]

이 배열을 정렬 함수 sort(by:)를 이용하여 정렬해 보자.
정렬 기준을 위해 함수를 정의하여 인자값으로 넣어주어야 한다.


📚 함수를 작성하여 sort(by:) 메서드의 인자로 넣기

func order(s1: Int, s2: Int) -> Bool {
	if s1 > s2 { //s1이 s2보다 클 경우 true 리턴
    	return true
    } else { 
    	return false
    }
}
value.sort(by: order) // 9 7 5 3 2 1

📚 order을 클로저 형식으로 표현해 보기

{
	(s1: Int, s2: Int) -> Bool in 
    	if s1 > s2 {
        	return true
        } else {
        	return false
        }
}

📚 order의 클로저 표현식을 sort 메서드의 인자값으로 사용해 보기

value.sort(by: {
    (s1: Int, s2: Int) -> Bool in
        if s1 > s2 {
            return true
        } else {
            return false
        }
})

📚 클로저 표현식을 좀 더 간단하게 만들어 보기

{ (s1: Int, s2: Int) -> Bool in  return s1>s2 }

value.sort(by: { (s1: Int, s2: Int) -> Bool in
    return s1>s2
})

❗️클로저 표현식은 반환값 타입을 생략할 수 있음 -> 컴파일러가 클로저 표현식의 구문을 해석하여, 반환타입을 추론한다

{ (s1: Int, s2: Int) in return s1>s2}

value.sort(by: { (s1: Int, s2: Int) in
    return s1>s2
})

❗️매개변수의 타입 정의를 생략할 수 있음 -> 마찬가지로 컴파일러가 추론 가능

{ s1, s2 in return s1>s2 }

value.sort(by: { s1, s2 in
    return s1>s2
})

❗️매개변수도 생략이 가능하고, in 키워드 역시 생략 가능 -> 매개변수명 대신 $0, $1... 와 같은 이름으로 할당된 내부 상수를 이용. 입력받은 인자값의 순서대로 매칭됨

{ return $0>$1 }

value.sort(by: {
    return $0>$1
})

❗️ 클로저가 반환하는 값이 있다면, return 키워드도 생략 가능 -> 클로저의 마지막 줄의 결과값은 암시적으로 반환값으로 취급

{ $0>$1 }

value.sort(by: {
    $0>$1
})



트레일링 클로저

  • trailing: 후행
  • 함수의 마지막 인자값이 클로저일 때, 이를 인자값 형식으로 작성하는 대신 함수의 뒤에 꼬리처럼 붙일 수 있는 문법
  • 함수의 마지막 인자값에만 적용!!!!!!!!!!
  • 인자 레이블은 생략

📚 인자값으로 사용되던 클로저를 통째로 밖으로 꺼낸 뒤, sort() 메서드 뒤쪽에 붙임

value.sort() { (s1, s2) in 
	return s1 > s2
}

📚 인자값이 하나일 경우, sort 뒤의 괄호 생략 가능 -> 더 필요한 인자값도 없고, 호출 구문임이 명확하므로 괄호를 쓰지 않아도 됨!

value.sort { (s1, s2) in
	return s1 > s2
}

- 인자값들이 모두 클로저여도, 트레일링 클로저 문법은 마지막 인자값에만 적용




@Escaping

  • Swift에서 함수의 인자값으로 전달된 클로저는 기본적으로 탈출 불가(non-escape)
  • 탈출 불가로 관리함으로써 컴파일러가 메모리 관리상 지저분한 일들에 관여할 필요가 없음 -> 성능 향상
  • 이는 해당 클로저는 함수 내에서 혹은 직접 실행을 위해서만 사용 가능하다는 것을 의미
  • 변수나 상수에 대입할 수 없다 (함수 내부여도)
  • @escaping 속성을 클로저에 붙여주면, 해당 클로저는 탈출 가능하다
  • @escaping 속성은 함수 타입 정의 앞에 넣어줌



@autoclosure

  • 인자값으로 전달된 일반 구문이나 함수 등을 클로저로 wrapping
  • 일반 구문을 인자값으로 넣으면, 컴파일러가 알아서 클로저로 사용함
  • 인자값이 {} 형태가 아니라, () 형태로 사용 가능
  • 따라서 코드를 이해하기 쉬운 형태로 만들어 준다
  • @autoclousre 속성도 함수 타입 정의 앞에 넣어줌






아직 @escaping과 @autoclosure 속성을 사용해 보지 못해서 감이 잘 안 잡히는 중...
키워드를 사용하게 된다면 따로 포스팅해 보겠습니당.

출처)
꼼꼼한 재은씨의 Swift: 문법편

0개의 댓글