+) 프로토콜 타입제약은 Associated type을 써야 한다는데…. 프로토콜 공부하고 다시 배워갈게용
사실 정식 커리큘럼대로라면 아직 나오기엔 너무 이르지만, 서버통신을 부시기 위해서 저 T가 너무 걸리적거려서 먼저 제네릭 타입을 정리하려고 한다. 나중에 야우쓰 시즌 2 커리큘럼 만들때 어케 하는게 좋을까..? 고민을 해봐야겠당!
class BaseAPI{
public func judgeStatus<T: Codable>(by statusCode: Int, _ data: Data, _ object: T.Type) -> NetworkResult<Any> {
let decoder = JSONDecoder()
guard let decodedData = try? decoder.decode(GenericResponse<T>.self, from: data)
else {
return .pathErr
}
switch statusCode {
case 200..<205:
guard decodedData.data != nil else {
print("⛔️ \\(self)애서 디코딩 오류가 발생했습니다 ⛔️")
return .decodedErr
}
return .success(decodedData.data as Any)
case 400..<500:
return .requestErr(decodedData.message ?? "요청에러")
case 500:
return .serverErr
default:
return .networkFail
}
}
Apple 공식문서 왈 “Swift에서 가장 강력한 기능 중 하나”라고 평가를 받는 Generic은
타입에 의존하지 않는 범용 코드를 작성할 때 사용한다
제네릭을 사용하면 중복을 피하고, 코드를 유연하게 작성할 수 있다
라고 설명되어있으며, 실제 Swift의 표준 라이브러리가 대다수 제네릭으로 선언된다. 감이 안 잡힐게 뻔하니까 예시를 들어서 설명하도록 하겠다.
⇒ 다양한 객체에 대해 구현이 동일한 메서드나 타입을 컴파일 타임에 확인해 주는 강력한 도구
: 제네릭을 이용한 함수
자 우리는 두 개의 Int 타입 변수 값을 바꿔주는 swap함수를 구현을 해볼것이다.
func swapToInt(_ a: inout Int, _ b: inout Int) {
let tempA = a
a = b
b = tempA
}
근데 여기서 내가 String 타입 변수를 바꿔주는 함수를 구현하고 싶다. 그러면 새로운 함수를 만들어야겠쬬? 뭐 오버로딩을 하는 방법도 있겠고
func swapToInt(_ a: inout Int, _ b: inout Int) {
let tempA = a
a = b
b = tempA
}
func swapToString(_ a: inout String, _ b: inout String) {
let tempA = a
a = b
b = tempA
}
아니 그럼 여기서 개발자라면 (사실 난 그렇지 않은데) 짜증이 나야된다. ”아니 내가 같은 기능을 쓰는 함수를 여러개 만들어서 메모리를 낭비시켜야돼?” (이렇게 생각하는 놈이 변태다.)
그래서 Swift는 Generic 타입을 제공해서 아래와 같이 중복을 피하고 유연하게 코드를 짤 수 있게 해준다!
저렇게 T를 써줘서 만들어줄 수 있는데, 저 T는 타입 파라미터라고 불린다.
func swapToVariable<T>(_ a: inout T:, _ b: inout T) {
let tempA = a
a = b
b = tempA
}
<T>라고 불렸던 타입 파라미터는 새로운 형식으로 생성되는 것이 아니라, 실제 함수가 호출될 때 해당 매개변수의 타입으로 대체되는 Placeholder이다.