21. Generics

Kang.__.Mingu·2021년 7월 31일
0

1. Study Swift

목록 보기
21/25

형식에 독립적인 코드를 구현하는 방법에 대해 공부합니다.

Generic Function

특정 형식과 연관되지 않은 함수를 구현하는 방법에 대해 공부

Generics

func swapInteger(lhs: inout Int, rhs: inout Int) {
   let tmp = lhs
   lhs = rhs
   rhs = tmp
}

var a = 10
var b = 20

swapInteger(lhs: &a, rhs: &b)
a
b

// 필요한 수만큼 갯수 구현
func swapInteger16(lhs: inout Int16, rhs: inout Int16) {
   // ...
}

func swapInteger64(lhs: inout Int64, rhs: inout Int64) {
   // ...
}

func swapDouble(lhs: inout Double, rhs: inout Double) {
   // ...
}

Generic Function

func name<T>(parameters) -> Type {
	code
}

함수 parameters

제네릭 함수로 구현

func swapValue<T>(lhs: inout T, rhs: inout T) {
   let tmp = lhs
   lhs = rhs
   rhs = tmp
}

a = 1
b = 2
swapValue(lhs: &a, rhs: &b)
a
b

// Double로 전달
var c = 1.2
var d = 3.4
swapValue(lhs: &c, rhs: &d)

// T가 Int라면 Int타입으로 출력되고 Double 이라면 Double로 출력된다.

Type Constraints

<TypeParameter: ClassName>
<TypeParameter: ProtocolName>

값이 다를 때만 교체하면 효율적이다

func swapValue<T: Equatable>(lhs: inout T, rhs: inout T) { // <T: Equatable> 비교할 수 있는 값만 전달
    if lhs == rhs { return }
    
    let tmp = lhs
    lhs = rhs
    rhs = tmp
}

Specialization

func swapValue<T: Equatable>(lhs: inout T, rhs: inout T) {
   print("generic version")
   
   if lhs == rhs {
      return
   }
   
   let tmp = lhs
   lhs = rhs
   rhs = tmp
}

func swapValue(lhs: inout String, rhs: inout String) {
    print("specailalized version")
    
    if lhs.caseInsensitiveCompare(rhs) == .orderedSame {
        return
    }
    
    let tmp = lhs
    lhs = rhs
    rhs = tmp
}

var a = 1
var b = 2
swapValue(lhs: &a, rhs: &b)


// 우선 순위가 높은 2번째 함수가 출력
var c = "Swift"
var d = "Programming"
swapValue(lhs: &c, rhs: &d)

Generic Types

제네릭 타입을 선언하고 형식 내부에서 사용하는 다양한 방식을 타입 파라미터로 대체하는 방법에 대해 공부

class Name<T> {
	code
}

struct Name<T> {
	code
}

enum Name<T> {
	code
}
struct Color<T> {
    var red: T
    var green: T
    var blue: T
}
// 타입 파라미터가 자동으로 추론
var c = Color(red: 128, green: 80, blue: 200)

//let d: Color<Int> //= Color(red: 128.0, green: 80.0, blue: 200.0)

// Array
//let arr: Array<Int>
//
//let dict: Dictionary<String, Double>


// 속성을 배열로 나타냄

extension Color {
    func getComponents() -> [T] {
        return [red, green, blue]
    }
}

let intColor = Color(red: 1, green: 2, blue: 3)
intColor.getComponents()

let dblColor = Color(red: 1.0, green: 2.0, blue: 3.0)       // 확장 대상 추가
dblColor.getComponents()

Associated Types

프로토콜 내에서 실제 형식으로 대체되는 연관 형식을 선언하는 방법에 대해 공부

associatedType Name
// 연관형식
protocol QueueCompatible {
    associatedtype Element      // 형식 제약하려면 associatedtype Element: Equatable 프로토콜 추가
   func enqueue(value: Element)
   func dequeue() -> Element?
}

class IntegerQueue: QueueCompatible {
    typealias  Element = Int
    
    func enqueue(value: Int) {
        
    }
    
    func dequeue() -> Int? {
        return 0
    }
}

class DoubleQueue: QueueCompatible {
    func enqueue(value: Double) {
        
    }
    func dequeue() -> Double? {
        return 0
    }
}
profile
최선을 다해 꾸준히 노력하는 개발자 망고입니당 :D

0개의 댓글