[Swift🦩] #24 뢈투λͺ…ν•œ νƒ€μž… Opaque Type

λ˜μƒΒ·2022λ…„ 4μ›” 22일
0

iOS

λͺ©λ‘ 보기
40/47
post-thumbnail
  • ν•¨μˆ˜μ˜ λ°˜ν™˜ νƒ€μž…μ„ κ°€λ¦°λ‹€.
  • ν•¨μˆ˜μ˜ λ°˜ν™˜ νƒ€μž…μœΌλ‘œ ꡬ체적인 νƒ€μž…μ„ μ œκ³΅ν•˜μ§€ μ•Šκ³ , ν”„λ‘œν† μ½œ μΈ‘λ©΄μ—μ„œ μ„œμˆ ν•œλ‹€.
  • ν”„λ‘œν† μ½œ νƒ€μž…μΈ μ–΄λ–€ 값을 λ°˜ν™˜ν•˜λŠ” 것이 μ•„λ‹ˆλΌ, ν”„λ‘œν† μ½œ νƒ€μž…μ˜ 정체성을 λ³΄μ‘΄ν•œλ‹€.
  • μ»΄νŒŒμΌλŸ¬λŠ” νƒ€μž… 정보에 접근이 λ˜λŠ”λ°, ν΄λΌμ΄μ–ΈνŠΈ λͺ¨λ“ˆμ€ νƒ€μž… 정보에 μ ‘κ·Όν•  수 μ—†λ‹€.
  • ν•΄λ‹Ή ν”„λ‘œν† μ½œμ„ λ”°λ₯΄λŠ” (μƒμ†λœ ν”„λ‘œν† μ½œ μ•ˆλ¨) νƒ€μž…λ§Œμ΄ Opaque Type 으둜 return 될 수 있음.

1. 뢈투λͺ…ν•œ νƒ€μž…μ΄ ν•΄κ²°ν•˜λŠ” 문제

  • ASCII 그림을 κ·Έλ¦¬λŠ” λͺ¨λ“ˆμ„ μž‘μ„±ν•œλ‹€κ³  κ°€μ •ν•˜λ©΄,
  • ASCII 의 νŠΉμ„±μ€ Shape ν”„λ‘œν† μ½œμ— μš”κ΅¬μ‚¬ν•­μΈ
  • μ–΄λ–€ λͺ¨μ–‘μ˜ λ¬Έμžμ—΄ ν‘œν˜„μ„ λ°˜ν™˜ν•˜λŠ” draw() ν•¨μˆ˜.
protocol Shape {
    func draw() -> String
}

struct Triangle: Shape {
    var size: Int
    func draw() -> String {
        var result: [String] = []
        for length in 1...size {
            result.append(String(repeating: "*", count: length))
        }
        return result.joined(separator: "\n")
    }
}
let smallTriangle = Triangle(size: 3)
print(smallTriangle.draw())
// *
// **
// ***



// μœ„μ˜ 코양을 수직으둜 λ’€μ§‘λŠ” μ½”λ“œλ₯Ό κ΅¬ν˜„.
// Triangle 을 λ„£μœΌλ©΄ FlippedShape<Triangle> 이 생성됨.
struct FlippedShape<T: Shape>: Shape {
    var shape: T
    func draw() -> String {
        let lines = shape.draw().split(separator: "\n")
        return lines.reversed().joined(separator: "\n")
    }
}
let flippedTriangle = FlippedShape(shape: smallTriangle)
print(flippedTriangle.draw())
// ***
// **
// *


// μœ„μ˜ 두 μ½”λ“œλ₯Ό κ²°ν•©
// μ—­μ‹œ Triangle 을 λ„£μœΌλ©΄?
// JoinedShape<FlippedShape<Triangle>, Triangle> 이런 νƒ€μž…μ΄ 생성됨.
struct JoinedShape<T: Shape, U: Shape>: Shape {
    var top: T
    var bottom: U
    func draw() -> String {
        return top.draw() + "\n" + bottom.draw()
    }
}
let joinedTriangles = JoinedShape(top: smallTriangle, bottom: flippedTriangle)
print(joinedTriangles.draw())
// *
// **
// ***
// ***
// **
// *
  • JoinedShape<FlippedShape<Triangle>, Triangle> 이런걸 λ°˜ν™˜ νƒ€μž…μœΌλ‘œ μ“°κ³  싢지도 μ•Šλ‹€...
  • μ–΄λ–€ λͺ¨μ–‘이라도 뒀집어 쀄 수 있고, λ°μΉΌμ½”λ§ˆλ‹ˆ 해쀄 수 μžˆμ–΄μ•Ό ν•˜κΈ° λ•Œλ¬Έμ—,
  • Generic 으둜 두 νƒ€μž…μ„ λ˜‘κ°™μ΄ λ§žμΆ”κ³ , return type 도 Shape κ°€ λ˜λŠ” 것.
  • κ·Έλž˜μ„œ JoinedShape 와 FlippedShape 와 같은 래퍼 νƒ€μž…μ€ λͺ¨λ“ˆμ˜ μ‚¬μš©μžμ—κ²ŒλŠ” μ€‘μš”ν•˜μ§€ μ•Šμ€ μ •λ³΄μ΄λ―€λ‘œ ν‘œμ‹œλ˜μ§€ μ•Šμ•„μ•Ό 함 -> μš°λ¦¬μ—κ²Œ ν•„μš”ν•œκ±΄ 그게 Shape λΌλŠ” 것 뿐.
    • μ–΄λ–»κ²Œ 뒀집고 ν•©μΉ˜λŠ”μ§€μ— λŒ€ν•œ μ •λ³΄λŠ” κ³΅κ°œν•  ν•„μš”κ°€ μ—†λ‹€.
    • Generic 의 경우, μ•„λž˜μ²˜λŸΌ Element λ₯Ό μ‚¬μš©ν•˜μ—¬ ν”„λ‘œνΌν‹°λ‚˜ λ©”μ„œλ“œλ₯Ό κ΅¬ν˜„ν•˜κ³ , μ‹€μ œ 호좜 μ‹œ Stack<Int> (IntλŠ” Equatable) μ΄λ ‡κ²Œ Element κ°€ μ •ν•΄μ§€κ²Œ λ˜λŠ”λ°,
    • 뢈투λͺ…ν•œ νƒ€μž…μ˜ 경우, μ •ν™•νžˆ λ­”μ§€λŠ” ν•„μš”μ—†κ³  Equatable 을 λ”°λ₯΄λŠ” some Equatable 둜 λ¦¬ν„΄ν•˜κ³  μ‹Άλ‹€λŠ” 뜻.
    • μ™œλƒλ©΄ / μ΄λ ‡κ²Œ 생긴 FilppedShape 인지 > μ΄λ ‡κ²Œ 생긴 JoinedShape 인지가 μ€‘μš”ν•΄?
    • Shape μ΄λ©΄μ„œ draw ν•¨μˆ˜λ₯Ό μ“Έ 수 μžˆμ–΄μ„œ λͺ¨μ–‘λ§Œ 좜λ ₯되면 λ˜μž–μ•„!!!!
struct Stack<Element: Equatable> {
    var list: [Element]
    mutating func append(_ element: Element) {
        list.append(element)
    }
    // Generic
    mutating func pop() -> Element {
        return list.remove(at: list.count - 1)
    }
    
    // Opaque Type
    mutating func pop() -> some Equatable {
        return list.remove(at: list.count - 1)
    }
}



2. 뢈투λͺ…ν•œ νƒ€μž… λ°˜ν™˜

  • Generic κ³Ό λ°˜λŒ€.
  • Generic
    • ν˜ΈμΆœν•˜λŠ” μ½”λ“œμ—μ„œ νŒŒλΌλ―Έν„° νƒ€μž…μ„ 선택
    • ν•¨μˆ˜λ₯Ό κ΅¬ν˜„λΆ€μ—μ„œ 좔상화 된 인자둜 값을 λ°˜ν™˜ν•  수 있음.
  • μ›λž˜λŠ”!!! Generic 으둜 T λΌλŠ” type 을 μ •ν•˜κ³  κ·Έκ±Έ return κ°’μ—κΉŒμ§€ μ μš©ν•΄μ„œ ν•¨μˆ˜ μ™ΈλΆ€μ—μ„œκΉŒμ§€ μ‚¬μš©ν•΄μ•Όν•˜λ―€λ‘œ, νƒ€μž…μ„ μ™ΈλΆ€μ—μ„œ λͺ…μ‹œλ₯Ό 해야함.
// generic
func max<T>(_ x: T, _ y: T) -> T where T: Comparable { ... }
  • max λ₯Ό μ‹€μ œλ‘œ ν˜ΈμΆœν•  λ•Œ, λ„£λŠ” x, y νŒŒλΌλ―Έν„° νƒ€μž…μ— 따라 λ‹¬λΌμ§€λŠ” Tλ₯Ό λ°˜ν™˜ν•˜κ²Œ λœλ‹€.

some Type - Opaque Type

ν•˜μ§€λ§Œ Opaque Type 의 경우?

  • ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•  λ•Œ return 값이 μΆ”μƒν™”λœ νƒ€μž…μœΌλ‘œ λ°˜ν™˜λ˜κ²Œ ν•  수 μžˆλ‹€.
  • some ν‚€μ›Œλ“œ μ‚¬μš©.
struct Square: Shape {
    var size: Int
    func draw() -> String {
        // λͺ¨μ–‘μ˜ κΈ°λ³Έ νƒ€μž…μ΄ 뭔지 λͺ¨λ₯΄κ² λŠ”데, λ°˜ν™˜μ€ ν•  수 있음.
        let line = String(repeating: "*", count: size)
        let result = Array<String>(repeating: line, count: size)
        return result.joined(separator: "\n")
    }
}

// κ·Έλž˜μ„œ some Shape λΌλŠ” κ°’μœΌλ‘œ λ°˜ν™˜.
// JoinedShape<Triangle, FilppedShape<Triangle>> 처럼 νƒ€μž…μ„ 정해쀄 ν•„μš”κ°€ μ—†λ‹€.
// <T: Shape>  -> T κ°€ μ—†λŠ”λ°λ„, some Shape λΌλŠ” κ°’μœΌλ‘œ λ°˜ν™˜μ΄ κ°€λŠ₯ν•œ 것.
func makeTrapezoid() -> some Shape {
    let top = Triangle(size: 2)
    let middle = Square(size: 2)
    let bottom = FlippedShape(shape: top)
    let trapezoid = JoinedShape(
        top: top,
        bottom: JoinedShape(top: middle, bottom: bottom)
    )
    return trapezoid
}
let trapezoid = makeTrapezoid()
print(trapezoid.draw())
// *
// **
// **
// **
// **
// *

wrapping ν•¨μˆ˜ Generic κ³Ό κ²°ν•©

  • Opaque Types λŠ” νŒŒλΌλ―Έν„° νƒ€μž…μ—λŠ” μ‚¬μš©ν•  μˆ˜κ°€ μ—†μœΌλ―€λ‘œ,
  • Generic κ³Ό κ²°ν•©ν•΄μ„œ νŒŒλΌλ―Έν„°κ°€ ν”„λ‘œν† μ½œμ„ λ”°λ₯΄λ„둝 μ‚¬μš©ν•  수 μžˆλ‹€.
func flip<T: Shape>(_ shape: T) -> some Shape {
    return FlippedShape(shape: shape)
}
func join<T: Shape, U: Shape>(_ top: T, _ bottom: U) -> some Shape {
    JoinedShape(top: top, bottom: bottom)
}

let opaqueJoinedTriangles = join(smallTriangle, flip(smallTriangle))
print(opaqueJoinedTriangles.draw())
// *
// **
// ***
// ***
// **
// *
  • κΈ°λ³Έ νƒ€μž…μ„ filp join ν•¨μˆ˜λ‘œ λž˜ν•‘ν•΄μ„œ FlippedShape, JoinedShape κ°€ μ–΄λ–€ νƒ€μž…μΈμ§€ λ“œλŸ¬λ‚˜μ§€ μ•Šκ²Œ ν•œλ‹€.
  • λͺ¨λ‘ some Shape 일 뿐.

return 이 λͺ¨λ‘ 같은 Type 이어야 함.

  • λ°˜ν™˜ν•˜λŠ” 값이 λͺ¨λ‘ Shape μ—¬μ•Ό ν•œλ‹€. (단일 νƒ€μž…μ„ λ°˜ν™˜ν•œλ‹€κ³  ν‘œν˜„ν•¨)
  • Shape λ₯Ό λ”°λ₯΄λŠ” μ–΄λ–€ κ΅¬ν˜„μ²΄λ„ μ•ˆλ¨.
func invalidFlip<T: Shape>(_ shape: T) -> some Shape {
    if shape is Square {
        return shape // Error: return types don't match
    }
    return FlippedShape(shape: shape) // Error: return types don't match
}

struct FlippedShape<T: Shape>: Shape {
    var shape: T
    func draw() -> String {
        if shape is Square { 
            return shape.draw() // μ΄λ ‡κ²Œ. μ‚¬μš©ν•˜μž.
        }
        let lines = shape.draw().split(separator: "\n")
        return lines.reversed().joined(separator: "\n")
    }
}
  • νƒ€μž…μ„ λ°˜ν™˜ν•  λ•Œ Generic 도 μ‚¬μš©ν•  수 μžˆλ‹€.
  • λŒ€μ‹  κΈ°λ³Έ νƒ€μž… T λ₯Ό μ£ΌκΈ° λ•Œλ¬Έμ—, 단일 νƒ€μž…μ„ λ”°λ₯΄κ²Œ λ˜μ–΄μ„œ κ°€λŠ₯ν•œ κ²ƒμž„.
  • Collection 이라고 λΆ„κΈ°νƒ€μ„œ Dictionary 와 Array λ₯Ό λ°˜ν™˜ν•˜λŠ” κ²½μš°λŠ” μ•ˆλœλ‹€λŠ” 것.
// λ°˜ν™˜κ°’μ˜ κΈ°λ³Έ νƒ€μž…μ„ Array<Shape> 둜 μ„€μ •.
// λŒ€μ‹  Shape κ°€ μ›μ†Œλ‘œ 듀어가야함.
func `repeat`<T: Shape>(shape: T, count: Int) -> some Collection {
    return Array<T>(repeating: shape, count: count)
}
  • κΌ­ ν•¨μˆ˜μ˜ λ°˜ν™˜κ°’λ§Œμ΄ μ•„λ‹ˆλΌ λ³€μˆ˜μ˜ νƒ€μž…μœΌλ‘œλ„ 지정 κ°€λŠ₯. (νŒŒλΌλ―Έν„°λŠ” μ•ˆλ¨)
var f1: CarFactory = TeslaFactory()
// ERROR : Protocol 'CarFactory' can be only used as a generic constraint ...
var f1: some CarFactory = TeslaFactory()
print(f1.produce())
// OK

3. Opaque Type vs Protocol

  • ν”„λ‘œν† μ½œμ„ μ‚¬μš©ν•˜λŠ” 것과 뢈투λͺ… νƒ€μž…μ„ return ν•˜λŠ” 것은 λΉ„μŠ·ν•œλ°,
  • λ°˜ν™˜ νƒ€μž…μ΄ νƒ€μž… 정체성을 μœ μ§€ν•˜λŠ”μ§€ μ—¬λΆ€λ‘œ κ°ˆλ¦°λ‹€.
  • Opaque Type 은 ν•˜λ‚˜μ˜ νŠΉμ • νƒ€μž…μ„ μ°Έμ‘°ν•˜μ§€λ§Œ, ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λŠ” 녀석이 μ–΄λ–€ νƒ€μž…μΈμ§€λŠ” λͺ¨λ₯Έλ‹€.
  • ν”„λ‘œν† μ½œ νƒ€μž…μ€ ν”„λ‘œν† μ½œμ„ μ€€μˆ˜ν•˜λŠ” λͺ¨λ“  νƒ€μž…μ„ μ°Έμ‘°ν•  수 μžˆλ‹€.
  • ν”„λ‘œν† μ½œμ€ ν”„λ‘œν† μ½œμ„ μ€€μˆ˜ν•˜λŠ” λͺ¨λ“  νƒ€μž…μ„ μœ μ—°ν•˜κ²Œ λ°˜ν™˜ν•  수 μžˆλ‹€.
    • ν•˜μ§€λ§Œ Type Casting 을 ν•˜μ§€ μ•ŠμœΌλ©΄ λ°˜ν™˜λœ 값에 λŒ€ν•œ 일뢀 μž‘μ—…μ„ μˆ˜ν–‰ν•  수 μ—†λ‹€.
  • 뢈투λͺ…ν•œ νƒ€μž…μ€ κΈ°λ³Έ νƒ€μž…μ— λŒ€ν•œ κ°•λ ₯ν•œ 보μž₯을 ν•  수 μžˆλ‹€. (무쑰건 Shape 둜 λ°˜ν™˜.)
    • ν”„λ‘œν† μ½œ νƒ€μž…μ„ λ°˜ν™˜κ°’μœΌλ‘œ μ“Έ 수 μ—†λŠ” μœ„μΉ˜μ— μ“΄λ‹€.
// ν”„λ‘œν† μ½œλ‘œ κ΅¬ν˜„ν•œ μœ„μ˜ ν•¨μˆ˜. 
// Shape ν”„λ‘œν† μ½œμ„ λ”°λ₯΄λŠ” μ—¬λŸ¬ νƒ€μž…μ˜ 값을 λ°˜ν™˜ν•  수 μžˆλ‹€.
func protoFlip<T: Shape>(_ shape: T) -> Shape {
    if shape is Square {
        return shape // Square return κ°€λŠ₯.
    }

    return FlippedShape(shape: shape)
}

let protoFlippedTriangle = protoFlip(smallTriangle)
let sameThing = protoFlip(smallTriangle)
protoFlippedTriangle == sameThing  // Error : == 이 κ΅¬ν˜„μ΄ μ•ˆλ˜μ–΄ 있음.


protoFlip(protoFlip(smallTriangle)) // Error : ν•œ 번 λ’€μ§‘μ€κ²Œ μœ νš¨ν•œ μΈμˆ˜κ°€ μ•„λ‹˜. 
// Generic T: Shape μ—λŠ” Shape λ₯Ό κ΅¬ν˜„ν•œ ꡬ체적인 νƒ€μž…λ§Œμ΄ 갈 수 μžˆλŠ”λ°,
// Shape κ°€ λ°˜ν™˜ νƒ€μž…μ΄λ―€λ‘œ Shape ν”„λ‘œν† μ½œ 자체λ₯Ό 인자둜 넣은 것이 됨.

protoFlip(protoFlippedTriangle as! FlippedShape<Triangle>)
// μ •ν™•ν•œ νƒ€μž…μœΌλ‘œ downcast ν•˜λ©΄ κ°€λŠ₯함.
  • Error : ν”„λ‘œν† μ½œ νƒ€μž…μ„ μ‚¬μš©ν•΄μ„œ νŠΉμ • 정보가 λ³΄μ‘΄λ˜μ§€ μ•ŠμŒ.
  • Shape μ—λŠ” == 이 κ΅¬ν˜„μ΄ μ•ˆλ˜μ–΄μžˆκΈ° λ•Œλ¬Έ.
  • 근데 == 을 μΆ”κ°€ν•˜λ €κ³  ν•˜λ©΄, ν”„λ‘œν† μ½œμ„ μ±„νƒν•œ ꡬ체적인 νƒ€μž…μ„ λ‚˜νƒ€λ‚΄λŠ” Self νƒ€μž…μ˜ 인수λ₯Ό μ‚¬μš©ν•΄μ•Όν•¨.
  • ν•˜μ§€λ§Œ Self λ₯Ό ν”„λ‘œν† μ½œμ— μΆ”κ°€ν•œλ‹€λ©΄?
    • μ–΄λ–€ νƒ€μž…μΈμ§€λ₯Ό μ•Œμ•„μ•Ό Self λ₯Ό μ“Έ 수 μžˆμ–΄μ„œ Type Erasure 그게 뭔데... κ°€ ν—ˆμš©λ˜μ§€ μ•ŠμŒ.

protocol Container {
    associatedtype Item 
    // Item μ΄λΌλŠ” associatedtype 이 μžˆμ–΄μ„œ Container λ₯Ό λ°˜ν™˜νƒ€μž…μœΌλ‘œ μ‚¬μš©ν•  수 μ—†μŒ.
    // Item 이 μ–΄λ–€ νƒ€μž…μΈμ§€λ₯Ό λͺ¨λ₯΄λ‹ˆκΉŒ.
    // λ°˜ν™˜ μ œμ•½ μ‘°κ±΄μœΌλ‘œλ„ μ‚¬μš©μ΄ μ•ˆλ¨.
    var count: Int { get }
    subscript(i: Int) -> Item { get }
}
extension Array: Container { }


// Error: Protocol with associated types can't be used as a return type.
func makeProtocolContainer<T>(item: T) -> Container {
    return [item]
}

// Error: Not enough information to infer C.
func makeProtocolContainer<T, C: Container>(item: T) -> C {
    return [item]
}


// 그치만 μ΄λ ‡κ²Œ some 을 λΆ™μ—¬μ„œ 뢈투λͺ…ν•œ νƒ€μž…μ„ 보내주면?
// μ»¨ν…Œμ΄λ„ˆλ₯Ό λ°˜ν™˜ν•˜λ˜, νƒ€μž… 지정은 κ±°λΆ€ν•˜κ²Œ λ˜λ―€λ‘œ μ—°κ΄€ νƒ€μž…μ΄ μžˆλŠ” protocol λ°˜ν™˜μ΄ κ°€λŠ₯해진닀.
func makeOpaqueContainer<T>(item: T) -> some Container {
    return [item]
}
let opaqueContainer = makeOpaqueContainer(item: 12)
let twelve = opaqueContainer[0]
print(type(of: twelve))  // Prints "Int" : νƒ€μž… μΆ”λ‘  κ°€λŠ₯.



Type Erasure 그게 뭔데...

func getComparable() -> Comparable { // error : ν”„λ‘œν† μ½œμ„ λ”°λ₯΄λŠ” νƒ€μž…μ„ λ°˜ν™˜ν•  μˆ˜κ°€ μ—†μŒ.
  return 1
}

// κ·Έλž˜μ„œ μ•„λž˜μ²˜λŸΌ Generic 을 ν†΅ν•΄μ„œ Comparable 을 λ”°λ₯΄λŠ” μ–΄λ–€ νƒ€μž…μ„ μ‚¬μš©ν•œλ‹€κ³  λͺ…μ‹œν•΄μ•Ό ν–ˆμŒ.
// 그러면 ν•¨μˆ˜ μ™ΈλΆ€μ—μ„œ 이 νƒ€μž…μ΄ 뭔지... λͺ…μ‹œκ°€ ν•„μš”ν•¨.
func getComparable<T: Comparable>() -> T {
  return 1 as! T
}
func getComparable<T>() -> T 
    where T: Comparable {
  return 1 as! T
}
  • κ·Έλž˜μ„œ Opaque Type 이 λ“±μž₯ν–ˆλŠ”λ°...?
func getComparable() -> some Comparable {
  return 1
}
  • μ•„λž˜μ²˜λŸΌ λΆ„κΈ°λ₯Ό νƒ€μ„œ μ—¬λŸ¬ comparable 을 λ”°λ₯΄λŠ” 값을 return ν•˜κ³  μ‹Άλ‹€λ©΄..?
func getComparable() -> some Comparable {
	if true { return 1 }
    else { return "oh my god" }
}
  • Opaque Type μ—μ„œ return 값이 λ§Œμ‘±ν•΄μ•Ό ν•˜λŠ” 쑰건을 λ”°λ₯΄κ²Œ ν•˜κΈ° μœ„ν•΄.
  • Type 을 μ§€μ›Œμ„œ λ­‰λš±κ·Έλ €μ€˜μ•Όν•¨.
  • AnyComparable 같은 ꡬ쑰체λ₯Ό λ§Œλ“€μ–΄μ„œ νƒ€μž…μ„ μ§€μš΄λ‹€.
  • μžμ„Έν•œ μ½”λ“œλŠ” https://minsone.github.io/programming/swift-opaque-type-and-erase-type
  • μ•„λ¬΄νŠΌ Self λ₯Ό ν”„λ‘œν† μ½œμ— μΆ”κ°€ν•˜κ²Œ 되면, Type 을 μ§€μšΈμˆ˜κ°€ μ—†λ‹€.
    • Self λΌλŠ” ν•΄λ‹Ή 객체의 μ •ν™•ν•œ νƒ€μž…μ„ λ‚˜νƒ€λ‚΄λŠ” κ±°λ‹ˆκΉŒ.

https://sanichdaniel.tistory.com/16



  • Generic 은 νƒ€μž…μ„ 좔상화 ν•˜λ˜, ν•΄λ‹Ή νƒ€μž…μ΄ μ–΄λ–€ ν”„λ‘œν† μ½œμ„ λ”°λ₯΄λŠ”μ§€λ‚˜ μ–΄λ–€ νƒ€μž…μΈμ§€ 등을 <T: Equtable> where ν‚€μ›Œλ“œλ‘œ 지정해쀄 수 μžˆμ—ˆμŒ.
  • 그리고 μ‹€μ œλ‘œ μ‚¬μš©ν•  λ•Œ, μ•„ 이거 μ •ν™•ν•˜κ²Œ μ–΄λ–€ νƒ€μž…μ΄λ‹€! 라고 지정이 λ˜μ–΄μ„œ 듀어감.
  • κ·Έλ ‡κΈ° λ•Œλ¬Έμ— Generic 으둜 T λΌλŠ” type 을 μ •ν•˜κ³  κ·Έκ±Έ return κ°’μ—κΉŒμ§€ μ μš©ν•΄μ„œ ν•¨μˆ˜ μ™ΈλΆ€μ—μ„œκΉŒμ§€ μ‚¬μš©ν•΄μ•Όν•˜λ―€λ‘œ, λ“€μ–΄κ°€λŠ” νƒ€μž…μ„ μ™ΈλΆ€μ—μ„œ λͺ…μ‹œν•΄μ•Όν•¨. Array<Int>
  • ν•˜μ§€λ§Œ Opaque νƒ€μž…μ€ μ •ν™•ν•˜κ²Œ μ–΄λ–€ νƒ€μž…μ΄λ‹€! μ—†μŒ. μΆ”μƒν™”λœ(μƒμœ„) νƒ€μž…μ„ κ·ΈλŒ€λ‘œ return.
  • ν•¨μˆ˜ μ™ΈλΆ€μ—μ„œ μ–΄λ–€ ν”„λ‘œν† μ½œμ„ λ”°λ₯΄λŠ” νƒ€μž…μ„ μ •ν™•ν•˜κ²Œ λͺ…μ‹œν•˜λŠ”κ±Έ ν”Όν•˜κΈ° μœ„ν•΄μ„œ μ‚¬μš©
func getComparable<T>() -> T 
    where T: Comparable {
  return 1
}



질문

some ν‚€μ›Œλ“œμ— λŒ€ν•΄ μ„€λͺ…ν•˜μ‹œμ˜€.

  • some ν‚€μ›Œλ“œλŠ” ν•΄λ‹Ή ν”„λ‘œν† μ½œ(예λ₯Ό λ“€μ–΄μ„œ Comparable) 을 λ”°λ₯΄λŠ” νƒ€μž…μ„ λ°˜ν™˜ν•  λ•Œ μ‚¬μš©ν•œλ‹€.
  • μ§€κΈˆκΉŒμ§€λŠ” ν”„λ‘œν† μ½œμ„ λ”°λ₯΄λŠ” νƒ€μž…μ„ λ°˜ν™˜ν•˜λ €λ©΄, Generic 의 νƒ€μž… μ œν•œμ„ μ΄μš©ν•΄μ•Ό ν–ˆλŠ”λ°,
  • κ·Έλ ‡κ²Œ ν•˜λ©΄ ν•¨μˆ˜ λ°”κΉ₯μ—μ„œ ν•΄λ‹Ή νƒ€μž…μ΄ (Comparable 을 λ”°λ₯΄λŠ”) μ •ν™•νžˆ μ–΄λ–€ νƒ€μž…μΈμ§€ (Int, String, ...) λ₯Ό λͺ…μ‹œν•΄μ£Όμ–΄μ•Ό ν–ˆλ‹€.
  • μΌλ°˜ν™”ν•΄μ„œ return ν•˜κ³  μ™ΈλΆ€μ—μ„œ λͺ…μ‹œλ₯Ό μ•ˆν•˜κ³  μ‹Άμ–΄... : some Comparable λ₯Ό μ‚¬μš©ν•œλ‹€.
  • λŒ€μ‹  ν•΄λ‹Ή ν”„λ‘œν† μ½œμ„ μƒμ†ν•œ ν”„λ‘œν† μ½œμ„ μ±„νƒν•˜λŠ” 객체가 λ°˜ν™˜λ  순 μ—†μŒ. μ •ν™•ν•˜κ²Œ Comparable 만이 λ°˜ν™˜λ˜μ–΄μ•Ό 함.
  • κ·ΈλŸ¬λ―€λ‘œ Type Erasing 을 μ‚¬μš©ν•œλ‹€.
profile
0λ…„μ°¨ iOS κ°œλ°œμžμž…λ‹ˆλ‹€.

0개의 λŒ“κΈ€