λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
⌨️ Language/swift

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

by hyebin (Helia) 2023. 2. 7.
λ°˜μ‘ν˜•

μ œλ„€λ¦­ (Generic)

  • νƒ€μž…μ„ νŒŒλΌλ―Έν„°ν™” ν•˜μ—¬ 컴파일 νƒ€μž„μ— ꡬ체적인 νƒ€μž…μ΄ κ²°μ •λ˜λŠ” 것을 의미
  • μ œλ„€λ¦­μ„ μ΄μš©ν•˜λ©΄ νƒ€μž…μ— μœ μ—°ν•˜κ²Œ λŒ€μ²˜ν•˜λŠ” 것이 κ°€λŠ₯
  • μ œλ„€λ¦­μœΌλ‘œ κ΅¬ν˜„ν•œ κΈ°λŠ₯κ³Ό νƒ€μž…μ€ μž¬μ‚¬μš©μ— 용이
  • μ½”λ“œμ˜ 쀑볡을 쀄일 수 μžˆμ–΄μ„œ κΉ”λ”ν•œ ν‘œν˜„μ΄ κ°€λŠ₯
  • Swiftμ—μ„œμ˜ λŒ€ν‘œμ μΈ μ œλ„€λ¦­ νƒ€μž…μœΌλ‘œλŠ” Array와 Dictionary νƒ€μž…μ΄ 
  • Array와 DictionaryλŠ” Int 값을 μ €μž₯ν•  μˆ˜λ„ 있고, String 값을 μ €μž₯ν•  μˆ˜λ„ μžˆμœΌλ―€λ‘œ, νƒ€μž…μ— μ œν•œμ΄ μ—†μŒ
// String νƒ€μž…μ„ κ°–λŠ” λ‘κ°œμ˜ 값을 λ°”κΎΈλŠ” ν•¨μˆ˜
func swapTwoStrings(_ a: inout String, _ b: inout String) {
	let temporaryA = a
 	a = b
 	b = temporaryA
}

// Double νƒ€μž…μ„ κ°–λŠ” λ‘κ°œμ˜ 값을 λ°”κΎΈλŠ” ν•¨μˆ˜
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
}

 

νƒ€μž… νŒŒλΌλ―Έν„° (Type Parameters) 

  • μœ„ swapTwoValues ν•¨μˆ˜μ˜ μ˜ˆμ œμ—μ„œ TλŠ” νƒ€μž… νŒŒλΌλ―Έν„°μ˜ μ˜ˆμ‹œ
  • νƒ€μž… νŒŒλΌλ―Έν„°λŠ” κΊ½μ‡  κ΄„ν˜Έ (<>) 사이에, 견본 (placeholder) νƒ€μž…μ„ μ§€μ •ν•œ λ‹€μŒμ— 이름을 μ§€μ •ν•˜κ³ , ν•¨μˆ˜μ˜ 이름 λ°”λ‘œ 뒀에 μž‘μ„±
  • νƒ€μž… νŒŒλΌλ―Έν„°λ₯Ό ν•œλ²ˆ μ„ μ–Έν•˜λ©΄ 이 것을 ν•¨μˆ˜μ˜ νƒ€μž…μœΌλ‘œ μ‚¬μš© κ°€λŠ₯
  • 볡수의 νƒ€μž… νŒŒλΌλ―Έν„°λ₯Ό μ‚¬μš©ν•  λ•ŒλŠ” <T, U>와 같이 콀마둜 ꡬ뢄

νƒ€μž… νŒŒλΌλ―Έν„° 이름 μ§“κΈ°

  • Dictionary와 같이 μ—˜λ¦¬λ¨ΌνŠΈ κ°„μ˜ μ„œλ‘œ 상관관계가 μžˆλŠ” 경우 μ˜λ―Έκ°€ μžˆλŠ” 이름을 νŒŒλΌλ―Έν„° μ΄λ¦„μœΌλ‘œ λΆ™μž„
  • κ·Έλ ‡μ§€ μ•Šμ€ κ²½μš°λŠ” T , U , V와 같은 단일 문자둜 νŒŒλΌλ―Έν„° 이름을 μ‚¬μš©
  • 값이 μ•„λ‹ˆλΌ νƒ€μž…μ— λŒ€ν•œ placeholder μž„μ„ 가리킀기 μœ„ν•΄, 항상 νƒ€μž… λ§€κ°œλ³€μˆ˜μ˜ μ΄λ¦„μ—λŠ” 카멜 ν‘œκΈ°λ²•μ„ μ‚¬μš©

νƒ€μž… μ œμ•½ 사항

  • νƒ€μž… μ œμ•½μ‚¬ν•­μ€ νƒ€μž… λ§€κ°œλ³€μˆ˜κ°€ νŠΉμ • ν΄λž˜μŠ€μ—μ„œ μƒμ†λ˜μ–΄μ•Ό ν•˜κ±°λ‚˜, νŠΉμ • ν”„λ‘œν† μ½œμ΄λ‚˜ ν”„λ‘œν† μ½œ 합성을 μ€€μˆ˜ν•˜λŠ” 것을 μ§€μ •
  • 예λ₯Ό λ“€μ–΄, Swift의 Dictionary νƒ€μž…μ€ λ”•μ…”λ„ˆλ¦¬μ˜ ν‚€λ‘œ μ‚¬μš©λ  수 μžˆλŠ” νƒ€μž…μ„ Hashable둜 μ œν•œ
  • 단일 ν΄λž˜μŠ€λ‚˜ νƒ€μž… λ§€κ°œλ³€μˆ˜ 이름 뒀에 νƒ€μž… λ§€κ°œλ³€μˆ˜ λͺ©λ‘μœΌλ‘œ 콜둠(:)으둜 κ΅¬λΆ„λœ, ν”„λ‘œν† μ½œ μ œμ•½μ‚¬ν•­μ„ μœ„μΉ˜μ‹œμΌœμ„œ νƒ€μž… μ œμ•½μ‚¬ν•­μ„ μž‘μ„±
func someFunction<T: SomeClass, U: SomeProtocol>(someT: T, someU: U)
{
 // ...
}

 

μ—°κ΄€ νƒ€μž… (Associated Types)

  • μ—°κ΄€ νƒ€μž…(associated type)은 ν”„λ‘œν† μ½œμ—μ„œ μ‚¬μš©λ˜λŠ” νƒ€μž…μ— placeholder 이름을 μ£ΌλŠ” 것
  • μ—°κ΄€ νƒ€μž…μ— μ‚¬μš©ν•˜λŠ” μ‹€μ œ νƒ€μž…μ€ ν”„λ‘œν† μ½œμ΄ 채택될 λ•ŒκΉŒμ§€ μ§€μ •λ˜μ§€ μ•ŠμŒ
  • μ—°κ΄€ νƒ€μž…μ€ associatedtype ν‚€μ›Œλ“œλ‘œ μ§€μ •
protocol Container {
     associatedtype Item
     mutating func append(_ item: Item)
     var count: Int { get }
     subscript(i: Int) -> Item { get }
}

 

μ œλ„€λ¦­ Where절

  • νŠΉμ • ν”„λ‘œν† μ½œμ„ λ°˜λ“œμ‹œ μ€€μˆ˜ν•˜λŠ” μ—°κ΄€λœ νƒ€μž…μ„ κ°€μ Έμ˜€κ±°λ‚˜, νŠΉμ • νƒ€μž… λ§€κ°œλ³€μˆ˜μ™€ μ—°κ΄€λœ νƒ€μž…μ΄ λ™μΌν•˜κ²Œ ν•˜λŠ” 것이 κ°€λŠ₯
  • where ν‚€μ›Œλ“œλ‘œ μ‹œμž‘
  • μ—°κ΄€λœ νƒ€μž… λ˜λŠ” νƒ€μž…κ³Ό μ—°κ΄€λœ νƒ€μž… κ°„μ˜ λ™λ“±ν•œ 관계에 λŒ€ν•œ μ œμ•½μ‚¬ν•­μ΄ 뒀따름
  • μ œλ„€λ¦­ whereμ ˆμ„ νƒ€μž…μ΄λ‚˜ ν•¨μˆ˜μ˜ 본문의 μ—΄λ¦° μ€‘κ΄„ν˜Έ({}) λ°”λ‘œ μ•žμ— μž‘μ„±
extension Array where Element: FixedWidthInteger {
    mutating func pop() -> Element { return self.removeLast() }
}
λ°˜μ‘ν˜•