๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐ŸŽ iOS/WWDC

[WWDC 2022] Swift๋กœ ํ”„๋กœํ† ์ฝœ ์ธํ„ฐํŽ˜์ด์Šค ์„ค๊ณ„ํ•˜๊ธฐ (Design protocol interface in Swift)

by Fomagran ๐Ÿ’ป 2022. 7. 11.
728x90
๋ฐ˜์‘ํ˜•

์•ˆ๋…•ํ•˜์„ธ์š” Foma ์ž…๋‹ˆ๋‹ค!

 

์˜ค๋Š˜์€ ์ €๋ฒˆ ๊ธ€์ธ Embrace Swift Generics์—์„œ ๊ณ„์† ์–ธ๊ธ‰ํ•˜๋˜ Design protocol interface in Swift ์„ธ์…˜์— ๋Œ€ํ•ด์„œ ๋‹ค๋ค„๋ณด๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค!

 

(์ €๋ฒˆ ๊ธ€๊ณผ ๋งŽ์ด ์—ฐ๊ด€๋˜์–ด ์žˆ์œผ๋‹ˆ ์•ˆ๋ณด์‹  ๋ถ„๋“ค์€ ๊ผญ ์—ฌ๊ธฐ ์—์„œ ๋ณด๊ณ  ์™€์ฃผ์„ธ์š”!) 

 

๋ฐ”๋กœ ์‹œ์ž‘ํ• ๊ฒŒ์š”~


Understand type erasure

 

 

๊ฐ€์žฅ ๋จผ์ € ํƒ€์ž… ์ด๋ ˆ์ด์ ธ์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. (erasure๋ฅผ ์ •ํ™•ํžˆ ์–ด๋–ป๊ฒŒ ํ•ด์„ํ•ด์•ผ ํ• ์ง€ ๋ชจ๋ฅด๊ฒ ๋„ค์š”.. ์‚ญ์ œ? ์ง€์›€?)

 

๊ฐ€์žฅ ๋จผ์ € ๋™๋ฌผ ํ”„๋กœํ† ์ฝœ์„ ์‚ดํŽด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

๋™๋ฌผ ํ”„๋กœํ† ์ฝœ์€ associatedtype์œผ๋กœ ๋จน์ดํƒ€์ž…๊ณผ ์ƒ์‚ฐํ’ˆํƒ€์ž…์ด ์žˆ๊ณ , ๋ฉ”์„œ๋“œ๋กœ ๋จน์ดํƒ€์ž…์„ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋ฐ›๋Š” eat, ์ƒ์‚ฐํ’ˆ ํƒ€์ž…์„ ๋ฐ˜ํ™˜ํ•˜๋Š” produce ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

 

protocol Animal {
    associatedtype FeedType: AnimalFeed
    associatedtype ProductType: Product
    func eat(_ food: FeedType)
    func produce() -> ProductType
}

 

๊ฐ ๊ตฌ์ฒด์ ์ธ ๋™๋ฌผ๋“ค์€ ๋™๋ฌผ ํ”„๋กœํ† ์ฝœ์„ ๋”ฐ๋ฅด๋ฉฐ ๊ตฌ์ฒด์ ์ธ ๋จน์ด์™€ ์ƒ์‚ฐํ’ˆ ํƒ€์ž…์„ ๋ช…์‹œํ•˜์ฃ .

 

struct Cow: Animal {
    func eat(_ food: Hay) {}
    func produce() -> Milk {
        return Milk()
    }
}

struct Chicken: Animal {
    func eat(_ food: Grain) {}
    func produce() -> Egg {
        return Egg()
    }
}

struct Horse: Animal {
    func eat(_ food: Carrot) {}
    func produce() -> Vehicle {
        return Vehicle()
    }
}

 

๋™๋ฌผ๋“ค์—๊ฒŒ ๋จน์ด์™€ ์ƒ์‚ฐํ’ˆ์„ ๊ธธ๋Ÿฌ๋‚ด๋Š” ๋†์žฅ ์ŠคํŠธ๋ŸญํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์—ฌ๊ธฐ์„œ๋Š” any Animal, any Product์™€ ๊ฐ™์ด ์•ž์— any ํ‚ค์›Œ๋“œ์™€ ํ•จ๊ป˜ ํ”„๋กœํ† ์ฝœ์ด ๋ช…์‹œ๋œ ๋ฐฐ์—ด๋“ค์ด ์žˆ์Šต๋‹ˆ๋‹ค.

 

์ด๊ฒƒ๋“ค์€ "ํ•ด๋‹น ํ”„๋กœํ† ์ฝœ์„ ๋”ฐ๋ฅด๋Š” ์–ด๋–ค ๊ตฌ์ฒด์ ์ธ ํƒ€์ž…๋“ค์ด ์ฑ„์›Œ์งˆ๊ฑฐ์•ผ" ๋ผ๊ณ  ๋ช…์‹œ๋งŒ ํ•  ๋ฟ ๊ตฌ์ฒด์ ์ธ ํƒ€์ž…๋“ค์ด ์ง€์›Œ์ ธ ์žˆ์Šต๋‹ˆ๋‹ค.

 

([any Animal] == [Cow, Horse, Chicken], [any Product] == [Milk, Vehicle, Egg]์™€ ๊ฐ™์€ ๊ฒƒ์ด์ฃ .)

 

๋ฐ”๋กœ ์ด๋ ‡๊ฒŒ ํƒ€์ž…์„ ๋ช…์‹œํ•˜์ง€ ์•Š๊ณ  ์ง€์›Œ์ ธ ์žˆ๋Š” ์ƒํƒœ๋ฅผ "ํƒ€์ž… ์ด๋ ˆ์ด์ ธ" ๋ผ๊ณ  ๋ถ€๋ฅด๋Š” ๊ฒƒ์ด์ฃ .

 

struct Farm {
    var animals:[any Animal]
    
    func feed(_ animal: some Animal) {
        let crop = type(of: animal).FeedType.grow()
        let produce = crop.harvest()
        animal.eat(produce)
    }
    
    func feedAll(_ animals: [any Animal]) {
        for animal in animals {
            feed(animal)
        }
    }
    
    func produce() -> [any Product] {
        return animals.map { animal in
            animal.produce()
        }
    }
}

Hide implementation details

 

๊ทธ ๋‹ค์Œ์œผ๋กœ ์•Œ์•„๋ณผ ๊ฒƒ์€ ๊ตฌ์ฒด์ ์ธ ํƒ€์ž…์„ ์ˆจ๊ธฐ๋Š” ๊ฒƒ ์ž…๋‹ˆ๋‹ค.

 

์ด๊ฒƒ์€ ์ •์  ํƒ€์ž… ํ• ๋‹น์„ ๋” ๋ชจ๋“ˆํ™”ํ•˜๊ณ  ๊ฒฌ๊ณ ํ•˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š”๋ฐ์š”.

 

์˜ˆ๋ฅผ ๋“ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ๋™๋ฌผ ํ”„๋กœํ† ์ฝœ์— isHungry ํ”„๋กœํผํ‹ฐ๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

protocol Animal {
    var isHungry:Bool { get }
	...
}

 

๋†์žฅ์—์„  ์ด ๋ฐฐ๊ณ ํ”ˆ ๋™๋ฌผ๋“ค์—๊ฒŒ๋งŒ ๋จน์ด๋ฅผ ์ฃผ๋ ค๊ณ  ํ•˜๋Š”๋ฐ์š”.

 

์ด๊ฒƒ์„ ์œ„ํ•ด isHungry๊ฐ€ true๋กœ ๋œ ๋™๋ฌผ๋“ค์„ filter ๋ฉ”์„œ๋“œ๋กœ ๊ฑธ๋Ÿฌ ๋จน์ด๋ฅผ ์ฃผ๋„๋ก ๊ตฌํ˜„ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

struct Farm {
    var hungryAnimals: [any Animal] {
        animals.filter(\.isHungry)
    }
    
    func feedToHungryAnimals() {
        for animal in hungryAnimals {
			...
        }
    }
    ...

 

์œ„์—์„œ filter ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ hungryAnimals๋ฅผ ๋งŒ๋“œ๋Š” ๊ณผ์ •์—์„œ ๋ฌธ์ œ์ ์ด ๋ฐœ์ƒํ•˜๋Š”๋ฐ์š”.

 

filter๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฑธ๋Ÿฌ๋‚ด๋Š” hungryAnimals๋Š” ํ•ญ์ƒ ์ž„์‹œ์ ์œผ๋กœ ์ƒ๊ฒจ๋‚˜๊ณ  ์‚ฌ๋ผ์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

์ด๊ฒƒ์€ ๋งŒ์•ฝ ์—„์ฒญ๋‚˜๊ฒŒ ๋งŽ์€ ๋ฐฐ๊ณ ํ”ˆ ๋™๋ฌผ๋“ค์ด ์กด์žฌํ•œ๋‹ค๋ฉด ๊ณ„์†ํ•ด์„œ ๋งŽ์€ ์ˆ˜์˜ ์—ฐ์‚ฐํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ต‰์žฅํžˆ ๋น„ํšจ์œจ์ ์ธ ์ฝ”๋“œ๊ฐ€ ๋  ๊ฒƒ ์ž…๋‹ˆ๋‹ค.

 

์ด ๋ฌธ์ œ๋ฅผ ๊ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•ด์„œ ์•„๋ž˜์™€ ๊ฐ™์ด Lazy๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ์š”.

 

lazy์— ๋Œ€ํ•ด ๊ฐ„๋‹จํ•˜๊ฒŒ ์„ค๋ช…๋“œ๋ฆฌ๋ฉด ํ•ญ์ƒ ์—ฐ์‚ฐ์„ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ ๊ฒŒ์œผ๋ฅธ ์ƒํƒœ๋กœ ์žˆ๋‹ค๊ฐ€ feedToHungryAnimals๊ฐ€ ์‹คํ–‰๋  ๋•Œ๋งŒ ์—ฐ์‚ฐ์„ ํ•˜๊ฒŒ ๋˜์–ด ์ž„์‹œ์ ์œผ๋กœ ํ• ๋‹น๋˜๋Š” ๊ฒƒ์„ ํ”ผํ•ด์ค๋‹ˆ๋‹ค.

 

(lazy์— ๋Œ€ํ•œ ์ž์„ธํ•œ ์„ค๋ช…์€ ์—ฌ๊ธฐ ๊ฐ“์ œ๋“œ๋‹˜์˜ ์„ค๋ช…์„ ๋ณด๋ฉด ์ดํ•ดํ•˜๊ธฐ ์‰ฌ์šฐ์‹ค ๊ฑฐ์—์š”!)

 

struct Farm {
    var hungryAnimals: LazyFilterSequence<[any Animal]> {
        animals.lazy.filter(\.isHungry)
    }
    ...

 

LazyFilterSequence๋Š” Collection ํ”„๋กœํ† ์ฝœ์„ ๋”ฐ๋ฅด๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์—

 

 

์ €๋ฒˆ ๊ธ€์—์„œ ๋ฐฐ์šด some์„ ํ™œ์šฉํ•˜๋ฉด ๋ถˆํˆฌ๋ช…ํ•œ ๊ฒฐ๊ณผ ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ณต์žกํ•œ ๊ตฌ์ฒด์ ์ธ ํƒ€์ž…(LazyFilterSequence)์„ ์ˆจ๊ธธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์ด๋ ‡๊ฒŒ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ์‚ฌ์šฉํ•˜๋Š” ํด๋ผ์ด์–ธํŠธ๋Š” Collection ํ”„๋กœํ† ์ฝœ์„ ๋”ฐ๋ฅด๋ฉฐ ๊ทธ ์•ˆ์— Animal ํ”„๋กœํ† ์ฝœ์„ ๋”ฐ๋ฅด๋Š” ๋ฌด์—‡์ธ๊ฐ€๋ฅผ ์–ป๊ณ  ์žˆ๋‹ค๋Š” ๊ฒƒ๋งŒ ์•Œ ๋ฟ, ๊ตฌ์ฒด์ ์ธ ํƒ€์ž…์— ๋Œ€ํ•ด ์•Œ ์ˆ˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

 

struct Farm {
    var hungryAnimals: some Collection<any Animal> {
        animals.lazy.filter(\.isHungry)
    }
	...

 

 

๋งŒ์•ฝ hungryAnimals๋ฅผ ์–ด๋–ค ๊ฒฝ์šฐ์—” LazyFilterSequence๋กœ ์–ด๋–ค ๊ฒฝ์šฐ์—” Array๋กœ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ• ๊นŒ์š”?

 

์•„๋ž˜์™€ ๊ฐ™์ด ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ ์ž…๋‹ˆ๋‹ค.

 

    var hungryAnimals: some Collection<any Animal> {
        if isLazy {
           return animals.lazy.filter(\.isHungry)
        }else {
           return animals.filter(\.isHungry)
        }
    }

 

 

ํ•˜์ง€๋งŒ ์ด๋ ‡๊ฒŒ ์ž‘์„ฑํ•˜๋ฉด ๋ถˆํˆฌ๋ช…ํ•˜๊ฒŒ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ธฐ๋ณธ ์œ ํ˜•์„ ์ถ”๋ก ํ•  ์ˆ˜๊ฐ€ ์—†๋‹ค๋Š” ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

 

 

๊ณ ๋กœ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„  some ๋Œ€์‹  any ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Collection ํ”„๋กœํ† ์ฝœ์„ ๋”ฐ๋ฅด๋Š” ํƒ€์ž…์„ ๋ชจ๋‘ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์–ด ์ค๋‹ˆ๋‹ค.

 

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๊ตฌ์ฒด์ ์ธ ๊ฒฐ๊ณผ ํƒ€์ž…์„ ์ˆจ๊ธฐ๋ฉด์„œ ํ•ด๋‹น ํ”„๋กœํ† ์ฝœ์„ ๋”ฐ๋ฅด๋Š” ๋ชจ๋“  ํƒ€์ž…์„ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด์ฃ !

 

    var hungryAnimals: any Collection<any Animal> {
        if isLazy {
           return animals.lazy.filter(\.isHungry)
        }else {
           return animals.filter(\.isHungry)
        }
    }

Identify type relationships

 

์ด์ œ๋ถ€ํ„ฐ๋Š” ์—ฌ๋Ÿฌ ์ถ”์ƒํ™”๋œ ํ”„๋กœํ† ์ฝœ์˜ ๊ด€๊ณ„๋ฅผ ์‹๋ณ„ํ•˜๊ณ  ๋ณด์žฅํ•˜๋Š” ๋ฒ•์— ๋Œ€ํ•ด์„œ ๋‹ค๋ค„ ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

๋™๋ฌผ์—๊ฒŒ ์ฃผ๋Š” ๋จน์ด๋ฅผ ๊ธฐ๋ฅด๊ธฐ ์œ„ํ•ด์„  ์•„๋ž˜์™€ ๊ฐ™์ด 3๋‹จ๊ณ„๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

 

1. ๋™๋ฌผ์˜ ๋จน์ด ํƒ€์ž…์„ ๊ธฐ๋ฅด๋ฉด ๊ณก๋ฌผ์ด ๋˜๊ณ 

2. ๊ณก๋ฌผ์„ ์ˆ˜ํ™•ํ•˜๋ฉด ๋จน์ด๊ฐ€ ๋˜๊ณ 

3. ๋™๋ฌผ๋“ค์—๊ฒŒ ๊ทธ ๋จน์ด๋ฅผ ์ฃผ๊ฒŒ ๋˜๋Š” ๊ฒƒ ์ž…๋‹ˆ๋‹ค.

 

    func feed(_ animal: some Animal) {
        let crop = type(of: animal).FeedType.grow()
        let food = crop.harvest()
        animal.eat(food)
    }

 

๊ทธ๋Ÿฌ๋ฉด ๋™๋ฌผ์˜ ๋จน์ด์—” ๊ณก๋ฌผ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์–ด์•ผ ํ•˜๊ฒ ์ฃ ?

 

protocol AnimalFeed {
    associatedtype CropType: Crop
    static func grow() -> CropType
}

 

๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๊ณก๋ฌผ๋„ ๋™๋ฌผ์˜ ๋จน์ด์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์–ด์•ผ ํ•  ๊ฒƒ ์ž…๋‹ˆ๋‹ค.

 

protocol Crop {
    associatedtype FeedType: AnimalFeed
    func harvest() -> FeedType
}

 

ํ•˜์ง€๋งŒ ์œ„์™€ ๊ฐ™์ด ๊ตฌํ˜„๋˜์–ด ์žˆ๋‹ค๋ฉด Crop์˜ FeedType์„ ์•Œ์•„๋‚ด๊ณ  ํ•ด๋‹น Feed์˜ CropType์„ ์•Œ์•„๋‚ด๊ณ  Cropt์˜ FeedType์„ ์•Œ์•„๋‚ด๊ณ ... ์ด๋Ÿฐ ์‹์œผ๋กœ ๋ฌดํ•œ๋Œ€๋กœ ์—ฐ๊ฒฐ์ด ๋˜๋Š” ๋ฌธ์ œ์ ์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

 

 

๊ทธ๋ž˜์„œ ๊ตฌํ˜„๋ถ€์—์„  ์•„๋ž˜์™€ ๊ฐ™์€ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒŒ ๋˜๋Š” ๊ฒƒ์ด์ฃ .

 

 

๋˜ ๋‹ค๋ฅธ ๋ฌธ์ œ์ ์ด ํ•˜๋‚˜ ๋” ์กด์žฌํ•˜๋Š”๋ฐ์š”.

 

Hay๋ฅผ ๊ธธ๋Ÿฌ๋‚ด๋ฉด Alfalfa๊ฐ€ ๋˜๊ณ  

 

struct Hay: AnimalFeed {
    static func grow() -> Alfalfa {
        return Alfalfa()
    }
}

 

Alfalfa๋ฅผ ์ˆ˜ํ™•ํ•˜๋ฉด Hay๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

 

struct Alfalfa: Crop {    
    func harvest() -> Hay {
        return Hay()
    }
}

 

ํ•˜์ง€๋งŒ ์—ฌ๊ธฐ์„œ Alfalfa๋ฅผ ๋‹ญ์ด ๋จน๋Š” Scratch์œผ๋กœ ๋ณ€๊ฒฝ์ด ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ๊ฒƒ ์ž…๋‹ˆ๋‹ค.

 

struct Alfalfa: Crop {    
    func harvest() -> Scratch {
        return Scratch()
    }
}

 

์ด๋ ‡๊ฒŒ ๋˜๋ฉด Alfalfa์˜ ๋จน์ด ํƒ€์ž…์€ Scratch๊ฐ€ ๋™๊ณ  ํ•ด๋‹น Crop ํƒ€์ž…์€ Millet์œผ๋กœ ๋ณ€๊ฒฝ๋˜์–ด ๋ฒ„๋ฆฌ๋Š” ๊ฒƒ์ด์ฃ .

 

๊ทธ๋Ÿฌ๋ฉด ์†Œ์—๊ฒŒ ์ค„ ๋จน์ด๊ฐ€ ๊ฑด์ดˆ์—์„œ ๋ฐ€๋ ˆ๋กœ ๋ฐ”๋€Œ์–ด ๋ฒ„๋ฆฌ๋Š” ๊ฒƒ์ด์ฃ .

 

 

์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์€ where์ ˆ์„ ์‚ฌ์šฉํ•˜์—ฌ ์•„๋ž˜์™€ ๊ฐ™์ด ์ •ํ™•ํ•œ ํƒ€์ž…์„ ๋ช…์‹œํ•ด ์ฃผ๋Š” ๊ฒƒ ์ž…๋‹ˆ๋‹ค.

 

Self๋Š” ์ž์‹ ์˜ ํƒ€์ž…์„ ์˜๋ฏธํ•˜๋Š” ๊ฒƒ์ด๋ฏ€๋กœ Crop์˜ Feed๋Š” Feed ์ž์‹ ์ด ๋˜์–ด์•ผ ํ•ด ๊ทธ๋ฆฌ๊ณ  Crop์˜ Feed๋Š” Crop ์ž์‹ ์ด ๋˜์–ด์•ผ ํ•œ๋‹ค๊ณ  ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ด์ฃ .

 

์ด๋ ‡๊ฒŒ ๊ตฌํ˜„ํ•˜๋ฉด ๋™๋ฌผ์—๊ฒŒ ์•Œ๋งž์€ ๊ณก๋ฌผ๊ณผ ๋จน์ด๋ฅผ ์‹ค์ˆ˜์—†์ด ์ค„ ์ˆ˜ ์žˆ๊ฒŒ ๋˜๋Š” ๊ฒƒ์ด์ฃ !

 

protocol AnimalFeed {
    associatedtype CropType: Crop
        where CropType.FeedType == Self
    static func grow() -> CropType
}
protocol Crop {
    associatedtype FeedType: AnimalFeed
        where FeedType.CropType == Self
    func harvest() -> FeedType
}

 

๋˜ํ•œ ๋ฌดํ•œ๋Œ€๋กœ ์ด์–ด์กŒ๋˜ ๋‘ ํ”„๋กœํ† ์ฝœ์˜ ๊ด€๊ณ„๋Š” ์ด๋ ‡๊ฒŒ ํ•œ ์Œ์œผ๋กœ ๊ฐ„๋‹จํ•˜๊ฒŒ ๊ด€๊ณ„๊ฐ€ ๋ณ€ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 


Source Code

 

 

GitHub - fomagran/WWDC: Repository to study content published by WWDC

Repository to study content published by WWDC. Contribute to fomagran/WWDC development by creating an account on GitHub.

github.com


Reference

 

 

Design protocol interfaces in Swift - WWDC22 - Videos - Apple Developer

Learn how you can use Swift 5.7 to design advanced abstractions using protocols. We'll show you how to use existential types, explore how...

developer.apple.com

 

728x90
๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€