728x90
반응형

클로저를 다양하게 사용하는 방법에 대해서 공부했다.
후행클로저, 반환타입 생략, 단축 인자 이름, 암시적 반환 표현 의 다양한 모습으로 클로저를 표현할 수 있다.

일반적으로 클로저는 다음과 같이 사용할 수 있다.

// 클로저 기본 표현
func calcluate(a: Int, b: Int, method: (Int, Int) -> Int) -> Int {
    return method(a, b)
}

지난 번에 클로저 기본에 대해서 공부할 때 함수의 인자로 받아 사용했던 기억이 있다.
이번에는 클로저의 기본 문법에서 다양한 모습으로 바꿔서 사용해보려고 한다.

후행 클로저

함수의 매개변수 마지막으로 전달되는 클로저는 후행 클로저(trailing closure)로 함수 밖에 구현할 수 있다.
클로저가 함수의 마지막 전달인자일 때, 마지막 매개변수 이름을 생략한 후 함수 소괄호 외부에 클로저는 구현한다.
만약 클로저 내부에 여러 줄의 실행 코드가 있다면 후행클로저를 사용해 가독성을 높이는 것이 좋다고 한다.
마지막 전달 인자로 전달되는 클로저에만 해당된다 것을 기억하자.
후행 클로저는 위의 기본 표현을 다음과 같이 바꿔서 사용해볼 수 있었다.

var result: Int

// 후행 클로저 사용
result = calcluate(a: 10, b: 10) { (left: Int, right: Int) -> Int in
    return left + right
}

print(result)

========== 출력 결과 ==========
20

기본 표현에서는 함수 내부에서 클로저를 구현해 사용했다면
지금은 클로저를 함수 밖으로 빼서 마지막 전달인자로 사용했다.

반환타입 생략

반환타입을 생략해서 사용할 수도 있다.
기본 표현에서 만들었던 함수인 calculate 라는 함수의 method 라는 매개변수는 Int 라는 두 개의 인자를 받아 Int 타입으로 반환한다.
method 라는 변수에서 Int 타입을 반환할 것이라는 것을 컴파일러가 알기 때문에
클로저에서 반환 타입을 명시해주지 않아도 된다고 한다. 다만, "in" 키워드는 있어야 한다.
그래서 후행 클로저를 사용한 문법에서 다음과 같이 반환타입을 생략한 후에 출력해보았다.

var result: Int

// 반환타입 생략
// Int 타입을 반환할 것을 알기 때문에 생략해도된다. in은 생략하면 안된다.
result = calcluate(a: 10, b: 10) { (left: Int, right: Int) in
    return left + right
}

print(result)

========== 출력 결과 ==========
20

후행 클로저를 사용할 때와 비교해보면 "-> Int" 라는 결과를 Int 타입으로 반환해주는 부분이 사라진 것을 확인할 수 있다.
결과는 마찬가지로 같은 값이 나온다.

단축 인자 이름

또한 인자의 이름을 단축해서 사용할 수도 있다고 한다.
클로저의 매개변수 이름이 굳이 필요하지 않다면 단축된 인자 이름으로 대신할 수 있다.
단축 인자 이름은 변수의 입력 순서대로 $0, $1, $2, ... 와 같이 표현을 통해 사용할 수 있다.
쉘 스크립트에서 스크립트의 입력 인자를 스크립트 내부에서 사용할 때와 비슷한 것 같다.
그래서 다음과 같이 단축 인자이름으로 바꿔보았다.

// 단축 인자 이름
result = calcluate(a: 10, b: 10, method: {
    return $0 + $1
})

print(result)

// 후행클로저와 함께 사용할 수 있다.
result = calcluate(a: 10, b: 10) {
    return $0 + $1
}

print(result)

========== 출력 결과 ==========
20
20

left, right 라는 인자를 없애고 $0 과 $1 이라는 인자이름을 통해 인자를 받아 결과를 출력한 것을 확인할 수 있었다.

암시적 반환 표현

마지막으로 return 이라는 반환 표현을 사용하지 않아도
클로저의 마지막 줄의 결과값은 암시적으로 반환 값으로 취급한다고 한다.
그래서 더 축약해서 사용할 수 있었다.

// 암시작 반환 표현
result = calcluate(a: 10, b: 10) {
    $0 + $1
}

print(result)

result = calcluate(a: 10, b: 10) { $0 + $1 }

print(result)

========== 출력 결과 ==========
20
20

return 이라는 반환 표현이 사라졌지만 마지막 줄을 반환 값으로 취급했기 때문에
다르지 않은 결과를 출력할 수 있었다.

누가봐도 간단해진 것이 보일 만큼 다양한 표현으로 정말 코드가 너무 간결해졌다.

// 클로저 기본 표현
func calcluate(a: Int, b: Int, method: (Int, Int) -> Int) -> Int {
    return method(a, b)
}

// 후행클로저 + 반환타입 생략 + 단축 인자이름 + 암시적 반환 표현
result = calcluate(a: 10, b: 10) { $0 + $1 }

정말 같은 코드인게 신기할 정도로 간단해졌다.
위의 기본 표현을 보지 않고 처음 보는 소스라면 당장 이해하기는 힘들 것 같다.

그래서 너무 축약된 코드는 다른 사람이 보거나, 시간이 지난 후 다시 보게 된다면
알아보기 힘들기 때문에 적절히 축약해서 사용해야 한다고 한다.
무작정 코드를 축약한다고 해서 좋은 것이 아니라 명확하게 알 수 있는 코드가 좋은 것처럼 적절히 사용해야 한다.
다른 블로그에서 정리된 글을 보면서 이해가 더 필요할 것 같다.

 

- 참고 사이트 - 

www.edwith.org/boostcamp_ios/lecture/11297/

 

[LECTURE] 18. 클로저 고급 (💎생각해보기) : edwith

생각해보기 ▶라이브러리 혹은 다른 사람의 스위프트 코드를 보면서 클로저의 축약표현 때문에 당황했던 적은 없나요? 어려웠거나 당황했던 경험을 나눠봅시다~! +)토론게시글 작성 시, ... - 부

www.edwith.org

medium.com/@jgj455/오늘의-swift-상식-closure-aa401f76b7ce

 

오늘의 Swift 상식 (Closure)

클로저(Closure)란?

medium.com

 

728x90
반응형
복사했습니다!