Bibi's DevLog πŸ€“πŸŽ

[Swift] type(of:) λ³Έλ¬Έ

πŸ“±πŸŽ iOS/🍏 Apple Developer Documentation

[Swift] type(of:)

λΉ„λΉ„ bibi 2022. 9. 28. 21:52

Apple Developer Documentation

type(of:)

κ°’μ˜ λ‹€μ΄λ‚˜λ―Ή νƒ€μž…μ„ λ°˜ν™˜ν•©λ‹ˆλ‹€.

μ„ μ–Έ

func type<T, Metatype>(of value: T) -> Metatype

λ°˜ν™˜κ°’

동적 νƒ€μž… (= λ©”νƒ€νƒ€μž…metatype μΈμŠ€ν„΄μŠ€)

νŒŒλΌλ―Έν„°

  • value: 동적 νƒ€μž…μ„ 찾으렀 ν•˜λŠ” κ°’

μ„€λͺ…

이 type(of:) ν•¨μˆ˜λŠ” κ°’μ˜ 동적 νƒ€μž…μ„ μ°ΎκΈ° μœ„ν•΄ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 특히 동적 νƒ€μž…μ΄ 정적 νƒ€μž…κ³Ό λ‹€λ₯Ό λ•Œ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€. κ°’μ˜ 정적 νƒ€μž…(static type) 은 κ°’μ˜ λͺ…μ‹œλœ, 컴파일 μ‹œμ μ˜ νƒ€μž…μ„ λ§ν•©λ‹ˆλ‹€. κ°’μ˜ 동적 νƒ€μž…(dynamic) 은 μ‹€ν–‰ μ‹œμ μ˜ κ°’μ˜ μ‹€μ œ νƒ€μž…μ„ λ§ν•˜λ©°, κ°’μ˜ ꡬ체 νƒ€μž…μ˜ ν•˜μœ„ νƒ€μž…μ΄ 될 수 μžˆμŠ΅λ‹ˆλ‹€.

μ•„λž˜ μ½”λ“œμ—μ„œ, count λ³€μˆ˜λŠ” IntλΌλŠ” λ™μΌν•œ 정적 νƒ€μž…κ³Ό 동적 νƒ€μž…μ„ 가지고 μžˆμŠ΅λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜, countκ°€ printInfo(_:) ν•¨μˆ˜λ‘œ μ „λ‹¬λ˜λ©΄, value νŒŒλΌλ―Έν„°λŠ” Any(νŒŒλΌλ―Έν„°μ— μ •μ˜λœ νƒ€μž…)λΌλŠ” 정적 νƒ€μž…κ³Ό IntλΌλŠ” 동적 νƒ€μž…μ„ κ°€μ§€κ²Œ λ©λ‹ˆλ‹€.

func printInfo(_ value: Any) {
    let t = type(of: value)
    print("'\(value)' of type '\(t)'")
}

let count: Int = 5
printInfo(count)
// '5' of type 'Int'

type(of:) λ©”μ„œλ“œλ‘œλΆ€ν„° λ°˜ν™˜λœ 동적 νƒ€μž…μ€, 클래슀, ꡬ쑰체, enum, λΉ„ν”„λ‘œν† μ½œ νƒ€μž… T에 λŒ€ν•΄μ„œλŠ” ꡬ체 λ©”νƒ€νƒ€μž…(T.Type)이며, ν”„λ‘œν† μ½œ λ˜λŠ” ν”„λ‘œν† μ½œ κ΅¬ν˜„ P에 λŒ€ν•΄μ„œλŠ” μ‹€μ‘΄ λ©”νƒ€νƒ€μž…(P.Type)μž…λ‹ˆλ‹€. λ§Œμ•½ type(of:) 둜 μ „λ‹¬λœ κ°’μ˜ 정적 νƒ€μž…μ΄ ν΄λž˜μŠ€λ‚˜ ν”„λ‘œν† μ½œλ‘œ μ œν•œλ˜μ–΄ μžˆλ‹€λ©΄, κ·Έ 클래슀 λ˜λŠ” ν”„λ‘œν† μ½œμ˜ μ΄λ‹ˆμ…œλΌμ΄μ €λ‚˜ λ‹€λ₯Έ static(정적) member듀에 μ ‘κ·Όν•˜κΈ° μœ„ν•΄ κ·Έ λ©”νƒ€νƒ€μž…μ„ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

예λ₯Ό λ“€μ–΄, μ•„λž˜ μ˜ˆμ‹œμ—μ„œ printSmileyInfo(_:)ν•¨μˆ˜μ— κ°’μœΌλ‘œμ„œ μ „λ‹¬λœ νŒŒλΌλ―Έν„°λŠ” Smiley 클래슀의 μΈμŠ€ν„΄μŠ€ λ˜λŠ” Smiley 의 μ„œλΈŒν΄λž˜μŠ€ 쀑 ν•˜λ‚˜μž…λ‹ˆλ‹€. 이 ν•¨μˆ˜λŠ” type(of:) λ₯Ό value 의 동적 νƒ€μž…μ„ μ°ΎκΈ° μœ„ν•΄ μ‚¬μš©ν•˜λ©°, μ—¬κΈ°μ„œ valueλŠ” Smiley.Type λ©”νƒ€νƒ€μž…μ˜ μΈμŠ€ν„΄μŠ€μž…λ‹ˆλ‹€.

class Smiley {
    class var text: String {
        return ":)"
    }
}

class EmojiSmiley: Smiley {
     override class var text: String {
        return "πŸ˜€"
    }
}

func printSmileyInfo(_ value: Smiley) {
    let smileyType = type(of: value)
    print("Smile!", smileyType.text)
}

let emojiSmiley = EmojiSmiley()
printSmileyInfo(emojiSmiley)
// Smile! πŸ˜€

이 μ˜ˆμ‹œμ—μ„œ, smileyType λ©”νƒ€νƒ€μž…μ˜ text ν”„λ‘œνΌν‹°μ— μ ‘κ·Όν•˜λ©΄, Smiley클래슀의 μ›λž˜ μ •μ˜ λŒ€μ‹  EmojiSmiley μ„œλΈŒν΄λž˜μŠ€λ‘œλΆ€ν„° override된 값을 κ²€μƒ‰ν•˜κ²Œ λ©λ‹ˆλ‹€.

μ œλ„€λ¦­ λ§₯λ½μ—μ„œ 동적 νƒ€μž… μ°ΎκΈ°

일반적으둜, ꡬ체 λ©”νƒ€νƒ€μž…κ³Ό μ‹€μ‘΄ λ©”νƒ€νƒ€μž… μ‚¬μ΄μ˜ 차이점에 λŒ€ν•΄ μ•Œ ν•„μš”λŠ” μ—†μŠ΅λ‹ˆλ‹€. ν•˜μ§€λ§Œ type(of:) λ₯Ό ν˜ΈμΆœν•˜λŠ” 것은 ν”„λ‘œν† μ½œμ— λ°”μΈλ”©λœ νƒ€μž… νŒŒλΌλ―Έν„°κ°€ μžˆλŠ” μ œλ„€λ¦­ λ§₯λ½μ—μ„œ μ˜ˆμƒμΉ˜ λͺ»ν•œ κ²°κ³Όκ°€ λ°œμƒν•  수 μžˆμŠ΅λ‹ˆλ‹€. μ œλ„€λ¦­ νŒŒλΌλ―Έν„° Tκ°€ ν”„λ‘œν† μ½œ P에 λ°”μΈλ”©λ˜μ–΄ μžˆλŠ” 경우, νƒ€μž… νŒŒλΌλ―Έν„°λŠ” μ œλ„€λ¦­ ν•¨μˆ˜μ˜ body λ‚΄μ—μ„œ ν”„λ‘œν† μ½œ νƒ€μž…μž„μ΄ μ •μ μœΌλ‘œ μ•Œλ €μ Έ μžˆμ§€ μ•ŠμŠ΅λ‹ˆλ‹€. κ·Έ κ²°κ³Ό, type(of:) λŠ” ꡬ체 λ©”νƒ€νƒ€μž…μΈ P.Protocol λ§Œμ„ λ°˜ν™˜ν•˜κ²Œ λ©λ‹ˆλ‹€.

μ•„λž˜ μ˜ˆμ‹œλŠ” printGenericInfo(_:) ν•¨μˆ˜λ₯Ό μ •μ˜ν•©λ‹ˆλ‹€. 이 ν•¨μˆ˜λŠ” μ œλ„€λ¦­ νŒŒλΌλ―Έν„°λ₯Ό λ°›κ³  μƒˆ ν”„λ‘œν† μ½œ P 에 λŒ€ν•΄ String νƒ€μž… 적합성을 μ„ μ–Έν•©λ‹ˆλ‹€. PλΌλŠ” 정적 νƒ€μž…μ˜ λ¬Έμžμ—΄λ‘œ printGenericInfo(_:)ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λ©΄, type(of:) 의 호좜 κ²°κ³ΌλŠ” String.self λŒ€μ‹  P.self κ°€ λ©λ‹ˆλ‹€ (즉 νŒŒλΌλ―Έν„° λ‚΄λΆ€μ˜ 동적 νƒ€μž…).

func printGenericInfo<T>(_ value: T) {
    let t = type(of: value)
    print("'\(value)' of type '\(t)'")
}

protocol P {}
extension String: P {}

let stringAsP: P = "Hello!"
printGenericInfo(stringAsP)
// 'Hello!' of type 'P'

이 μ˜ˆμƒμΉ˜ λͺ»ν•œ κ²°κ³ΌλŠ” λ‹€μŒκ³Ό 같은 이유 λ•Œλ¬Έμ— λ°œμƒν•©λ‹ˆλ‹€. printGenericInfo(_:) λ‚΄λΆ€μ˜ type(of: value) ν˜ΈμΆœμ€ T.Type 의 μΈμŠ€ν„΄μŠ€μΈ λ©”νƒ€νƒ€μž…μ„ λ°˜ν™˜ν•΄μ•Ό ν•˜λŠ”λ°, String.self (κΈ°λŒ€λ˜λŠ” 동적 νƒ€μž…)λŠ” P.Type (value의 ꡬ체 λ©”νƒ€νƒ€μž…)의 μΈμŠ€ν„΄μŠ€κ°€ μ•„λ‹™λ‹ˆλ‹€. 이 μ œλ„€λ¦­ λ§₯λ½μ—μ„œ value λ‚΄λΆ€μ˜ 동적 νƒ€μž…μ„ μ–»κΈ° μœ„ν•΄μ„œλŠ”, type(of:) 을 ν˜ΈμΆœν•  λ•Œ νŒŒλΌλ―Έν„°λ₯Ό Anyνƒ€μž…μœΌλ‘œ λ³€ν™˜ν•΄μ•Ό ν•©λ‹ˆλ‹€.

func betterPrintGenericInfo<T>(_ value: T) {
    let t = type(of: value as Any)
    print("'\(value)' of type '\(t)'")
}

betterPrintGenericInfo(stringAsP)
// 'Hello!' of type 'String'