고차함수의 클로저가 헷갈려요...? (feat. reduce)

김하민·2024년 12월 4일
1

[Swift] 문법 배우기

목록 보기
3/3
post-thumbnail

아 맞다.

생각해보니, 저번 포스팅에서 제목에 reduce를 넣어놓고는 내용에선 까먹고 적지 않은 것이 있더라고요?

그래서 이어서 적어보려 합니다.

후행 클로저와도 어느정도 연관이 있는 이야기다 보니, 어찌보면 잘 된 일이겠죠.

저번 포스팅에서 썼던 reduce 예제를 다시 가져와보겠습니다.

reduce를 쓰다보면, 트레일링 클로저를 사용해 어떻게 reduce를 할지 전달해 주곤 합니다.

트레일링 클로저가 뭔지 모른다고요? 클릭하십시오 휴먼.
또는 클로저가 뭔지, 또는 클로저 축약문법이 익숙하지 않다고요? 클릭하십시오 휴먼.

클로저 또 너냐

위의 글을 읽었거나, 클로저에 대한 어느정도의 이해가 있다면 말이죠,

let 머리부터발끝까지: [String] = ["머리", "부터", "발끝", "까지"]

let 오로나민씨 = 머리부터발끝까지.reduce("") { $0 + $1 }

print(오로나민씨 + "오로나민씨") // 머리부터발끝까지오로나민씨

여기서 $0, $1이 왜 쓰이는지 아실 겁니다.

근데 이건 어떨까요?

let 머리부터발끝까지: [String] = ["머리", "부터", "발끝", "까지"]

let 사랑스러워 = 머리부터발끝까지.reduce("", +)

print(사랑스러워 + "다사랑스러워") // 머리부터발끝까지다사랑스러워

이게 왜 되지? 싶지 않으신가요?

let 오로나민씨 = 머리부터발끝까지.reduce("") { $0 + $1 }
let 사랑스러워 = 머리부터발끝까지.reduce("", +)

아니, 트레일링 클로저까지만 알면 끝난 거 아니었어? 하실 수 있습니다.

하지만 이번엔 비교적 짧으니 좀만 견뎌보시죠.

Q. 저게 왜 되냐?

A: 고차함수는 클로저를 받으니까요!

예제로 쓰인 고차함수 reduce의 정의를 볼까요?

위의 정의에서 클로저를 받는 아래 코드를 봅시다.

nextPartialResult: (Result, Self.Element) throws -> Result

이해를 돕기 위해 헷갈릴 수 있는 제네릭과 에러 처리 구문 throws를 없애보겠습니다.

nextPartialResult: (String, String) -> String

즉, nextPartialResult는 String 2개를 받아 String을 반환하는 클로저(익명함수)를 받는 함수의 전달인자인 것입니다.

근데 클로저 첫 번째 시리즈를 보셨으면 아시겠지만, 보통 우리가 클로저라고 부르는 것은 익명 함수입니다.

네. 다시 말하지만 클로저는 함수입니다.

근데 우리가 자각하지 못 하는 다른 함수 친구가 또 있다면 믿으시겠습니까?

바로 연산자들입니다.

일반 함수들과는 다르게 prefix/postfix/infix operator라고 선언해줘야 연산자 앞/뒤의 값을 가져올 수 있어서 쵸큼 다르긴 한데...

함수라는건 똑같으니 일단 계속 진행하겠습니다.

연산자가 함수이니,
함수를 전달인자로 받는 고차함수에서 사용이 가능한 것입니다.

let 오로나민씨 = 머리부터발끝까지.reduce("") { $0 + $1 }
let 사랑스러워 = 머리부터발끝까지.reduce("", +)

그래서 이런 짓도 가능합니다

import Foundation

let 머리부터발끝까지: [String] = ["머리", "부터", "발끝", "까지"]

// 클로저로 작성하여 전달.
let 힘차게 = { $0 + $1 + "!" }

// 중위 연산자 ~ 선언 후,
infix operator ~

// 함수로 작성하여 전달.
func ~ (lhs: String, rhs: String) -> String {
    return lhs + rhs + "~"
}

let 사랑스러워 = 머리부터발끝까지.reduce("", +)
let 힘차게머리부터발끝까지 = 머리부터발끝까지.reduce("", 힘차게)
let 늘어지게머리부터발끝까지 = 머리부터발끝까지.reduce("", ~)

print(사랑스러워 + "다사랑스러워") // 머리부터발끝까지다사랑스러워
print(힘차게머리부터발끝까지 + "다입수") // 머리!부터!발끝!까지!다입수
print(늘어지게머리부터발끝까지 + "오로나민씨") // 머리~부터~발끝~까지~오로나민씨

참 신기하지 않나요?

오늘은 여기까지입니다.

나가세요 이제.







0개의 댓글