์ฝ˜ํ…์ธ  ๋Œ€ํ‘œ ์ด๋ฏธ์ง€ - ๐Ÿ” ์Šค์œ„ํ”„ํŠธ ๋ฆฌํ”Œ๋ ‰์…˜๊ณผ Mirror๋ฅผ ํ™œ์šฉํ•œ ๋Ÿฐํƒ€์ž„ ํƒ€์ž… ๊ฒ€์‚ฌ ์™„์ „ ์ •๋ณต

๐Ÿ” ์Šค์œ„ํ”„ํŠธ ๋ฆฌํ”Œ๋ ‰์…˜๊ณผ Mirror๋ฅผ ํ™œ์šฉํ•œ ๋Ÿฐํƒ€์ž„ ํƒ€์ž… ๊ฒ€์‚ฌ ์™„์ „ ์ •๋ณต

๋Ÿฐํƒ€์ž„์— ํƒ€์ž…์„ ๋“ค์—ฌ๋‹ค๋ณด๋Š” ๋งˆ๋ฒ• ๊ฐ™์€ ๊ธฐ์ˆ , ์ง€๊ธˆ ๋ฐ”๋กœ ์‹œ์ž‘ํ•ด๋ณผ๊นŒ์š”? โœจ

๐ŸŽฏ ์•ˆ๋…•ํ•˜์„ธ์š”! ์˜ค๋Š˜์€ Swift์˜ ์ˆจ๊ฒจ์ง„ ๋ณด์„ ๊ฐ™์€ ๊ธฐ๋Šฅ, ๋ฆฌํ”Œ๋ ‰์…˜(Reflection)๊ณผ Mirror์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•ด๋ณผ ๊ฑฐ์˜ˆ์š”.

ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ํ•˜๋‹ค ๋ณด๋ฉด "์ด ๋ณ€์ˆ˜๊ฐ€ ๋Ÿฐํƒ€์ž„์— ์ •ํ™•ํžˆ ์–ด๋–ค ํƒ€์ž…์ด์ง€?", "์ด ๊ฐ์ฒด ์•ˆ์— ์–ด๋–ค ํ”„๋กœํผํ‹ฐ๋“ค์ด ๋“ค์–ด์žˆ์ง€?" ๊ฐ™์€ ๊ถ๊ธˆ์ฆ์ด ์ƒ๊ธธ ๋•Œ๊ฐ€ ์žˆ์ฃ . ์ปดํŒŒ์ผ ํƒ€์ž„์—๋Š” ๋ชจ๋“  ๊ฒŒ ๋ช…ํ™•ํ•˜์ง€๋งŒ, ์‹ค์ œ๋กœ ์•ฑ์ด ๋Œ์•„๊ฐ€๋Š” ์ˆœ๊ฐ„์—๋Š” ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ์ƒํ™ฉ๋“ค์ด ๋ฐœ์ƒํ•˜๊ธฐ๋„ ํ•˜๊ณ ์š”. ๐Ÿค”

๋ฐ”๋กœ ์ด๋Ÿด ๋•Œ ํ•„์š”ํ•œ ๊ฒŒ ๋ฆฌํ”Œ๋ ‰์…˜์ด์—์š”! ๋งˆ์น˜ ๊ฑฐ์šธ(Mirror)๋กœ ์ž์‹ ์„ ๋น„์ถฐ๋ณด๋“ฏ, ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋˜๋Š” ๋™์•ˆ ๊ฐ์ฒด์˜ ๋‚ด๋ถ€ ๊ตฌ์กฐ๋ฅผ ๋“ค์—ฌ๋‹ค๋ณผ ์ˆ˜ ์žˆ๋Š” ๊ฐ•๋ ฅํ•œ ๋„๊ตฌ๋ž๋‹ˆ๋‹ค.

๐ŸŽช ๋ฆฌํ”Œ๋ ‰์…˜์ด๋ž€ ๋ฌด์—‡์ธ๊ฐ€์š”?

๋ฆฌํ”Œ๋ ‰์…˜(Reflection)์€ ํ”„๋กœ๊ทธ๋žจ์ด ์‹คํ–‰ ์ค‘์— ์ž๊ธฐ ์ž์‹ ์˜ ๊ตฌ์กฐ๋ฅผ ๊ฒ€์‚ฌํ•˜๊ณ  ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋Š” ๋Šฅ๋ ฅ์„ ๋งํ•ด์š”. ์‰ฝ๊ฒŒ ๋งํ•˜๋ฉด, ์ฝ”๋“œ๊ฐ€ "์ž๊ธฐ ์ž์‹ ์„ ๊ฑฐ์šธ๋กœ ๋น„์ถฐ๋ณด๋Š” ๊ฒƒ"์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋ผ์š”. ๐Ÿชž

๋‹ค๋ฅธ ์–ธ์–ด๋“ค(Java, Python, C# ๋“ฑ)์—์„œ๋Š” ์ด๋ฏธ ์˜ค๋ž˜์ „๋ถ€ํ„ฐ ๋ฆฌํ”Œ๋ ‰์…˜์„ ๊ฐ•๋ ฅํ•˜๊ฒŒ ์ง€์›ํ•ด์™”๋Š”๋ฐ, Swift๋„ Mirror๋ผ๋Š” ๊ตฌ์กฐ์ฒด๋ฅผ ํ†ตํ•ด ๋ฆฌํ”Œ๋ ‰์…˜ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๊ณ  ์žˆ์–ด์š”.

๐Ÿ’ก ๋ฆฌํ”Œ๋ ‰์…˜์œผ๋กœ ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ๋“ค

โœ… ๊ฐ์ฒด์˜ ํƒ€์ž… ์ •๋ณด๋ฅผ ๋Ÿฐํƒ€์ž„์— ํ™•์ธ
โœ… ๊ฐ์ฒด๊ฐ€ ๊ฐ€์ง„ ํ”„๋กœํผํ‹ฐ ๋ชฉ๋ก๊ณผ ๊ฐ’ ์กฐํšŒ
โœ… ๊ฐ์ฒด์˜ ๊ตฌ์กฐ๋ฅผ ๋™์ ์œผ๋กœ ํƒ์ƒ‰
โœ… ๋””๋ฒ„๊น…๊ณผ ๋กœ๊น…์— ํ™œ์šฉ
โœ… JSON ์ง๋ ฌํ™”/์—ญ์ง๋ ฌํ™” ๊ตฌํ˜„
โœ… ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ ์‹œ ๊ฐ์ฒด ๊ฒ€์ฆ

๐Ÿ”ฎ Mirror์˜ ๊ธฐ๋ณธ ๊ฐœ๋…

Swift์—์„œ ๋ฆฌํ”Œ๋ ‰์…˜์˜ ํ•ต์‹ฌ์€ ๋ฐ”๋กœ Mirror ๊ตฌ์กฐ์ฒด์˜ˆ์š”. Mirror๋Š” ๋ง ๊ทธ๋Œ€๋กœ "๊ฑฐ์šธ"์ฒ˜๋Ÿผ ์–ด๋–ค ์ธ์Šคํ„ด์Šค์˜ ๋‚ด๋ถ€ ๊ตฌ์กฐ๋ฅผ ๋น„์ถฐ์ฃผ๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

Mirror๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์ •๋ง ๊ฐ„๋‹จํ•ด์š”:

let person = Person(name: "๊น€์ฒ ์ˆ˜", age: 28)
let mirror = Mirror(reflecting: person)

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด person ๊ฐ์ฒด์˜ ๋‚ด๋ถ€๋ฅผ ๋“ค์—ฌ๋‹ค๋ณผ ์ˆ˜ ์žˆ๋Š” ๊ฑฐ์šธ์ด ๋งŒ๋“ค์–ด์ง€๋Š” ๊ฑฐ์ฃ ! ๐ŸŽ‰

์›๋ณธ ๊ฐ์ฒด Person name: "๊น€์ฒ ์ˆ˜" age: 28 email: "test@example.com" Mirror ๐Ÿชž ๋ฆฌํ”Œ๋ ‰์…˜ ๊ฒฐ๊ณผ ํ”„๋กœํผํ‹ฐ ๊ฐœ์ˆ˜: 3๊ฐœ ํƒ€์ž…: Person โœ“ name (String) โœ“ age (Int) โœ“ email (String)

๐Ÿ› ๏ธ Mirror์˜ ์ฃผ์š” ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ

Mirror ๊ตฌ์กฐ์ฒด๋Š” ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์œ ์šฉํ•œ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ œ๊ณตํ•ด์š”. ํ•˜๋‚˜์”ฉ ์‚ดํŽด๋ณผ๊นŒ์š”?

ํ”„๋กœํผํ‹ฐ/๋ฉ”์„œ๋“œ ์„ค๋ช… ๋ฐ˜ํ™˜ ํƒ€์ž…
children ๊ฐ์ฒด์˜ ๋ชจ๋“  ์ž์‹ ์š”์†Œ(ํ”„๋กœํผํ‹ฐ) ์ปฌ๋ ‰์…˜ Children
displayStyle ๊ฐ์ฒด์˜ ํ‘œ์‹œ ์Šคํƒ€์ผ (struct, class, enum ๋“ฑ) DisplayStyle?
subjectType ๋ฐ˜์˜๋˜๋Š” ๊ฐ์ฒด์˜ ํƒ€์ž… Any.Type
superclassMirror ๋ถ€๋ชจ ํด๋ž˜์Šค์˜ Mirror (์žˆ์„ ๊ฒฝ์šฐ) Mirror?

๐Ÿ“ฆ children ํ”„๋กœํผํ‹ฐ ํ™œ์šฉํ•˜๊ธฐ

๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ๊ฑด ๋ฐ”๋กœ children ํ”„๋กœํผํ‹ฐ์˜ˆ์š”. ์ด๊ฑธ ํ†ตํ•ด ๊ฐ์ฒด์˜ ๋ชจ๋“  ํ”„๋กœํผํ‹ฐ๋ฅผ ์ˆœํšŒํ•  ์ˆ˜ ์žˆ์–ด์š”:

struct Person {
    let name: String
    let age: Int
    let email: String
}

let person = Person(name: "๊น€์ฒ ์ˆ˜", age: 28, email: "chulsoo@example.com")
let mirror = Mirror(reflecting: person)

for child in mirror.children {
    if let label = child.label {
        print("\(label): \(child.value)")
    }
}

// ์ถœ๋ ฅ:
// name: ๊น€์ฒ ์ˆ˜
// age: 28
// email: chulsoo@example.com
๐Ÿ’ก ํŒ: child.label์€ ์˜ต์…”๋„์ด์—์š”! ํŠœํ”Œ์ด๋‚˜ ๋ฐฐ์—ด ๊ฐ™์€ ๊ฒฝ์šฐ ๋ ˆ์ด๋ธ”์ด ์—†์„ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด์ฃ . ํ•ญ์ƒ ์˜ต์…”๋„ ๋ฐ”์ธ๋”ฉ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒŒ ์•ˆ์ „ํ•ด์š”.

๐ŸŽฏ ์‹ค์ „ ํ™œ์šฉ ์˜ˆ์ œ

1๏ธโƒฃ ๋””๋ฒ„๊น…์šฉ ์„ค๋ช… ๋ฌธ์ž์—ด ์ƒ์„ฑํ•˜๊ธฐ

๊ฐ์ฒด์˜ ๋ชจ๋“  ํ”„๋กœํผํ‹ฐ๋ฅผ ๋ณด๊ธฐ ์ข‹๊ฒŒ ์ถœ๋ ฅํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด๋ณผ๊นŒ์š”? ๋””๋ฒ„๊น…ํ•  ๋•Œ ์ •๋ง ์œ ์šฉํ•˜๋‹ต๋‹ˆ๋‹ค! ๐Ÿ›

func describe(_ object: Any) -> String {
    let mirror = Mirror(reflecting: object)
    var description = "\(mirror.subjectType) {\n"
    
    for child in mirror.children {
        if let label = child.label {
            description += "  \(label): \(child.value)\n"
        }
    }
    
    description += "}"
    return description
}

// ์‚ฌ์šฉ ์˜ˆ์‹œ
struct Book {
    let title: String
    let author: String
    let pages: Int
    let isAvailable: Bool
}

let book = Book(
    title: "์Šค์œ„ํ”„ํŠธ ๋งˆ์Šคํ„ฐํ•˜๊ธฐ",
    author: "๋ฐ•๊ฐœ๋ฐœ",
    pages: 450,
    isAvailable: true
)

print(describe(book))

// ์ถœ๋ ฅ:
// Book {
//   title: ์Šค์œ„ํ”„ํŠธ ๋งˆ์Šคํ„ฐํ•˜๊ธฐ
//   author: ๋ฐ•๊ฐœ๋ฐœ
//   pages: 450
//   isAvailable: true
// }

2๏ธโƒฃ ๋”•์…”๋„ˆ๋ฆฌ๋กœ ๋ณ€ํ™˜ํ•˜๊ธฐ

๊ฐ์ฒด๋ฅผ ๋”•์…”๋„ˆ๋ฆฌ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๊ฒƒ๋„ ์ž์ฃผ ์“ฐ์ด๋Š” ํŒจํ„ด์ด์—์š”. JSON ์ง๋ ฌํ™”๋‚˜ ๋กœ๊น…์— ์œ ์šฉํ•˜์ฃ :

func toDictionary(_ object: Any) -> [String: Any] {
    let mirror = Mirror(reflecting: object)
    var dictionary: [String: Any] = [:]
    
    for child in mirror.children {
        if let label = child.label {
            dictionary[label] = child.value
        }
    }
    
    return dictionary
}

// ์‚ฌ์šฉ ์˜ˆ์‹œ
struct Product {
    let id: Int
    let name: String
    let price: Double
    let inStock: Bool
}

let product = Product(id: 101, name: "๋งฅ๋ถ ํ”„๋กœ", price: 2500000, inStock: true)
let dict = toDictionary(product)

print(dict)
// ["id": 101, "name": "๋งฅ๋ถ ํ”„๋กœ", "price": 2500000.0, "inStock": true]

3๏ธโƒฃ ํƒ€์ž… ๊ฒ€์‚ฌ ๋ฐ ํ•„ํ„ฐ๋ง

ํŠน์ • ํƒ€์ž…์˜ ํ”„๋กœํผํ‹ฐ๋งŒ ์ฐพ์•„๋‚ด๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•ด์š”:

func findProperties<T>(of type: T.Type, in object: Any) -> [String: T] {
    let mirror = Mirror(reflecting: object)
    var result: [String: T] = [:]
    
    for child in mirror.children {
        if let label = child.label,
           let value = child.value as? T {
            result[label] = value
        }
    }
    
    return result
}

// ์‚ฌ์šฉ ์˜ˆ์‹œ
struct UserProfile {
    let username: String
    let age: Int
    let email: String
    let score: Int
    let bio: String
}

let profile = UserProfile(
    username: "swiftmaster",
    age: 25,
    email: "master@swift.com",
    score: 9500,
    bio: "Swift ๊ฐœ๋ฐœ์ž์ž…๋‹ˆ๋‹ค"
)

// String ํƒ€์ž… ํ”„๋กœํผํ‹ฐ๋งŒ ์ฐพ๊ธฐ
let stringProps = findProperties(of: String.self, in: profile)
print(stringProps)
// ["username": "swiftmaster", "email": "master@swift.com", "bio": "Swift ๊ฐœ๋ฐœ์ž์ž…๋‹ˆ๋‹ค"]

// Int ํƒ€์ž… ํ”„๋กœํผํ‹ฐ๋งŒ ์ฐพ๊ธฐ
let intProps = findProperties(of: Int.self, in: profile)
print(intProps)
// ["age": 25, "score": 9500]
โœจ ์žฌ๋Šฅ๋„ท ํ™œ์šฉ ํŒ: ์ด๋Ÿฐ ๋ฆฌํ”Œ๋ ‰์…˜ ๊ธฐ์ˆ ์€ ์žฌ๋Šฅ๋„ท(https://www.jaenung.net)์—์„œ Swift ๊ฐœ๋ฐœ ์žฌ๋Šฅ์„ ๊ณต์œ ํ•˜๊ฑฐ๋‚˜ ๋ฐฐ์šธ ๋•Œ ์ •๋ง ์œ ์šฉํ•ด์š”! ํŠนํžˆ ๊ณ ๊ธ‰ Swift ๊ธฐ๋ฒ•์„ ๋‹ค๋ฃจ๋Š” ๊ฐ•์˜๋‚˜ ๋ฉ˜ํ† ๋ง์—์„œ ์ž์ฃผ ๋‹ค๋ค„์ง€๋Š” ์ฃผ์ œ๋ž๋‹ˆ๋‹ค.

๐Ÿ” DisplayStyle๋กœ ํƒ€์ž… ๊ตฌ๋ถ„ํ•˜๊ธฐ

displayStyle ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ์ฒด๊ฐ€ struct์ธ์ง€, class์ธ์ง€, enum์ธ์ง€ ๋“ฑ์„ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ์–ด์š”:

func getTypeDescription(_ object: Any) -> String {
    let mirror = Mirror(reflecting: object)
    
    guard let displayStyle = mirror.displayStyle else {
        return "์•Œ ์ˆ˜ ์—†๋Š” ํƒ€์ž…"
    }
    
    switch displayStyle {
    case .struct:
        return "๊ตฌ์กฐ์ฒด (Struct)"
    case .class:
        return "ํด๋ž˜์Šค (Class)"
    case .enum:
        return "์—ด๊ฑฐํ˜• (Enum)"
    case .tuple:
        return "ํŠœํ”Œ (Tuple)"
    case .optional:
        return "์˜ต์…”๋„ (Optional)"
    case .collection:
        return "์ปฌ๋ ‰์…˜ (Collection)"
    case .dictionary:
        return "๋”•์…”๋„ˆ๋ฆฌ (Dictionary)"
    case .set:
        return "์ง‘ํ•ฉ (Set)"
    @unknown default:
        return "๊ธฐํƒ€ ํƒ€์ž…"
    }
}

// ํ…Œ์ŠคํŠธ
struct MyStruct { let value: Int }
class MyClass { let value: Int; init(value: Int) { self.value = value } }
enum MyEnum { case first, second }

print(getTypeDescription(MyStruct(value: 10)))  // ๊ตฌ์กฐ์ฒด (Struct)
print(getTypeDescription(MyClass(value: 20)))   // ํด๋ž˜์Šค (Class)
print(getTypeDescription(MyEnum.first))         // ์—ด๊ฑฐํ˜• (Enum)
print(getTypeDescription([1, 2, 3]))            // ์ปฌ๋ ‰์…˜ (Collection)
print(getTypeDescription(["key": "value"]))     // ๋”•์…”๋„ˆ๋ฆฌ (Dictionary)

๐ŸŒณ ์ƒ์† ๊ตฌ์กฐ ํƒ์ƒ‰ํ•˜๊ธฐ

ํด๋ž˜์Šค์˜ ์ƒ์† ๊ตฌ์กฐ๋„ Mirror๋ฅผ ํ†ตํ•ด ํƒ์ƒ‰ํ•  ์ˆ˜ ์žˆ์–ด์š”. superclassMirror ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ผ์š”:

class Animal {
    let species: String
    init(species: String) {
        self.species = species
    }
}

class Dog: Animal {
    let breed: String
    init(breed: String) {
        self.breed = breed
        super.init(species: "๊ฐœ")
    }
}

class Poodle: Dog {
    let color: String
    init(color: String) {
        self.color = color
        super.init(breed: "ํ‘ธ๋“ค")
    }
}

func printInheritanceChain(_ object: Any) {
    var mirror: Mirror? = Mirror(reflecting: object)
    var level = 0
    
    while let currentMirror = mirror {
        let indent = String(repeating: "  ", count: level)
        print("\(indent)๐Ÿ“ฆ \(currentMirror.subjectType)")
        
        for child in currentMirror.children {
            if let label = child.label {
                print("\(indent)  โ”œโ”€ \(label): \(child.value)")
            }
        }
        
        mirror = currentMirror.superclassMirror
        level += 1
    }
}

let myPoodle = Poodle(color: "ํฐ์ƒ‰")
printInheritanceChain(myPoodle)

// ์ถœ๋ ฅ:
// ๐Ÿ“ฆ Poodle
//   โ”œโ”€ color: ํฐ์ƒ‰
//   ๐Ÿ“ฆ Dog
//     โ”œโ”€ breed: ํ‘ธ๋“ค
//     ๐Ÿ“ฆ Animal
//       โ”œโ”€ species: ๊ฐœ
์ƒ์† ๊ตฌ์กฐ ํƒ์ƒ‰ Animal (๋ถ€๋ชจ) species: String ๐Ÿพ ์ตœ์ƒ์œ„ ํด๋ž˜์Šค Dog (์ž์‹) breed: String ๐Ÿ• Animal ์ƒ์† Poodle (์†์ž) color: String ๐Ÿฉ Dog ์ƒ์† Mirror ํƒ์ƒ‰ ์ˆœ์„œ 1 Poodle ํ”„๋กœํผํ‹ฐ 2 Dog ํ”„๋กœํผํ‹ฐ 3 Animal ํ”„๋กœํผํ‹ฐ โœจ ํƒ์ƒ‰ ๊ฒฐ๊ณผ color: "ํฐ์ƒ‰" breed: "ํ‘ธ๋“ค" species: "๊ฐœ"

โš ๏ธ Mirror์˜ ํ•œ๊ณ„์™€ ์ฃผ์˜์‚ฌํ•ญ

Mirror๋Š” ๊ฐ•๋ ฅํ•˜์ง€๋งŒ, ๋ช‡ ๊ฐ€์ง€ ์ œ์•ฝ์‚ฌํ•ญ์ด ์žˆ์–ด์š”. ์•Œ์•„๋‘๋ฉด ์ข‹์„ ๊ฒƒ๋“ค์„ ์ •๋ฆฌํ•ด๋ณผ๊ฒŒ์š”:

๐Ÿšจ ์ฃผ์˜ํ•ด์•ผ ํ•  ์ ๋“ค

1. ์„ฑ๋Šฅ ์˜ค๋ฒ„ํ—ค๋“œ
๋ฆฌํ”Œ๋ ‰์…˜์€ ๋Ÿฐํƒ€์ž„์— ๋™์ž‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ปดํŒŒ์ผ ํƒ€์ž„ ์ตœ์ ํ™”๋ฅผ ๋ฐ›์„ ์ˆ˜ ์—†์–ด์š”. ๋”ฐ๋ผ์„œ ์„ฑ๋Šฅ์ด ์ค‘์š”ํ•œ ๋ฃจํ”„ ์•ˆ์—์„œ๋Š” ์‚ฌ์šฉ์„ ์ž์ œํ•˜๋Š” ๊ฒŒ ์ข‹์•„์š”.

2. ์ฝ๊ธฐ ์ „์šฉ
Mirror๋Š” ๊ฐ’์„ ์ฝ์„ ์ˆ˜๋งŒ ์žˆ๊ณ , ์ˆ˜์ •ํ•  ์ˆ˜๋Š” ์—†์–ด์š”. ํ”„๋กœํผํ‹ฐ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋ ค๋ฉด ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•ด์•ผ ํ•ด์š”.

3. private ํ”„๋กœํผํ‹ฐ ์ ‘๊ทผ ๋ถˆ๊ฐ€
private์œผ๋กœ ์„ ์–ธ๋œ ํ”„๋กœํผํ‹ฐ๋Š” Mirror๋กœ๋„ ์ ‘๊ทผํ•  ์ˆ˜ ์—†์–ด์š”. Swift์˜ ์ ‘๊ทผ ์ œ์–ด๋Š” ๋ฆฌํ”Œ๋ ‰์…˜์—๋„ ์ ์šฉ๋œ๋‹ต๋‹ˆ๋‹ค.

4. ํƒ€์ž… ์ •๋ณด ์ œํ•œ
์ œ๋„ค๋ฆญ ํƒ€์ž…์˜ ๊ตฌ์ฒด์ ์ธ ํƒ€์ž… ํŒŒ๋ผ๋ฏธํ„ฐ ์ •๋ณด๋Š” ์–ป๊ธฐ ์–ด๋ ค์›Œ์š”.

5. ๊ณ„์‚ฐ ํ”„๋กœํผํ‹ฐ๋Š” ํฌํ•จ ์•ˆ ๋จ
์ €์žฅ ํ”„๋กœํผํ‹ฐ๋งŒ Mirror์— ๋‚˜ํƒ€๋‚˜๊ณ , ๊ณ„์‚ฐ ํ”„๋กœํผํ‹ฐ๋Š” ๋ณด์ด์ง€ ์•Š์•„์š”.

๐Ÿ”’ private ํ”„๋กœํผํ‹ฐ ์˜ˆ์ œ

struct SecureData {
    let publicInfo: String
    private let secretKey: String
    
    init(publicInfo: String, secretKey: String) {
        self.publicInfo = publicInfo
        self.secretKey = secretKey
    }
}

let data = SecureData(publicInfo: "๊ณต๊ฐœ ์ •๋ณด", secretKey: "๋น„๋ฐ€ํ‚ค123")
let mirror = Mirror(reflecting: data)

for child in mirror.children {
    if let label = child.label {
        print("\(label): \(child.value)")
    }
}

// ์ถœ๋ ฅ:
// publicInfo: ๊ณต๊ฐœ ์ •๋ณด
// secretKey: ๋น„๋ฐ€ํ‚ค123

// โš ๏ธ ์ฃผ์˜: private์ด์–ด๋„ Mirror๋กœ๋Š” ๋ณผ ์ˆ˜ ์žˆ์–ด์š”!
// ํ•˜์ง€๋งŒ ์ง์ ‘ ์ ‘๊ทผ์€ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค: data.secretKey // ์ปดํŒŒ์ผ ์—๋Ÿฌ
๐Ÿ’ก ํฅ๋ฏธ๋กœ์šด ์‚ฌ์‹ค: private ํ”„๋กœํผํ‹ฐ๋„ Mirror์—๋Š” ๋‚˜ํƒ€๋‚˜์š”! ํ•˜์ง€๋งŒ ์ด๊ฑด ๋ณด์•ˆ ์ทจ์•ฝ์ ์ด ์•„๋‹ˆ๋ผ, ๋””๋ฒ„๊น…๊ณผ ๊ฐœ๋ฐœ์„ ๋•๊ธฐ ์œ„ํ•œ ์˜๋„๋œ ๋™์ž‘์ด์—์š”. ์‹ค์ œ ์ฝ”๋“œ์—์„œ๋Š” ์—ฌ์ „ํžˆ ์ ‘๊ทผ ์ œ์–ด๊ฐ€ ์ž‘๋™ํ•˜๋‹ˆ๊นŒ์š”.

๐ŸŽจ ๊ณ ๊ธ‰ ํ™œ์šฉ ํŒจํ„ด

1๏ธโƒฃ ์ปค์Šคํ…€ Mirror ๊ตฌํ˜„ํ•˜๊ธฐ

CustomReflectable ํ”„๋กœํ† ์ฝœ์„ ์ฑ„ํƒํ•˜๋ฉด Mirror๊ฐ€ ๋ณด์—ฌ์ฃผ๋Š” ๋‚ด์šฉ์„ ์ปค์Šคํ„ฐ๋งˆ์ด์ง•ํ•  ์ˆ˜ ์žˆ์–ด์š”:

struct BankAccount: CustomReflectable {
    let accountNumber: String
    private let balance: Double
    private let pin: String
    
    init(accountNumber: String, balance: Double, pin: String) {
        self.accountNumber = accountNumber
        self.balance = balance
        self.pin = pin
    }
    
    // ์ปค์Šคํ…€ Mirror ์ •์˜
    var customMirror: Mirror {
        return Mirror(
            self,
            children: [
                "accountNumber": accountNumber,
                "balance": "***์ˆจ๊น€***",  // ๋ฏผ๊ฐํ•œ ์ •๋ณด๋Š” ์ˆจ๊น€
                "pin": "****"              // PIN์€ ์ ˆ๋Œ€ ๋…ธ์ถœ ์•ˆ ํ•จ
            ],
            displayStyle: .struct
        )
    }
}

let account = BankAccount(
    accountNumber: "123-456-789",
    balance: 1000000,
    pin: "1234"
)

let mirror = Mirror(reflecting: account)
for child in mirror.children {
    if let label = child.label {
        print("\(label): \(child.value)")
    }
}

// ์ถœ๋ ฅ:
// accountNumber: 123-456-789
// balance: ***์ˆจ๊น€***
// pin: ****

2๏ธโƒฃ ์žฌ๊ท€์  ๊ฐ์ฒด ํƒ์ƒ‰

์ค‘์ฒฉ๋œ ๊ฐ์ฒด ๊ตฌ์กฐ๋ฅผ ์žฌ๊ท€์ ์œผ๋กœ ํƒ์ƒ‰ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด๋ณผ๊นŒ์š”:

func deepInspect(_ object: Any, indent: String = "") {
    let mirror = Mirror(reflecting: object)
    
    print("\(indent)๐Ÿ“ฆ ํƒ€์ž…: \(mirror.subjectType)")
    
    for child in mirror.children {
        let label = child.label ?? "unnamed"
        let value = child.value
        
        print("\(indent)โ”œโ”€ \(label):", terminator: " ")
        
        // ๊ธฐ๋ณธ ํƒ€์ž…์ด๋ฉด ๋ฐ”๋กœ ์ถœ๋ ฅ
        if let stringValue = value as? String {
            print("\"\(stringValue)\"")
        } else if let intValue = value as? Int {
            print(intValue)
        } else if let doubleValue = value as? Double {
            print(doubleValue)
        } else if let boolValue = value as? Bool {
            print(boolValue)
        } else {
            // ๋ณต์žกํ•œ ํƒ€์ž…์ด๋ฉด ์žฌ๊ท€ ํ˜ธ์ถœ
            print("")
            deepInspect(value, indent: indent + "  ")
        }
    }
}

// ํ…Œ์ŠคํŠธ์šฉ ์ค‘์ฒฉ ๊ตฌ์กฐ
struct Address {
    let street: String
    let city: String
    let zipCode: String
}

struct Company {
    let name: String
    let address: Address
}

struct Employee {
    let name: String
    let age: Int
    let company: Company
}

let employee = Employee(
    name: "์ด๊ฐœ๋ฐœ",
    age: 30,
    company: Company(
        name: "ํ…Œํฌ์Šคํƒ€ํŠธ์—…",
        address: Address(
            street: "ํ…Œํ—ค๋ž€๋กœ 123",
            city: "์„œ์šธ",
            zipCode: "06234"
        )
    )
)

deepInspect(employee)

// ์ถœ๋ ฅ:
// ๐Ÿ“ฆ ํƒ€์ž…: Employee
// โ”œโ”€ name: "์ด๊ฐœ๋ฐœ"
// โ”œโ”€ age: 30
// โ”œโ”€ company: 
//   ๐Ÿ“ฆ ํƒ€์ž…: Company
//   โ”œโ”€ name: "ํ…Œํฌ์Šคํƒ€ํŠธ์—…"
//   โ”œโ”€ address: 
//     ๐Ÿ“ฆ ํƒ€์ž…: Address
//     โ”œโ”€ street: "ํ…Œํ—ค๋ž€๋กœ 123"
//     โ”œโ”€ city: "์„œ์šธ"
//     โ”œโ”€ zipCode: "06234"

3๏ธโƒฃ ๊ฐ์ฒด ๋น„๊ต ์œ ํ‹ธ๋ฆฌํ‹ฐ

๋‘ ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ๋ฅผ ๋น„๊ตํ•ด์„œ ์ฐจ์ด์ ์„ ์ฐพ์•„๋‚ด๋Š” ํ•จ์ˆ˜๋„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด์š”:

func findDifferences(between obj1: Any, and obj2: Any) -> [String: (Any, Any)] {
    let mirror1 = Mirror(reflecting: obj1)
    let mirror2 = Mirror(reflecting: obj2)
    
    var differences: [String: (Any, Any)] = [:]
    
    // obj1์˜ ํ”„๋กœํผํ‹ฐ๋ฅผ ๋”•์…”๋„ˆ๋ฆฌ๋กœ ๋ณ€ํ™˜
    var props1: [String: Any] = [:]
    for child in mirror1.children {
        if let label = child.label {
            props1[label] = child.value
        }
    }
    
    // obj2์˜ ํ”„๋กœํผํ‹ฐ๋ฅผ ๋”•์…”๋„ˆ๋ฆฌ๋กœ ๋ณ€ํ™˜
    var props2: [String: Any] = [:]
    for child in mirror2.children {
        if let label = child.label {
            props2[label] = child.value
        }
    }
    
    // ์ฐจ์ด์  ์ฐพ๊ธฐ
    for (key, value1) in props1 {
        if let value2 = props2[key] {
            // ๊ฐ„๋‹จํ•œ ๋น„๊ต (์‹ค์ œ๋กœ๋Š” ๋” ์ •๊ตํ•œ ๋น„๊ต ํ•„์š”)
            if "\(value1)" != "\(value2)" {
                differences[key] = (value1, value2)
            }
        }
    }
    
    return differences
}

// ์‚ฌ์šฉ ์˜ˆ์‹œ
struct Config {
    let serverURL: String
    let timeout: Int
    let enableLogging: Bool
}

let oldConfig = Config(
    serverURL: "https://api.old.com",
    timeout: 30,
    enableLogging: false
)

let newConfig = Config(
    serverURL: "https://api.new.com",
    timeout: 60,
    enableLogging: true
)

let diffs = findDifferences(between: oldConfig, and: newConfig)

print("๐Ÿ” ๋ณ€๊ฒฝ๋œ ์„ค์ •:")
for (key, values) in diffs {
    print("  \(key): \(values.0) โ†’ \(values.1)")
}

// ์ถœ๋ ฅ:
// ๐Ÿ” ๋ณ€๊ฒฝ๋œ ์„ค์ •:
//   serverURL: https://api.old.com โ†’ https://api.new.com
//   timeout: 30 โ†’ 60
//   enableLogging: false โ†’ true

๐Ÿงช ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์—์„œ์˜ ํ™œ์šฉ

Mirror๋Š” ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑํ•  ๋•Œ๋„ ์ •๋ง ์œ ์šฉํ•ด์š”. ํŠนํžˆ ๊ฐ์ฒด์˜ ๋‚ด๋ถ€ ์ƒํƒœ๋ฅผ ๊ฒ€์ฆํ•  ๋•Œ ๋ง์ด์ฃ :

import XCTest

// ํ…Œ์ŠคํŠธ ํ—ฌํผ ํ•จ์ˆ˜
func assertHasProperty<T>(
    _ object: Any,
    named propertyName: String,
    ofType type: T.Type,
    withValue expectedValue: T,
    file: StaticString = #file,
    line: UInt = #line
) where T: Equatable {
    let mirror = Mirror(reflecting: object)
    
    for child in mirror.children {
        if let label = child.label, label == propertyName {
            if let actualValue = child.value as? T {
                XCTAssertEqual(
                    actualValue,
                    expectedValue,
                    "ํ”„๋กœํผํ‹ฐ '\(propertyName)'์˜ ๊ฐ’์ด ์˜ˆ์ƒ๊ณผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค",
                    file: file,
                    line: line
                )
                return
            } else {
                XCTFail(
                    "ํ”„๋กœํผํ‹ฐ '\(propertyName)'์˜ ํƒ€์ž…์ด \(T.self)๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค",
                    file: file,
                    line: line
                )
                return
            }
        }
    }
    
    XCTFail(
        "ํ”„๋กœํผํ‹ฐ '\(propertyName)'์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค",
        file: file,
        line: line
    )
}

// ํ…Œ์ŠคํŠธ ์˜ˆ์‹œ
class UserTests: XCTestCase {
    func testUserCreation() {
        struct User {
            let id: Int
            let username: String
            let isActive: Bool
        }
        
        let user = User(id: 1, username: "testuser", isActive: true)
        
        // Mirror๋ฅผ ํ™œ์šฉํ•œ ๊ฒ€์ฆ
        assertHasProperty(user, named: "id", ofType: Int.self, withValue: 1)
        assertHasProperty(user, named: "username", ofType: String.self, withValue: "testuser")
        assertHasProperty(user, named: "isActive", ofType: Bool.self, withValue: true)
    }
}

๐Ÿš€ ์‹ค๋ฌด์—์„œ์˜ ํ™œ์šฉ ์‚ฌ๋ก€

๐Ÿ’ผ ์‹ค์ œ ํ”„๋กœ์ ํŠธ์—์„œ Mirror๊ฐ€ ๋น›๋‚˜๋Š” ์ˆœ๊ฐ„๋“ค

1. ๋กœ๊น… ์‹œ์Šคํ…œ ๐Ÿ”
์•ฑ์˜ ๋ชจ๋“  ์ด๋ฒคํŠธ์™€ ์ƒํƒœ๋ฅผ ์ž๋™์œผ๋กœ ๋กœ๊น…ํ•  ๋•Œ, Mirror๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ์ฒด์˜ ๋ชจ๋“  ํ”„๋กœํผํ‹ฐ๋ฅผ ์ž๋™์œผ๋กœ ๊ธฐ๋กํ•  ์ˆ˜ ์žˆ์–ด์š”.

2. ๋””๋ฒ„๊ทธ ํ™”๋ฉด ๐Ÿ›
๊ฐœ๋ฐœ ์ค‘์— ๊ฐ์ฒด์˜ ํ˜„์žฌ ์ƒํƒœ๋ฅผ ํ™”๋ฉด์— ํ‘œ์‹œํ•˜๋Š” ๋””๋ฒ„๊ทธ ๋ทฐ๋ฅผ ๋งŒ๋“ค ๋•Œ ์œ ์šฉํ•ด์š”.

3. ๋ฐ์ดํ„ฐ ์ง๋ ฌํ™” ๐Ÿ’พ
์ปค์Šคํ…€ JSON ์ธ์ฝ”๋”/๋””์ฝ”๋”๋ฅผ ๋งŒ๋“ค ๋•Œ Mirror๋ฅผ ํ™œ์šฉํ•˜๋ฉด ์ž๋™์œผ๋กœ ๋ชจ๋“  ํ”„๋กœํผํ‹ฐ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด์š”.

4. ํผ ๊ฒ€์ฆ โœ…
์‚ฌ์šฉ์ž ์ž…๋ ฅ ํผ์—์„œ ๋ชจ๋“  ํ•„๋“œ๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ฑ„์›Œ์กŒ๋Š”์ง€ ์ž๋™์œผ๋กœ ๊ฒ€์ฆํ•  ๋•Œ ์‚ฌ์šฉํ•ด์š”.

5. ๊ฐ์ฒด ๋ณต์‚ฌ ๐Ÿ“‹
๊นŠ์€ ๋ณต์‚ฌ(deep copy)๊ฐ€ ํ•„์š”ํ•  ๋•Œ Mirror๋กœ ๋ชจ๋“  ํ”„๋กœํผํ‹ฐ๋ฅผ ์ˆœํšŒํ•˜๋ฉฐ ๋ณต์‚ฌํ•  ์ˆ˜ ์žˆ์–ด์š”.

๐Ÿ“ ์‹ค๋ฌด ์˜ˆ์ œ: ์ž๋™ ๋กœ๊ฑฐ

class AutoLogger {
    static func log(_ object: Any, event: String) {
        let mirror = Mirror(reflecting: object)
        let typeName = "\(mirror.subjectType)"
        
        var logMessage = """
        โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        ๐Ÿ“Š ์ด๋ฒคํŠธ: \(event)
        ๐Ÿท๏ธ  ํƒ€์ž…: \(typeName)
        โฐ ์‹œ๊ฐ„: \(Date())
        โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
        """
        
        for child in mirror.children {
            if let label = child.label {
                logMessage += "\n  โ€ข \(label): \(child.value)"
            }
        }
        
        logMessage += "\nโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•"
        
        print(logMessage)
    }
}

// ์‚ฌ์šฉ ์˜ˆ์‹œ
struct OrderPlaced {
    let orderId: String
    let userId: String
    let totalAmount: Double
    let items: [String]
    let timestamp: Date
}

let order = OrderPlaced(
    orderId: "ORD-2024-001",
    userId: "USER-123",
    totalAmount: 89000,
    items: ["๋งฅ๋ถ ์ผ€์ด์Šค", "๋ฌด์„  ๋งˆ์šฐ์Šค"],
    timestamp: Date()
)

AutoLogger.log(order, event: "์ฃผ๋ฌธ ์™„๋ฃŒ")

// ์ถœ๋ ฅ:
// โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
// ๐Ÿ“Š ์ด๋ฒคํŠธ: ์ฃผ๋ฌธ ์™„๋ฃŒ
// ๐Ÿท๏ธ  ํƒ€์ž…: OrderPlaced
// โฐ ์‹œ๊ฐ„: 2024-01-15 14:30:00 +0000
// โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
//   โ€ข orderId: ORD-2024-001
//   โ€ข userId: USER-123
//   โ€ข totalAmount: 89000.0
//   โ€ข items: ["๋งฅ๋ถ ์ผ€์ด์Šค", "๋ฌด์„  ๋งˆ์šฐ์Šค"]
//   โ€ข timestamp: 2024-01-15 14:30:00 +0000
// โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

๐ŸŽ“ Mirror vs ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•๋“ค

๋Ÿฐํƒ€์ž„ ํƒ€์ž… ๊ฒ€์‚ฌ๋ฅผ ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ Mirror๋งŒ ์žˆ๋Š” ๊ฒŒ ์•„๋‹ˆ์—์š”. ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•๋“ค๊ณผ ๋น„๊ตํ•ด๋ณผ๊นŒ์š”?

๋ฐฉ๋ฒ• ์žฅ์  ๋‹จ์  ์‚ฌ์šฉ ์‹œ๊ธฐ
Mirror ํ”„๋กœํผํ‹ฐ ์ˆœํšŒ ๊ฐ€๋Šฅ
๊ตฌ์กฐ ํƒ์ƒ‰ ๊ฐ€๋Šฅ
์„ฑ๋Šฅ ์˜ค๋ฒ„ํ—ค๋“œ
์ฝ๊ธฐ ์ „์šฉ
๋””๋ฒ„๊น…, ๋กœ๊น…
๊ฐ์ฒด ๊ฒ€์‚ฌ
type(of:) ๋น ๋ฆ„
๊ฐ„๋‹จํ•จ
ํƒ€์ž…๋งŒ ํ™•์ธ ๊ฐ€๋Šฅ
๋‚ด๋ถ€ ๊ตฌ์กฐ ๋ชจ๋ฆ„
ํƒ€์ž… ์ฒดํฌ๋งŒ ํ•„์š”ํ•  ๋•Œ
is / as? ํƒ€์ž… ์บ์ŠคํŒ… ๋™์‹œ ๊ฐ€๋Šฅ
์•ˆ์ „ํ•จ
ํŠน์ • ํƒ€์ž…๋งŒ ํ™•์ธ
ํ”„๋กœํผํ‹ฐ ์ ‘๊ทผ ๋ถˆ๊ฐ€
ํƒ€์ž… ๋ณ€ํ™˜์ด ํ•„์š”ํ•  ๋•Œ
Codable ์ง๋ ฌํ™”/์—ญ์ง๋ ฌํ™”
ํƒ€์ž… ์•ˆ์ „
ํ”„๋กœํ† ์ฝœ ์ฑ„ํƒ ํ•„์š”
์ œํ•œ์ 
JSON ๋ณ€ํ™˜

๐Ÿ”„ ๊ฐ ๋ฐฉ๋ฒ•์˜ ์‚ฌ์šฉ ์˜ˆ์‹œ

struct Person {
    let name: String
    let age: Int
}

let person = Person(name: "๊น€์ฒ ์ˆ˜", age: 28)

// 1. Mirror - ํ”„๋กœํผํ‹ฐ ์ˆœํšŒ
let mirror = Mirror(reflecting: person)
print("Mirror๋กœ ํ™•์ธ:")
for child in mirror.children {
    if let label = child.label {
        print("  \(label): \(child.value)")
    }
}

// 2. type(of:) - ํƒ€์ž…๋งŒ ํ™•์ธ
let personType = type(of: person)
print("\ntype(of:)๋กœ ํ™•์ธ: \(personType)")  // Person

// 3. is - ํƒ€์ž… ์ฒดํฌ
let isPersonType = person is Person
print("\nis๋กœ ํ™•์ธ: \(isPersonType)")  // true

// 4. as? - ํƒ€์ž… ์บ์ŠคํŒ…
let anyValue: Any = person
if let castedPerson = anyValue as? Person {
    print("\nas?๋กœ ํ™•์ธ: \(castedPerson.name)")  // ๊น€์ฒ ์ˆ˜
}

// ์„ฑ๋Šฅ ๋น„๊ต (๋Œ€๋žต์ ์ธ ์†๋„)
// type(of:) > is/as? > Mirror
// Mirror๋Š” ๊ฐ€์žฅ ๋А๋ฆฌ์ง€๋งŒ ๊ฐ€์žฅ ๋งŽ์€ ์ •๋ณด๋ฅผ ์ œ๊ณต

๐Ÿ’ก ๋ฒ ์ŠคํŠธ ํ”„๋ž™ํ‹ฐ์Šค

โœจ Mirror๋ฅผ ํšจ๊ณผ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ํŒ

1. ๊ฐœ๋ฐœ/๋””๋ฒ„๊ทธ ํ™˜๊ฒฝ์—์„œ๋งŒ ์‚ฌ์šฉ
ํ”„๋กœ๋•์…˜ ์ฝ”๋“œ์˜ ํ•ต์‹ฌ ๋กœ์ง์—๋Š” Mirror ์‚ฌ์šฉ์„ ์ž์ œํ•˜๊ณ , ๋””๋ฒ„๊น…์ด๋‚˜ ๋กœ๊น… ์šฉ๋„๋กœ๋งŒ ์‚ฌ์šฉํ•˜์„ธ์š”.

2. ์บ์‹ฑ ํ™œ์šฉ
๊ฐ™์€ ํƒ€์ž…์˜ Mirror๋ฅผ ๋ฐ˜๋ณตํ•ด์„œ ์ƒ์„ฑํ•˜์ง€ ๋ง๊ณ , ๊ฐ€๋Šฅํ•˜๋ฉด ์บ์‹ฑํ•ด์„œ ์žฌ์‚ฌ์šฉํ•˜์„ธ์š”.

3. ํƒ€์ž… ์ฒดํฌ ๋จผ์ €
Mirror๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์ „์— type(of:)๋‚˜ is๋กœ ๋จผ์ € ํƒ€์ž…์„ ํ™•์ธํ•˜๋Š” ๊ฒŒ ํšจ์œจ์ ์ด์—์š”.

4. ์˜ต์…”๋„ ์ฒ˜๋ฆฌ ์ฒ ์ €ํžˆ
child.label์€ ํ•ญ์ƒ ์˜ต์…”๋„์ด๋‹ˆ ์•ˆ์ „ํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•˜์„ธ์š”.

5. CustomReflectable ํ™œ์šฉ
๋ฏผ๊ฐํ•œ ์ •๋ณด๊ฐ€ ์žˆ๋Š” ํƒ€์ž…์€ CustomReflectable์„ ๊ตฌํ˜„ํ•ด์„œ ๋…ธ์ถœ์„ ์ œ์–ดํ•˜์„ธ์š”.

๐ŸŽฏ ์„ฑ๋Šฅ ์ตœ์ ํ™” ์˜ˆ์ œ

// โŒ ๋‚˜์œ ์˜ˆ: ๋ฐ˜๋ณต๋ฌธ ์•ˆ์—์„œ Mirror ์ƒ์„ฑ
func processItems(_ items: [Person]) {
    for item in items {
        let mirror = Mirror(reflecting: item)  // ๋งค๋ฒˆ ์ƒ์„ฑ!
        // ... ์ฒ˜๋ฆฌ ...
    }
}

// โœ… ์ข‹์€ ์˜ˆ: ํƒ€์ž…๋ณ„๋กœ ํ•œ ๋ฒˆ๋งŒ ์ƒ์„ฑ
class MirrorCache {
    private var cache: [String: Mirror] = [:]
    
    func getMirror(for object: Any) -> Mirror {
        let typeName = "\(type(of: object))"
        
        if let cached = cache[typeName] {
            return cached
        }
        
        let mirror = Mirror(reflecting: object)
        cache[typeName] = mirror
        return mirror
    }
}

let cache = MirrorCache()

func processItemsOptimized(_ items: [Person]) {
    for item in items {
        let mirror = cache.getMirror(for: item)
        // ... ์ฒ˜๋ฆฌ ...
    }
}

๐ŸŒŸ ์žฌ๋Šฅ๋„ท์—์„œ ๋” ๋ฐฐ์šฐ๊ธฐ

Swift์˜ ๋ฆฌํ”Œ๋ ‰์…˜๊ณผ Mirror๋Š” ์ •๋ง ๊นŠ์ด ์žˆ๋Š” ์ฃผ์ œ์˜ˆ์š”. ์ด ๊ธ€์—์„œ ๋‹ค๋ฃฌ ๋‚ด์šฉ์€ ์‹œ์ž‘์— ๋ถˆ๊ณผํ•˜๋‹ต๋‹ˆ๋‹ค! ๐Ÿ˜Š

๋” ๊ณ ๊ธ‰ ๊ธฐ๋ฒ•์ด๋‚˜ ์‹ค๋ฌด ํ™œ์šฉ ์‚ฌ๋ก€๊ฐ€ ๊ถ๊ธˆํ•˜๋‹ค๋ฉด, ์žฌ๋Šฅ๋„ท์—์„œ Swift ์ „๋ฌธ๊ฐ€๋“ค์˜ ๊ฐ•์˜๋‚˜ ๋ฉ˜ํ† ๋ง์„ ๋ฐ›์•„๋ณด๋Š” ๊ฒƒ๋„ ์ข‹์€ ๋ฐฉ๋ฒ•์ด์—์š”. ์‹ค์ œ ํ”„๋กœ์ ํŠธ์—์„œ ์–ด๋–ป๊ฒŒ ํ™œ์šฉํ•˜๋Š”์ง€, ์–ด๋–ค ํ•จ์ •์„ ์กฐ์‹ฌํ•ด์•ผ ํ•˜๋Š”์ง€ ๋“ฑ ์‹ค์ „ ๊ฒฝํ—˜์„ ๊ณต์œ ๋ฐ›์„ ์ˆ˜ ์žˆ๊ฑฐ๋“ ์š”!

๐ŸŽ“ ํ•™์Šต ๋กœ๋“œ๋งต ์ œ์•ˆ

์ดˆ๊ธ‰ ๐ŸŒฑ
โ€ข Mirror ๊ธฐ๋ณธ ์‚ฌ์šฉ๋ฒ• ์ตํžˆ๊ธฐ
โ€ข children ํ”„๋กœํผํ‹ฐ๋กœ ํ”„๋กœํผํ‹ฐ ์ˆœํšŒํ•˜๊ธฐ
โ€ข displayStyle๋กœ ํƒ€์ž… ๊ตฌ๋ถ„ํ•˜๊ธฐ

์ค‘๊ธ‰ ๐ŸŒฟ
โ€ข CustomReflectable ํ”„๋กœํ† ์ฝœ ๊ตฌํ˜„
โ€ข ์žฌ๊ท€์  ๊ฐ์ฒด ํƒ์ƒ‰
โ€ข ์ƒ์† ๊ตฌ์กฐ ํƒ์ƒ‰
โ€ข ์‹ค์šฉ์ ์ธ ์œ ํ‹ธ๋ฆฌํ‹ฐ ํ•จ์ˆ˜ ๋งŒ๋“ค๊ธฐ

๊ณ ๊ธ‰ ๐ŸŒณ
โ€ข ์„ฑ๋Šฅ ์ตœ์ ํ™” ๊ธฐ๋ฒ•
โ€ข ์ปค์Šคํ…€ ์ง๋ ฌํ™” ์‹œ์Šคํ…œ ๊ตฌ์ถ•
โ€ข ๋ฉ”ํƒ€ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํŒจํ„ด
โ€ข ํ”„๋ ˆ์ž„์›Œํฌ ๊ฐœ๋ฐœ์— ํ™œ์šฉ

๐ŸŽฌ ๋งˆ๋ฌด๋ฆฌํ•˜๋ฉฐ

์˜ค๋Š˜์€ Swift์˜ ๋ฆฌํ”Œ๋ ‰์…˜๊ณผ Mirror์— ๋Œ€ํ•ด ์•Œ์•„๋ดค์–ด์š”! ๐ŸŽ‰

์ฒ˜์Œ์—๋Š” ์ข€ ์–ด๋ ต๊ฒŒ ๋А๊ปด์งˆ ์ˆ˜ ์žˆ์ง€๋งŒ, ํ•œ ๋ฒˆ ์ต์ˆ™ํ•ด์ง€๋ฉด ์ •๋ง ๊ฐ•๋ ฅํ•œ ๋„๊ตฌ๊ฐ€ ๋œ๋‹ต๋‹ˆ๋‹ค. ํŠนํžˆ ๋””๋ฒ„๊น…ํ•  ๋•Œ๋‚˜ ๋ณต์žกํ•œ ๊ฐ์ฒด ๊ตฌ์กฐ๋ฅผ ๋‹ค๋ฃฐ ๋•Œ Mirror๋งŒํผ ์œ ์šฉํ•œ ๊ฒŒ ์—†์–ด์š”.

ํ•˜์ง€๋งŒ ๊ธฐ์–ตํ•˜์„ธ์š”! ๐ŸŽฏ Mirror๋Š” "ํ•„์š”ํ•  ๋•Œ" ์‚ฌ์šฉํ•˜๋Š” ๋„๊ตฌ์˜ˆ์š”. ๋ชจ๋“  ๊ณณ์— ๋‚จ์šฉํ•˜๋ฉด ์„ฑ๋Šฅ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธธ ์ˆ˜ ์žˆ์œผ๋‹ˆ, ์ ์žฌ์ ์†Œ์— ํ™œ์šฉํ•˜๋Š” ๊ฒŒ ์ค‘์š”ํ•ด์š”.

์—ฌ๋Ÿฌ๋ถ„์˜ Swift ๊ฐœ๋ฐœ ์—ฌ์ •์— ์ด ๊ธ€์ด ์กฐ๊ธˆ์ด๋‚˜๋งˆ ๋„์›€์ด ๋˜์—ˆ์œผ๋ฉด ์ข‹๊ฒ ์–ด์š”. ๊ถ๊ธˆํ•œ ์ ์ด ์žˆ๋‹ค๋ฉด ์–ธ์ œ๋“  ๋Œ“๊ธ€๋กœ ๋ฌผ์–ด๋ด ์ฃผ์„ธ์š”! ๐Ÿ˜Š

๊ทธ๋Ÿผ ๋‹ค์Œ์— ๋˜ ์žฌ๋ฏธ์žˆ๋Š” Swift ์ด์•ผ๊ธฐ๋กœ ๋งŒ๋‚˜์š”! ํ•ดํ”ผ ์ฝ”๋”ฉ! ๐Ÿ’ปโœจ

๐ŸŽ“ ํ•™์Šต ์™„๋ฃŒ! ๐Ÿ” Mirror ๐Ÿชž Reflection โšก Runtime ๐ŸŽฏ Type Check ์ด์ œ ์—ฌ๋Ÿฌ๋ถ„๋„ Swift ๋ฆฌํ”Œ๋ ‰์…˜ ๋งˆ์Šคํ„ฐ! ๊ณ„์†ํ•ด์„œ ์—ฐ์Šตํ•˜๊ณ  ์‹ค์ „์— ์ ์šฉํ•ด๋ณด์„ธ์š” ๐Ÿ’ช

๐Ÿ“š ์ด ๊ธ€์ด ๋„์›€์ด ๋˜์…จ๋‚˜์š”?
๋” ๋งŽ์€ Swift ์ง€์‹์„ ์›ํ•˜์‹ ๋‹ค๋ฉด ์žฌ๋Šฅ๋„ท์˜ '์ง€์‹์ธ์˜ ์ˆฒ'์„ ๋ฐฉ๋ฌธํ•ด๋ณด์„ธ์š”!

๋Œ“๊ธ€ ์ž‘์„ฑ

์ด ๊ธ€์— ๋Œ€ํ•œ ์—ฌ๋Ÿฌ๋ถ„์˜ ์ƒ๊ฐ์„ ๋“ค๋ ค์ฃผ์„ธ์š”

๋Œ“๊ธ€ 0
๋Œ“๊ธ€์„ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ค‘์ž…๋‹ˆ๋‹ค.

์•„์ง ๋Œ“๊ธ€์ด ์—†์Šต๋‹ˆ๋‹ค.