λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
🍏 Today I Learned/Swift 문법

[Swift] μ œλ„€λ¦­ (Generic)

by Joseph Seong 2023. 12. 13.

 

 

μ œλ„€λ¦­ (Generic)

 

μ œλ„€λ¦­

 

πŸ’‘ μ œλ„€λ¦­μ΄λž€?

  • ν•¨μˆ˜, νƒ€μž… 및 데이터 ꡬ쑰에 λŒ€ν•œ μœ μ—°ν•˜κ³  좔상적인 μ½”λ“œλ₯Ό μž‘μ„±ν•  수 있게 ν•΄μ£ΌλŠ” κΈ°λŠ₯
  • λ‹€μ–‘ν•œ νƒ€μž…μ—μ„œ μž‘λ™ν•˜λ„λ‘ μΌλ°˜ν™”λœ μ½”λ“œλ₯Ό μž‘μ„±ν•  수 있게 ν•΄μ€€λ‹€.
  • μ œλ„€λ¦­μœΌλ‘œ κ΅¬ν˜„ν•œ κΈ°λŠ₯κ³Ό νƒ€μž…μ€ μž¬μ‚¬μš©ν•˜κΈ°λ„ 쉽고, μ½”λ“œμ˜ 쀑볡을 쀄일 수 μžˆλ‹€.
  • μ œλ„€λ¦­μ„ μ‚¬μš©ν•˜κ³ μž ν•  λ•ŒλŠ” μ œλ„€λ¦­μ΄ ν•„μš”ν•œ νƒ€μž… λ˜λŠ” λ©”μ„œλ“œμ˜ 이름 λ’€μ˜ ν™”μ‚΄κ΄„ν˜Έ 기호 사이에 μ œλ„€λ¦­μ„ μœ„ν•œ νƒ€μž… λ§€κ°œλ³€μˆ˜λ₯Ό 써주어 μ œλ„€λ¦­μ„ μ‚¬μš©ν•  κ²ƒμž„μ„ ν‘œμ‹œν•œλ‹€.
  • μ œλ„€λ¦­μ€ μ‹€μ œ νƒ€μž… 이름을 μ¨μ£ΌλŠ” λŒ€μ‹ μ— placeholderλ₯Ό μ‚¬μš©ν•œλ‹€. [ eg: T, V, U ]
  • placeholderλŠ” νƒ€μž…μ˜ μ’…λ₯˜λ₯Ό μ•Œλ €μ£Όμ§€ μ•Šμ§€λ§Œ μ–΄λ–€ νƒ€μž…μ΄λΌλŠ” 것은 μ•Œλ €μ€€λ‹€.
  • placeholder의 μ‹€μ œ νƒ€μž…μ€ ν•¨μˆ˜κ°€ ν˜ΈμΆœλ˜λŠ” μˆœκ°„ κ²°μ •λœλ‹€.
  • placeholderλŠ” νƒ€μž… λ§€κ°œλ³€μˆ˜λ‘œ 쓰일 μˆ˜λ„ μžˆλŠ”λ°, 이 νƒ€μž… λ§€κ°œλ³€μˆ˜λŠ” ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•  λ•Œλ§ˆλ‹€ μ‹€μ œ νƒ€μž…μœΌλ‘œ μΉ˜ν™˜λœλ‹€.
  • ν•˜λ‚˜μ˜ νƒ€μž… λ§€κ°œλ³€μˆ˜λ₯Ό κ°–μ§€ μ•Šκ³  μ—¬λŸ¬ 개의 νƒ€μž… λ§€κ°œλ³€μˆ˜λ₯Ό κ°–κ³  μ‹Άλ‹€λ©΄ ν™€ν™”μ‚΄κ΄„ν˜Έ 기호 μ•ˆμͺ½μ— μ‰Όν‘œλ‘œ λΆ„λ¦¬ν•œ μ—¬λŸ¬ 개의 νƒ€μž… λ§€κ°œλ³€μˆ˜λ₯Ό 지정해쀄 수 μžˆλ‹€. [ eg: <T, U> ]
  • μ œλ„€λ¦­ νƒ€μž…μ„ κ΅¬ν˜„ν•˜λ©΄ ꡬ쑰체, 클래슀, μ—΄κ±°ν˜• 등이 μ–΄λ–€ νƒ€μž…κ³Όλ„ μ—°κ΄€λ˜μ–΄ λ™μž‘ν•  수 μžˆλ‹€.
  • μ œλ„€λ¦­ νƒ€μž…μ„ μ •ν•΄μ£Όλ©΄ κ·Έ νƒ€μž…μ—λ§Œ λ™μž‘ν•˜λ„λ‘ μ œν•œν•  수 μžˆμ–΄ μ•ˆμ „ν•˜κ³  μ˜λ„ν•œ λŒ€λ‘œ κΈ°λŠ₯을 μ‚¬μš©ν•˜λ„λ‘ μœ λ„ν•  수 μžˆλ‹€.

 

inout ν‚€μ›Œλ“œ

/*
inout ν‚€μ›Œλ“œλŠ” ν•¨μˆ˜ λ‚΄μ—μ„œ λ§€κ°œλ³€μˆ˜λ‘œ μ „λ‹¬λœ 값을 λ³€κ²½ν•˜κ³ , 
이λ₯Ό ν•¨μˆ˜ μ™ΈλΆ€μ—μ„œλ„ λ°˜μ˜ν•  수 μžˆλ„λ‘ ν•˜λŠ” 데 μ‚¬μš©λœλ‹€. 
이λ₯Ό 톡해 ν•¨μˆ˜ λ‚΄μ—μ„œ λ§€κ°œλ³€μˆ˜μ˜ 값을 직접 μˆ˜μ •ν•  수 μžˆλ‹€.

inout ν‚€μ›Œλ“œ μ‚¬μš© 방법:
1. λ§€κ°œλ³€μˆ˜μ— inout ν‚€μ›Œλ“œλ₯Ό λΆ™μ—¬ μ„ μ–Έν•œλ‹€.
2. ν•¨μˆ˜ 호좜 μ‹œ λ§€κ°œλ³€μˆ˜λ₯Ό & 기호둜 μ „λ‹¬ν•˜μ—¬ ν•΄λ‹Ή 값을 참쑰둜 μ „λ‹¬ν•œλ‹€.
*/


// ν•¨μˆ˜ μ •μ˜
func increment(_ value: inout Int) {
    value += 1
}

var number = 5
print("Before increment: \(number)") // 좜λ ₯: Before increment: 5

// ν•¨μˆ˜ 호좜 μ‹œ λ§€κ°œλ³€μˆ˜μ— &λ₯Ό μ‚¬μš©ν•˜μ—¬ λ³€μˆ˜μ˜ μ°Έμ‘°λ₯Ό 전달
increment(&number)

print("After increment: \(number)") // 좜λ ₯: After increment: 6

// 두 λ³€μˆ˜μ˜ 값을 λ°”κΏ”μ£ΌλŠ” ν•¨μˆ˜λ₯Ό νƒ€μž…λ³„λ‘œ μž‘μ„±ν•΄μ•Όν•¨(μ œλ„€λ¦­ μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” 경우)
func swapTwoInts(_ a: inout Int, _ b: inout Int) {
    let temporaryA = a
    a = b
    b = temporaryA
}

func swapTwoStrings(_ a: inout String, _ b: inout String) {
    let temporaryA = a
    a = b
    b = temporaryA
}

func swapTwoDoubles(_ a: inout Double, _ b: inout Double) {
    let temporaryA = a
    a = b
    b = temporaryA
}

// μ œλ„€λ¦­μ„ μ‚¬μš©ν•˜λ©΄ νƒ€μž…μ— 상관없이 μ‚¬μš©κ°€λŠ₯함
func swapTwoValues<T>(_ a: inout T, _ b: inout T) {
    let temporaryA = a
    a = b
    b = temporaryA
}

 

큐(Queue), μŠ€νƒ(Stack)

struct Queue<T> {
    private var queue: [T] = [] 
    
    public var count: Int {
        return queue.count
    }
    
    public var isEmpty: Bool {
        return queue.isEmpty
    }
    
    public mutating func enqueue(_ element: T) {
        queue.append(element)
    }
    
    public mutating func dequeue() -> T? {
        return isEmpty ? nil : queue.removeFirst()
    }
}

var queue = Queue<Int>()	// λͺ¨λ“  Tκ°€ 일치
queue.enqueue(10)			// int의 κ°’λ§Œ 넣을 수 μžˆλ‹€.
queue.enqueue(20)
queue.dequeue() // 10

struct Stack<T> {
    private var stack: [T] = []
    
    public var count: Int {
        return stack.count
    }
    
    public var isEmpty: Bool {
        return stack.isEmpty
    }
    
    public mutating func push(_ element: T) {
        stack.append(element)
    }
    
    public mutating func pop() -> T? {
        return isEmpty ? nil : stack.popLast()
    }
}

var stack = Stack<Int>()	// TλŠ” Int둜 κ³ μ •
stack.push(10)				// int의 κ°’λ§Œ 넣을 수 μžˆλ‹€.
stack.push(20)
stack.pop() // 20

 

λ”•μ…”λ„ˆλ¦¬ (Dictionary)

// λ”•μ…”λ„ˆλ¦¬ μ˜ˆμ‹œ
@frozen public struct Dictionary<Key, Value> where Key : Hashable {	// whereλŠ” μ œμ•½μ‘°κ±΄(Key의 κ²½μš°μ—λŠ” Hashable을 λ”°λ₯Έ νƒ€μž…λ§Œ λ“€μ–΄μ˜¬ 수 μžˆλ‹€.)

    /// The element type of a dictionary: a tuple containing an individual
    /// key-value pair.
    public typealias Element = (key: Key, value: Value)


var fruitsInventory: Dictionary<String, Int> = [:]
fruitsInventory["apple"] = 3
/*
Key, Value νƒ€μž…μ˜ μ œλ„€λ¦­μœΌλ‘œ λ˜μ–΄μžˆμ–΄ μš°λ¦¬λŠ” μ›ν•˜λŠ” νƒ€μž…μœΌλ‘œ λ”•μ…”λ„ˆλ¦¬λ₯Ό 생성할 수 있음
μ œμ•½μ‘°κ±΄μ€ Keyκ°€ Hashable ν”„λ‘œν† μ½œλ§Œ λ”°λ₯΄λ©΄ λ˜λŠ” 것이닀
κΈ°λ³Έ μžλ£Œν˜•μΈ String은 Hashable ν”„λ‘œν† μ½œμ„ λ”°λ₯΄κ³  있음
λ§Œμ•½ λ‹€λ₯Έ μžλ£Œν˜•μ„ Key둜 μ‚¬μš©ν•˜λ €λ©΄ Hashable ν”„λ‘œν† μ½œμ„ 채택해야 함
*/

 

/*
where ν‚€μ›Œλ“œλŠ” λ¬΄μ—‡μΌκΉŒμš”?

μ œλ„€λ¦­μ˜ μ œμ•½μ‘°κ±΄(Constraints)인 where ν‚€μ›Œλ“œλŠ” μ œλ„€λ¦­ νƒ€μž…μ— νŠΉμ • 쑰건을 λΆ€μ—¬ν•˜μ—¬ 
ν•΄λ‹Ή μ œμ•½μ„ μΆ©μ‘±ν•˜λŠ” νƒ€μž…λ§Œμ„ μ‚¬μš©ν•  수 μžˆλ„λ‘ ν•˜λŠ” κΈ°λŠ₯ 
where ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ μ œλ„€λ¦­ νƒ€μž…μ— νŠΉμ • ν”„λ‘œν† μ½œ 채택, 
νŠΉμ • νƒ€μž…κ³Όμ˜ 상속 관계 등을 μ œν•œν•  수 μžˆλ‹€.
*/

// ν”„λ‘œν† μ½œ 채택 μ œμ•½ μ˜ˆμ‹œ
func process<T>(value: T) where T: Numeric {
    // Numeric ν”„λ‘œν† μ½œμ„ μ±„νƒν•˜λŠ” νƒ€μž…λ§Œμ„ μ œλ„€λ¦­ νƒ€μž… T둜 λ°›μŒ
    print("Value is a numeric type.")
}

process(value: 5) // 좜λ ₯: Value is a numeric type.
process(value: 3.14) // 좜λ ₯: Value is a numeric type.
// process(value: "Hello") // 컴파일 μ—λŸ¬ - λ¬Έμžμ—΄μ€ Numeric ν”„λ‘œν† μ½œμ„ μ±„νƒν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— μ‚¬μš©ν•  수 μ—†λ‹€.


// 클래슀의 상속 관계 μ œμ•½ μ˜ˆμ‹œ
class MyClass {}
class MySubclass: MyClass {}

func process<T>(value: T) where T: MyClass {
    print("Value is an instance of MyClass or its subclasses.")
}

let obj = MySubclass()
process(value: obj) // 좜λ ₯: Value is an instance of MyClass or its subclasses.
// process(value: "Hello") // 컴파일 μ—λŸ¬ - λ¬Έμžμ—΄μ€ MyClass λ˜λŠ” κ·Έ ν•˜μœ„ ν΄λž˜μŠ€κ°€ μ•„λ‹ˆκΈ° λ•Œλ¬Έμ—

 

 

 

 

 

 

'🍏 Today I Learned > Swift 문법' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€

[Swift] RxSwift  (0) 2023.12.15
[Swift] Combine  (0) 2023.12.15
[Swift] ν™•μž₯ (Extension)  (0) 2023.12.13
[Swift] ν”„λ‘œν† μ½œ  (0) 2023.12.13
[Swift] ARC와 λ©”λͺ¨λ¦¬ λˆ„μˆ˜  (0) 2023.12.13