Semantics Type

typealias Kilograms = Double
 
struct Package {
    var weight: Kilograms
}

Combine Protocols

protocol ReadAccess {}
protocol WriteAccess {}
 
typealias AdminAccess = ReadAccess & WriteAccess
struct Teacher: AdminAccess {}

Int, Double์€ ์–ด๋””์„œ๋“  ์‚ฌ์šฉ๋˜๋Š” ํƒ€์ž…์ด๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์ฝ”๋“œ ์ž‘์„ฑ์‹œ ์–ด๋–ค ์˜๋ฏธ๋กœ ํ•ด๋‹น ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜๋Š”์ง€๋Š” ์ฝ”๋“œ๋ฅผ ์ฝ์–ด๋ด์•ผ ์•Œ ์ˆ˜ ์žˆ๋‹ค. ์ด๋Ÿฐ ๊ฒฝ์šฐ ์˜๋ฏธ๋ก ์ ์ธ ํƒ€์ž…์„ ์„ ์–ธํ•˜๊ธฐ ์œ„ํ•ด ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

Specializing generics

Type alias๋ฅผ ํ™œ์šฉํ•˜๋Š” ๋‹ค์Œ ๋ฐฉ๋ฒ•์€, ์ฝ”๋“œ ์ „๋ฐ˜์— ๊ฑธ์ณ, ๊ฐ™์€ generic type์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ์ด๋‹ค. ์ฆ‰, ๊ฐ™์€ generic์„ ์‚ฌ์šฉํ•˜๋Š”๋ฐ, ์ด generic์ด ๊ธธ์–ด์ง€๋Š” ๋“ฑ์˜ ์ด์œ ๋กœ ์˜คํžˆ๋ ค ์–ด๋–ค ์˜๋ฏธ์ธ์ง€ ํŒŒ์•…ํ•˜๊ธฐ ์–ด๋ ต๋‹ค๋ฉด ์‚ฌ์šฉํ•˜์ž. ์˜ˆ๋ฅผ ๋“ค์–ด, Note App์„ ๋งŒ๋“œ๋Š”๋ฐ, ๊ทธ ์•ˆ์˜ storage type์„ ๋ฐ˜์˜ํ•˜์•ผ ํ•˜๋Š” ์ƒํ™ฉ์„ ์ƒ๊ฐํ•ด๋ณด์ž.

class FileStorage<Key: Hashable, Location: FileStorageLocation> {
    ...    
}
 
class NoteSyncController {
    init(localStorage: FileStorage<Note.StorageKey, LocalFileStorageLocation>,
         cloudStorage: FileStorage<Note.StorageKey, CloudStorageLocation>) {
        ...
    }
}

์ƒ๋‹นํžˆ ์ฝ๊ธฐ ์–ด๋ ต๋‹ค. ์—ฌ๊ธฐ์„œ ํ•œ๋ฒˆ์˜ ์ถ”์ƒํ™”๋ฅผ ํ•œ๋‹ค๋ฉด ๊ฐ€๋…์„ฑ์ด ํฌ๊ฒŒ ํ–ฅ์ƒ๋  ๊ฒƒ์ด๋‹ค. ์ฐธ, Key: Hashable๊ณผ ๊ฐ™์ด ๋˜์–ด ์žˆ๋Š” ๊ฒƒ์„ generic์—์„œ type constraints๋ผ๊ณ  ํ•œ๋‹ค. ํ•ด๋‹น Type๋งŒ ์‚ฌ์šฉํ•˜๋„๋ก ์ œ์•ฝํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋‹ค์Œ๊ธ€์—์„œ ์•Œ์•„๋ณด์ž.

class FileStorage<Key: Hashable, Location: FileStorageLocation> {
    ...    
}
 
// Model
extension Note {
    typealias LocalStorage = FileStorage<StorageKey, LocalFileStorageLocation>
    typealias CloudStorage = FileStorage<StorageKey, CloudStorageLocation>
}
 
class NoteSyncController {
    init(localStorage: Note.LocalStorage,
         cloudStorage: Note.CloudStorage) {
        ...
    }
}

Note model์•ˆ์— type alias๋ฅผ ๋‘์–ด ์‚ฌ์šฉํ•˜๋Š” ์ธก์—์„œ ๊ฐ€๋ณ๊ฒŒ ์“ธ ์ˆ˜ ์žˆ๋„๋ก ํ–ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด, ๊ตฌํ˜„์˜ ์„ธ๋ถ€์‚ฌํ•ญ ์—ญ์‹œ Model ๋‚ด๋ถ€๋กœ ์ˆจ๊ธธ ์ˆ˜ ์žˆ๋‹ค.

Type-driven Logic

๊ฐ๊ฐ์˜ object์— ๋Œ€ํ•œ id๋ฅผ ์ „๋ฐ˜์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ ๋‹ค๊ณ  ํ•ด๋ณด์ž. id์˜ ํŠน์ง•์„ Identifiable Protocol์— ์ •์˜ํ•˜๊ณ , ์ด๋ฅผ ๊ตฌํ˜„์ฒด๊ฐ€ ์ด๋ฅผ ์ฑ„ํƒํ•จ์œผ๋กœ์จ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ด๋ณด์ž. ๊ทธ๋Ÿฐ๋ฐ ์ด ๋•Œ, id๋ฅผ ํ‘œ์‹œํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ด๋ฅผ ๋Œ€ํ‘œํ•˜๋Š” ๊ฐ’์„ ๊ฐ€์ ธ์•ผ ํ•œ๋‹ค. ์ด๋Ÿด ๋•Œ associatedType์„ ํ™œ์šฉํ•ด์„œ ์ด๋ฅผ ์ •์˜ํ•œ๋‹ค.

protocol Identifiable {
    associatedtype RawIdentifier: Codable = String
 
    var id: Identifier<Self> { get }
}

๊ทธ๋ฆฌ๊ณ  ์ด๋ฅผ ์ค€์ˆ˜ํ•˜๋Š” ๊ตฌํ˜„์ฒด๋ฅผ ๋ฐ›๋Š” struct๋ฅผ ๋งŒ๋“ค์ž.

struct Identifier<Value: Identifiable> {
    let rawValue: Value.RawIdentifier
 
    init(rawValue: Value.RawIdentifier) {
        self.rawValue = rawValue
    }
}

Identifier ๊ตฌํ˜„์ฒด๋Š” Identifiable์„ ์ค€์ˆ˜ํ•˜๋Š” ๊ตฌํ˜„์ฒด๋ฅผ rawvalue๋กœ ๊ฐ€์ง„๋‹ค.

struct User: Identifiable {
    let id: Identifier<User>
    let name: String
}
 
struct Group: Identifiable {
    typealias RawIdentifier = Int
 
    let id: Identifier<Group>
    let name: String
}
 
let group = Group(id: Identifier<Group>(rawValue: 3), name: "wansik")

Identifiable์„ ์ค€์ˆ˜ํ•˜๋Š” ๋‘๊ฐœ์˜ struct๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค. ์ด ๋•Œ, User์˜ ๊ฒฝ์šฐ ๋ช…์‹œํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— RawIdentifier๊ฐ€ String์œผ๋กœ ๋ฐ˜์˜๋˜๊ณ , Group์˜ ๊ฒฝ์šฐ ๋ช…์‹œํ•˜์—ฌ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค. ์ฆ‰, Protocol์ด associatedType์œผ๋กœ type constraint๊ฐ€ ๋˜์–ด ์žˆ๋Š” ๊ฒฝ์šฐ, ์ด๋ฅผ ๋ช…์‹œํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ type alias๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

์ถ”๊ฐ€์ ์œผ๋กœ, ์œ„์™€ ๊ฐ™์€ ํ˜•์‹์œผ๋กœ ๊ตฌํ˜„ํ•  ๊ฒฝ์šฐ, id๋ฅผ type safeํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

Generic Closures

typealias Handler<T> = (Result<T>) -> Void
 
func searchForNotes(matching query: String,
                    then handler: @escaping Handler<[Note]>) {
    ...
}

๋ฐ˜๋ณต์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” completion Handler๋ฅผ type alias๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค. ์กฐ๊ธˆ๋” ์˜๋ฏธ์žˆ๋Š” ์ •๋ณด๋ฅผ ์ค„ ์ˆ˜ ์žˆ๋‹ค. ์‹คํŒจ์‹œ, ์„ฑ๊ณต์‹œ ๊ฐ๊ฐ์˜ handler๋ฅผ ์ด๋Ÿฐ์‹์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋ฉด ๋” ์ฝ๊ธฐ ์ข‹์€ ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ฒ ๋‹ค.

Reference