안녕하세요! 후르륵짭짭 입니다!
최근 회사의 Swift 고급 강의를 들어서 큰 도움을 받아, 공부할 겸 하나씩 정리해보려고 합니당!
이번에는 첫 강의 복습 글이기 때문에 쉬운 내용으로 작성하려 합니다. (글쓰기가 힘들기도 해요 ㅎㅎㅎ)
그리고 앞으로 제가 좋아하는 뮤직비디오랑 내용 정리 글을 올린 후에 간단한 잡 생각을 작성하려고 합니다.
나중에 제가 이 글을 봤을 때, 그냥 일기 느낌으로 보려고요 ㅎㅎㅎ.
www.youtube.com/watch?v=cHkDZ1ekB9U
< 노래도 좋고 뮤비도 재미있고 두 배우가 너무 잘 어울립니다.>
** Generic - Closure의 확장 **
Closure는 함수이지만 다양한 형태로 정의를 쉽게 해줄 수 있는 함수 입니다.
2020.12.08 - [Xcode/Swift - PlayGround] - PlayGround ) Closure의 기능은 무엇인가?
예전에 저 글에서 클로저는 기능의 정의를 한 후에 사용하는 것이라고 말씀드렸습니다.
Generic와 Closure의 기본적인 내용을 알고 있다면 이번에 정리하는 내용은 쉽게 이해 할 수 있을 겁니다.
** 이 내용이 필요한 이유 **
protocol Validator { associatedtype Value func validate(_ value : Value) -> Bool } struct MiniSumValidate : Validator { let miniCount : Int func validate(_ values: [Int]) -> Bool { return values.reduce(0, +) < miniCount } } struct MaxSumValidate : Validator { let maxCount : Int func validate(_ values: [Int]) -> Bool { return values.reduce(0, +) > maxCount } }
만약 Int 배열에 들어가 있는 값이 최소값 보다 작은지, 최대값 보다 큰지 판단해주는 인스턴스를 생성한다면
위에 처럼 같은 구조를 만들기 위해 Protocol을 만들어 주고 MiniSumValidate와 MaxSumValidate를 만들어줬습니다.
그리고 사용 할 때는 아래 처럼 생성해서 사용 해주면 됩니다.
let list : [Int] = [10,30,12,43,54,12] let validator = MiniSumValidate(miniCount: 20) print("MiniSumValidate 의 결과는 : ",validator.validate(list)) let list2 : [Int] = [12,13,14,15,20,14] let validator2 = MaxSumValidate(maxCount: 30) print("MaxSumValidate 의 결과는 : ", validator2.validate(list2))
이렇게 Protocol을 사용해서 비슷한 형태의 인스턴스를 생성 할 수 있습니다.
그리고 Protocol을 준수하기 때문에 원하는 구조를 찍어낼 수 있습니다.
하지만 이러면 비슷한 구조의 인스턴스를 매번 생성해줘야하기 때문에 비효율적 입니다.
이런 문제를 해결하기 위해 제너릭과 클로저를 함께 사용했습니다.
** 클로저와 제너릭의 활용 **
struct Validator<T>{ let validate : (T) -> Bool init(validate : @escaping (T) -> Bool){ self.validate = validate } }
이렇게 제너릭을 사용해서 어떤 타입이 들어와도 사용할 수 있도록 해줍니다.
init()을 통해 T 타입을 받아서 Bool을 반환해주는 함수를 정의 한 다음 self.validate에 넣어줍니다.
let minSumValidator = Validator(validate: { (lists : [Int]) -> Bool in return lists.reduce(0, +) < 20 }) let maxSumValidator = Validator(validate: { (lists : [Int]) -> Bool in return lists.reduce(0, +) > 30 })
이렇게 해주면 클로저를 통해서 매번 self.validate를 다르게 만들어 줄 수 있습니다.
Validate 인스턴스는 그대로 사용 했는데, 내부의 클로저를 새롭게 정의 해줌을 통해 좀 더 간단한게
비슷하지만 다른 인스턴스를 만들 수 있게 됩니다.
let list : [Int] = [10,30,12,43,54,12] let minSumValidator = Validator(validate: { (lists : [Int]) -> Bool in return lists.reduce(0, +) < 20 }) //클로저를 이용하면 언떤 것이 인자로 들어가는지 안 알려주기 때문에 직접 알아서 넣어줘야한다. //만약 인자가 있는데 안 넣었을 경우 Function이라고 나온다. print(minSumValidator.validate(list)) let maxSumValidator = Validator(validate: { (lists : [Int]) -> Bool in return lists.reduce(0, +) > 30 }) print(maxSumValidator.validate(list))
위에 처럼 사용해주면 되는데, 클로저 같은 경우는 어떤 인자가 들어가는지 자동으로 안 알려주기 때문에, 직접 넣어줘야합니다.
인자를 빼고 넣어주면 그냥 Function 이라는 값이 나오게 됩니다.
** 클로저를 반환! **
extension Validator{ func combine(_ other : Validator<T>) -> Validator<T> { let newValidate = Validator(validate: { (input) -> Bool in print("input : \(input)") //init에서 validate를 생성 해줄 때 이미 T가 정해진다. //따라서 input : [Int] 가 되지 않는다. let result = validate(input) let result2 = other.validate(input) return result && result2 }) return newValidate } }
위의 내용을 이해 했다면 위의 코드도 충분히 이해가 될 겁니다.
새로운 클로저를 반환해주는 겁니다.
기존의 인스턴스에 존재하던 self.validate와 새로운 인자로 들어온 validate를 합쳐서
새로운 Validate 인스턴스를 반환해주는 겁니다.
(참고로 input : [Int]가 안되는 이유는 이미 init()에서 T에 대한 정의를 내려줬기 때문에 input의 타입도 정해지게 됩니다.)
let combinValidate = minSumValidator.combine(maxSumValidator) //이미 minSumValidator를 생성할 때 [Int]로 만들어 줬기 때문에 //Cannot convert value of type 'String' to expected element type 'Array<Int>.ArrayLiteralElement' (aka 'Int') //따라서 이렇게 오류가 발생한다. //combinValidate.validate(["!"]) print(combinValidate.validate([12,3,4,5,3,2,12]))
그리고 이렇게 사용이 가능합니다.
이렇게 사용하면 기존의 내용들을 합쳐서 새로운 기능을 가진 함수를 만들 수 있기 때문에, 사용성 측면에서도 효율적 일 것 같습니다.
** 20.04.11 - 잡 생각 **
진지함을 잘 몰라서 가끔 의도하지 않는 상처를 줄 때가 있습니다.
그런데 누구는 항상 남이 상처 받지 않게 말을 이쁘게 하더군요.
그래서 그 모습을 보면서 배우고 저도 달라지려고 합니다.
감사합니다.
'Xcode > Swift - PlayGround' 카테고리의 다른 글
(Swift) Closure - Capturing Value (0) | 2021.09.03 |
---|---|
PlayGround) 런타임 프로토콜 AND 컴파일 프로토콜 (클로저 잠깐,,) (1) | 2021.04.25 |
PlayGround) 제너릭에 대해 알아보자 (0) | 2021.03.27 |
PlayGround) Protocol에 대해서 좀 더 깊게 알아가기 (0) | 2021.02.14 |
PlayGround) Method Chaining와 Optional Chaining이란! (0) | 2021.02.13 |
댓글