본 내용은 '스위프트 프로그래밍' 책을 학습한 후 이를 바탕으로 작성한 글입니다.
context
context
는 컨텐츠를 담은 상자 같은 것이다.func addThree(_ num: Int) -> Int {
return num + 3
}
//매개변수로 일반 Int 타입의 값을 받기 때문에 정상적으로 실행
addThree(2)
//전달인자가 순수한 값이 아닌 옵셔널이라는 컨텍스트로 둘러싸여 전달되었기 때문에 오류 발생
addThree(Optional(2))
functor
functor
란 맵map
을 적용할 수 있는 컨테이너 타입이다.Array
, Dictionary
, Set
등등 스위프트의 많은 컬렉션 타입이 함수객체이다.flatMap
과 컴팩트맵 compactMap
flatMap
이라는 메서드를 활용한다.flatMap
은 맵 map
과 다르게 컨텍스트 내부의 컨텍스트를 모두 같은 위상으로 평평하게 펼쳐준다.func doubleEven(_ num: Int) -> Int? {
if num.isMultiple(of: 2) {
return num * 2
}
return nil
}
Optional(3).flatMap(doubleEven)
//nil
compactMap
은 스위프트 4.1 버전부터 flatMap
이 하던 역할 중 하나를 맡게 되었다.compactMap
의 사용법은 flatMap
과 같지만 좀 더 분명한 뜻을 나타내기 위해 compactMap
이라는 이름을 사용한다.let optionals: [Int?] = [1, 2, nil, 5]
let mapped: [Int?] = optionals.map{ $0 }
let compactMapped: [Int] = optionals.compactMap{ $0 }
print(mapped) //[Optional(1), Optional(2), nil, Optional(5)]
print(compactMapped) //[1, 2, 5]
flatMap
을 사용하지 않으면서 플랫맵 flatMap
과 같은 효과를 얻으려면 바인딩을 직접 해주면 된다.func stringToInteger(_ string: String) -> Int? {
return Int(string)
}
func integerToString(_ integer: Int) -> String? {
return "\(integer)"
}
var optionalString: String? = "2"
var result: Int?
if let string: String = optionalString {
if let number: Int = stringToInteger(string) {
if let finalString: String = integerToString(number) {
if let finalNumber: Int = stringToInteger(finalString) {
result = Optional(finalNumber)
}
}
}
}
print(result) //Optional(2)
flatMap
은 체이닝 중간에, 연산에 실패하는 경우나 값이 없어지는 경우에는 별도의 예외 처리없이 빈 컨테이너를 반환한다.func integerToNil(param: Int) -> String? {
return nil
}
optionalString = "2"
result = optionalString.flatMap(stringToInteger).flatMap(integerToNil).flatMap(stringToInteger)
print(result) //nil