Optionals, @autoclosure, rethrows, ??, compactMap

나이든별 / Oldstar·2022년 4월 24일
0

Think about Keywords

목록 보기
4/37

학습 내용

  • 여러 가지 옵셔널에 대해 리마인드했다.
  • 함수의 네이밍, 그리고 구조를 짤 때 주의할 점에 대해 익혔다. 하나의 동사로 표현할 수 있는 함수를 짜고, 나아가 유연한 코드를 짜야 한다는 것.
  • 프로젝트를 진행하던 중 사용한 고차함수에 대해 좀 더 알아보았다.

문제점 / 고민한 점

  • ?? 를 통한 기본값을 제공해 옵셔널을 푸는 방법을 애용해 왔지만, 그 안이 어떻게 이루어져 있는지 이번에 처음 고민해 보았다.
  • compactMap이 어떻게 옵셔널을 컨트롤하는지 고민해 보았다.

극복 방법

  • 공식 문서에 따르면 ?? 의 내부 구조는 이러하다:
func ?? <T>(optional: T?, defaultValue: @autoclosure () throws -> T) rethrows -> T
  • 이를 이해하기 위해 autoclosure와 rethrows에 대해서도 알아보았다.
  • 먼저, autoclosure는 파라미터 안에 들어온 것을 자동으로 클로저로 만들어준다는 뜻이다.
var friends = ["Oldstar", "Gordon"]

func sayHello(to friendProvider: () -> String) {
    print("Hello, \(friendProvider)!")
}

sayHello(to: { friends.pop() } ) // Hello, Gordon!

func sayHelloTo(friend friendProvider: @autoclosure () -> String) {
    print("Hello, \(friendProvider)!")
}

sayHelloTo(friend: friends.pop()) // Hello, Oldstar!
  • 또, rethrows는 함수의 파라미터가 오류를 throw할 때만 throw한다는 뜻이다.
  • throws라는 이름이 붙어 있는 것은 말하자면, '우리 개는 물어요' 라고 팻말을 달아 놓은 것처럼, 오류가 나올 가능성이 있는 것이라는 뜻.
  • 즉, ??는 왼쪽에는 옵셔널을 받고, 오른쪽에는 옵셔널 안에 있는 값과 같은 타입의 무언가를 받아서 기본값으로 삼는다. 제네릭 타입을 통해 이를 표시해두었다.
  • 단, 왜 기본값 파라미터마저도 throw하는가에 대해서는 명쾌한 답을 얻을 수 없었다.
  • 다음으로, compactMap은 다음과 같은 내부 구조를 가지고 있다.
func compactMap<ElementOfResult>(_ transform: (Self.Element) throws -> ElementOfResult?) rethrows -> [ElementOfResult]
  • 각각의 원소를 옵셔널로 취급하고, nil이 뜨면 값을 반환하지 않는다. nil이 아니라면 값을 반환해 새로운 시퀀스에 넣는다.
  • compactMap은 map과 비슷한 기능을 하지만, nil을 제거하는 데 특화되어 있다는 느낌을 받았다. Swift 4.1 이전까지는 flatMap을 사용했다면, 이후에는 상황에 따라 두 가지 함수를 나누어 쓰게끔 권장하고 있다.
  • 공부하다 보니 클로저가 참 중요한 역할을 하는구나.. 다시금 느낄 수 있었다.

참조

https://docs.swift.org/swift-book/LanguageGuide/Closures.html (@autoclosure)
https://docs.swift.org/swift-book/ReferenceManual/Declarations.html (rethrows)
https://developer.apple.com/documentation/swift/1539917 (??)
https://developer.apple.com/documentation/swift/sequence/2950916-compactmap (compactMap)

profile
함께 나아가고자 하는 사람

0개의 댓글