μλ νμΈμ, κ°μμ λλ€. μ€λμ Extensionμ λν΄μ 곡λΆν΄λ³Έ λ΄μ©μ μ 리νμ΄μ. κ·ΈλΌ μμ!
Swift Document chap.21 Extension λ°λ‘κ°κΈ°
Extensions (νμ₯, μ΅μ€ν μ )
Extension(μ΅μ€ν μ , νμ₯)μ κΈ°μ‘΄μ ν΄λμ€λ, ꡬ쑰체, μ΄κ±°ν λλ νλ‘ν μ½ νμ μ μλ‘μ΄ κΈ°λ₯μ μΆκ°νλ κΈ°λ₯μ΄λ€. μ΄λ μ€μ λ‘ ν΄λΉ νμ λ€μ΄ μ μλ μ½λμ μ κ·Όν μ μμ λμλ μ¬μ© κ°λ₯νλ€.
Swiftμ μ΅μ€ν μ μ λ€μκ³Ό κ°μ κΈ°λ₯μ μ 곡νλ€.
- μΈμ€ν΄μ€μ κ³μ° νλ‘νΌν°μ κ³μ° νμ νλ‘νΌν° μΆκ°
- μΈμ€ν΄μ€ λ©μλμ νμ λ©μλ μ μ
- μλΈ μ€ν¬λ¦½νΈ μ μ
- μλ‘μ΄ μ€μ²© νμ μ μ
- κΈ°μ‘΄ μ νμ΄ νΉμ νλ‘ν μ½μ μ€μνλλ‘ λ§λ€μ΄ μ£ΌκΈ°
Swiftμμλ νλ‘ν μ½μ νμ₯νμ¬ μꡬμ¬νμ ꡬνμ μ 곡νκ±°λ νλ‘ν μ½μ μΆκ° κΈ°λ₯μ μΆκ°ν μλ μλ€. νμ₯μΌλ‘ νμ μ μλ‘μ΄ κΈ°λ₯μ μΆκ°ν μλ μμ§λ§ κΈ°μ‘΄μ κΈ°λ₯μ μ€λ²λΌμ΄λ ν μλ μλ€.
Extension Syntax
μ΅μ€ν μ μ extension ν€μλλ‘ μ μΈνλ€.
extension SomeType {
// SomeType μ μΆκ°ν μλ‘μ΄ κΈ°λ₯μ μ¬κΈ°μ λ‘λλ€.
}
μ΅μ€ν μ μ κΈ°μ‘΄ νμ μ νμ₯νμ¬ νλ μ΄μμ νλ‘ν μ½μ μ±ννκ² ν μ μλ€. μ΄λ κ² νλ‘ν μ½μ μ±ννκΈ° μν΄μλ ν΄λμ€, ꡬ쑰체μμ μ±ννλ λ°©γ νκ³Ό λμΌν λ°©μμΌλ‘ νλ‘ν μ½ μ΄λ¦μ μμ±νλ©΄ λλ€.
extension SomeType: SomeProtocol, AnotherProtocol {
// νλ‘ν μ½μ νμ 쑰건 ꡬνμ μ¬κΈ°μ λ‘λλ€.
}
μ΄λ κ² νλ‘ν μ½μ μ±ννλ μμΈν λ°©λ²μ chap.22 νλ‘ν μ½ μμ λ°°μ°λλ‘ νμ.
μ΅μ€ν μ μ μ‘΄μ¬νλ generic νμ μλ μ μ©ν μ μλ€. Genericμ μ΅μ€ν μ μ μ μ©νλ λ°©λ²μ chap.23 Generic μμ μ΄ν΄λ³΄μ.
λ§μ½ μ΅μ€ν μ μ μ¬μ©νμ¬ κΈ°μ‘΄ νμ μ μλ‘μ΄ κΈ°λ₯μ μΆκ°νλ©΄, μΆκ°νκΈ° μ μ μμ±λ μΈμ€ν΄μ€λ€λ μλ‘μ΄ κΈ°λ₯μ μ¬μ©ν μ μλ€.
1. ExtensionμΌλ‘ κ³μ° νλ‘νΌν° (Computed Properties) μΆκ° νκΈ°
μ΅μ€ν μ μ κΈ°μ‘΄ νμ μ κ³μ° νλ‘νΌν°, κ³μ° νμ νλ‘νΌν°λ₯Ό μΆκ°ν μ μλ€.
λ€μ μμ λ Double νμ μ λ€μ―κ°μ κ³μ° μΈμ€ν΄μ€ νλ‘νΌν°λ₯Ό μΆκ°ν μ½λμ΄λ€.
extension Double {
var km: Double { return self * 1_000.0 }
var m: Double { return self }
var cm: Double { return self / 100.0 }
var mm: Double { return self / 1_000.0 }
var ft: Double { return self / 3.28084 }
}
let oneInch = 25.4.mm
print("One inch is \\(oneInch) meters")
// "One inch is 0.0254 meters" λ₯Ό μΈμν¨
let threeFeet = 3.ft
print("Three feet is \\(threeFeet) meters")
// "Three feet is 0.914399970739201 meters" λ₯Ό μΈμν¨
βΆοΈ μ½λμ€λͺ
μ΄ κ³μ° νλ‘νΌν°λ€μ Double κ°μ΄ νΉμ κΈΈμ΄ λ¨μλ‘ κ³ λ €λμ΄μΌ ν¨μ νννλ€. κ³μ° νλ‘νΌν°λ‘ ꡬνλκΈ΄ νμ§λ§, λΆλμμμ κΈμ κ°μ μ¨μ 거리 λ³νμ νλ λ°©λ²μΌλ‘ κ·Έ κΈμ κ°μ μ ꡬ문μΌλ‘ μ΄ νλ‘νΌν°λ€μ μ΄λ¦μ λ§λΆμΌ μ μλ€. (ex. .mm, .ft ...)
μ΄ μμ μμ 1.0 μ΄λΌλ Double κ°μ 1λ―Έν°λ₯Ό λνλ΄λ κ²μΌλ‘ κ³ λ €νλ€. κ·Έλμ κ³μ° νλ‘νΌν° mμ΄ self λ₯Ό λ°ννλ κ²μ΄λ€. 1.m μ΄λΌλ ννμμ 1.0μ΄λΌλ Double κ°μ κ³μ°νλ κ²μ΄λ€.
λ€λ₯Έ λ¨μλ₯Ό λ―Έν° μΈ‘μ κ°μΌλ‘ νννλ €λ©΄ μ΄λ ν λ³νμ΄ νμνλ€. 1km λ 1000m μ΄λ―λ‘, km κ³μ° μμ±μ 1_000.0μ κ³±νμ¬ λ―Έν°λ‘ ννν μλ₯Ό λ°ννλ€. μ΄μ λΉμ·νκ² 1 λ―Έν°λ 3.28084νΌνΈ μ΄λ―λ‘, ft κ³μ° μμ±μ μ€μ Double κ° 3.28084λ‘ λλμ΄μ νΌνΈλ₯Ό λ―Έν°λ‘ λ°ννλ€. μ΄ μμ±λ€μ μ½κΈ° μ μ©μ΄λ―λ‘, κ°κ²°ν¨μ μν΄ get ν€μλ μμ΄ νννλ€.
let aMarathon = 42.km + 195.m
print("A marathon is \\(aMarathon) meters long")
// "A marathon is 42195.0 meters long" μ μΈμν¨
μ μ½λμ²λΌ, μ΄λ€μ λ°νκ°μ Double νμ μ΄λ©°, Double νμ μ λ°μλ€μ΄λ κ³³λ§λ€ μμ μμμ μ¬μ©ν μ μλ€.
λ¨, μ΅μ€ν μ μ΄ κΈ°μ‘΄ μμ±μ μλ‘μ΄ κ³μ° μμ±μ μΆκ°ν μλ μμ§λ§, μ μ₯ νλ‘νΌν°λ νλ‘νΌν° μ΅μ λ²λ₯Ό μΆκ°ν μλ μλ€.
2. ExtensionμΌλ‘ μλ‘μ΄ μμ±μ (Initializers) μΆκ°νκΈ°
μ΅μ€ν μ μ κΈ°μ‘΄ νμ μ μλ‘μ΄ μμ±μλ₯Ό μΆκ°ν μ μλ€. μ΄λ₯Ό ν΅ν΄ νμ μ νμ₯νμ¬ μ»€μ€ν νμ μ μμ±μμ 맀κ°λ³μλ‘ λ°κ±°λ, μλ μλ μμ±μλ₯Ό μ 곡ν μ μλ€. μ΅μ€ν μ μ ν΄λμ€μ μλ‘μ΄ convenience μμ±μλ₯Ό μΆκ°ν μλ μμ§λ§, designated μμ±μλ μλ©Έμλ μΆκ°ν μ μλ€. μ΄λ¬ν λΆλΆμ νμ μ€μ ν΄λμ€ κ΅¬νλΆμμ μ μλμ΄μΌ νλ€.
μμ μ λͺ¨λ μ μ₯ νλ‘νΌν°μ defaultκ°μ μ 곡νλ©΄μ, μ΄λ€ μμ±μλ μ 곡νμ§ μμ κ° νμ μ μ΅μ€ν μ μΌλ‘ μμ±μλ₯Ό μΆκ°νλ©΄, μ΅μ€ν μ μ μμ±μ μμμ κ·Έ κ° νμ μ default μμ±μμ memberwise μμ±μλ₯Ό νΈμΆ ν μ μλ€.
λ€λ₯Έ λͺ¨λμμ μ μΈν ꡬ쑰체μ μ΅μ€ν μ μΌλ‘ μμ±μλ₯Ό μΆκ°νλ©΄, μλ‘μ΄ μμ±μκ° μ μ λͺ¨λμ μλ μμ±μλ₯Ό νΈμΆνκΈ° μ κΉμ§λ selfμ μ κ·Όν μ μλ€.
μλ μμ λ μ¬κ°νμ λνλ΄λ Rect ꡬ쑰체μ΄λ€. Sizeμ PointλΌλ λ κ°μ ꡬ쑰체λ μ μνλ€. λ ꡬ쑰체λ λ λ€ λͺ¨λ μμ±μ 0.0 μ΄λλ κΈ°λ³Έ κ°μ μ 곡νλ€.
struct Size {
var width = 0.0, height = 0.0
}
struct Point {
var x = 0.0, y = 0.0
}
struct Rect {
var origin = Point()
var size = Size()
}
Rect ꡬ쑰체λ μμ μ λͺ¨λ μμ±μ κΈ°λ³Έ κ°μ μ 곡νκΈ° λλ¬Έμ, μλμΌλ‘ default μμ±μμ memberwise μμ±μλ₯Ό λ°λλ€. μ΄ μμ±μλ€μ μ¬μ©νμ¬ μλ‘μ΄ RectμΈμ€ν΄μ€λ₯Ό μμ±ν μ μλ€.
let defaultRect = Rect()
let memberwiseRect = Rect(origin: Point(x: 2.0, y: 2.0), size: Size(width: 5.0, height: 5.0))
λ€μ μ½λλ Rect ꡬ쑰체λ₯Ό νμ₯νμ¬ νΉμ ν μ€μ¬μ κ³Ό ν¬κΈ°λ₯Ό μ·¨νλ μΆκ°μ μΈ μμ±μλ₯Ό μ μν μ½λμ΄λ€.
extension Rect {
init(center: Point, size: Size) {
let originX = center.x - (size.width / 2)
let originY = center.y - (size.height / 2)
self.init(origin: Point(x: originX, y: originY), size: size)
}
}
let centerRect = Rect(center: Point(x: 4.0, y: 4.0), size: Size(width: 3.0, height: 3.0))
// centerRect μ μμ μ (2.5, 2.5) μ΄κ³ , ν¬κΈ°λ (3.0, 3.0) μ
μ΄ μλ‘μ΄ μμ±μμ μμμ center λ° size κ°μ κΈ°μ΄νμ¬ μ μ ν μμ μ κ³μ°νλ κ²μ΄λ€. κ·Έλ° λ€μ μμ±μλ memberwise μμ±μλ₯Ό μλμΌλ‘ νΈμΆν΄μ μλ‘μ΄ κ°μ μ μ ν νλ‘νΌν°μ μ μ₯νλ€.(init) μ΄λ κ² μ΅μ€ν μ μΌλ‘ μΆκ°ν μμ±μλ μ΄κΈ°νκ° μλ£λλ©΄ μΈμ€ν΄μ€κ° μμ ν μ΄κΈ°ν λλλ‘ ν΄μΌνλ€.
3. ExtensionμΌλ‘ μΈμ€ν΄μ€ λ©μλ (Methods), νμ λ©μλ μΆκ°νκΈ°
μ΅μ€ν μ μ κΈ°μ‘΄ νμ μ μλ‘μ΄ μΈμ€ν΄μ€ λ©μλ λ° νμ λ©μλλ₯Ό μΆκ°ν μ μλ€. λ€μ μμ λ Int νμ μ repetitions μ΄λΌλ μ μΈμ€ν΄μ€ λ©μλλ₯Ό μΆκ°ν μ½λμ΄λ€.
extension Int {
func repetitions(task: () -> Void) {
for _ in 0..<self {
task()
}
}
}
repetition(task: )λ©μλλ () -> Void νμ μ λ¨μΌ μΈμλ₯Ό μ·¨νλλ°, μ΄λ 맀κ°λ³μλ μκ³ κ°λ λ°ννμ§ μλ ν¨μλ₯Ό μ§μνλ€.
μ΄ μ΅μ€ν μ μ μ νμλ μ΄λ€ μ μμμλ repetition(task: ) λ©μλλ₯Ό νΈμΆνμ¬ κ·Έ νμ λ§νΌ μ무λ₯Ό μνν μ μλ€.
3.repetitions {
print("Hello!")
}
// Hello!
// Hello!
// Hello!
3.1 Mutating Instance Methods (λ³κ²½ μΈμ€ν΄μ€ λ©μλ)
μ΅μ€ν μ μΌλ‘ μΆκ°ν μΈμ€ν΄μ€ λ©μλλ κ·Έ μ체λ₯Ό μμ λλ λ³κ²½ (Mutate) ν μ μλ€. ꡬ쑰체μ μ΄κ±°νμ λ©μλλ κ° νμ μ΄λ―λ‘ μ체μ μΌλ‘ μμ νκΈ° μν΄μλ mutating ν€μλλ₯Ό ν¨κ» μ¬μ©ν΄μ λ©μλλ₯Ό μΆκ°ν΄μΌ νλ€.
extension Int {
mutating func square() {
self = self * self
}
}
var someInt = 3
someInt.square()
// someInt λ μ΄μ 9 μ
4. ExtensionμΌλ‘ μλ‘μ΄ μλΈμ€ν¬λ¦½νΈ (Subscripts) μΆκ°νκΈ°
μ΅μ€ν μ μ κΈ°μ‘΄ νμ μ μλ‘μ΄ μλΈμ€ν¬λ¦½νΈλ₯Ό μΆκ°ν μ μλ€.
λ€μ μμ λ μ€μννΈ λ΄μ₯ Int νμ μ μ μ μλΈμ€ν¬λ¦½νΈλ₯Ό μΆκ°νλ μ½λμ΄λ€. [n] μ΄λΌλ μ΄ μλΈμ€ν¬λ¦½νΈλ μμΉ κ° μ€λ₯Έ μͺ½μμ n λ²μ§Έ μ리μ 10μ§ μ«μλ₯Ό λ°ννλ€.
- 123456789[0] μ 9 λ₯Ό λ°ν
- 123456789[1] μ 8μ λ°ν
extension Int {
subscript**(digitIndex: Int) -> Int {
var decimalBase = 1
for _ in 0..<digitIndex {
decimalBase *= 10
}
return (self / decimalBase) % 10
}
}
746381295[0]
// 5 λ₯Ό λ°νν¨
746381295[1]
// 9 λ₯Ό λ°νν¨
746381295[2]
// 2 λ₯Ό λ°νν¨
746381295[8]
// 7 μ λ°νν¨
Int κ°μ μμ²ν n μ΄ λ²μλ₯Ό λμ΄κ°λ©΄, 0μ λ°ννλ€.
746381295[9]
// λ§μΉ μ΄λ κ² μμ²ν κ²μ²λΌ, 0 μ λ°νν¨:
0746381295[9]
5. ExtensionμΌλ‘ κΈ°μ‘΄ ν΄λμ€, ꡬ쑰체, μ΄κ±°νμ μ€μ²© νμ (Nested Type) μΆκ°νκΈ°
μ΅μ€ν μ μ κΈ°μ‘΄μ ν΄λμ€, ꡬ쑰체, μ΄κ±°νμ μλ‘μ΄ μ€μ²© νμ μ μΆκ°ν μ μλ€.
extension Int {
enum Kind {
case negative, zero, positive
}
var kind: Kind {
switch self {
case 0:
return .zero
case let x where x > 0:
return .positive
default:
return .negative
}
}
}
μ΄ μ½λλ Intμ μλ‘μ΄ μ€μ²© μ΄κ±°νμ μΆκ°νλ€. KindλΌλ μ΄ μ΄κ±°νμ ν νΉλ³ν μ μκ° λνλ΄λ μμΉ κ°μ μ’ λ₯λ₯Ό λνλΈλ€. μμΉ κ°μ΄ μμμΈμ§, 0, μμμΈμ§λ₯Ό ννν΄μ€λ€.
λλ²μ§Έ λ¨λ½μμ, κ·Έ μ μμ λν μ μ ν Kind μ΄κ±°νμ λ°ννλ, kind(μλ¬Έμ) λΌλ μλ‘μ΄ μΈμ€ν΄μ€ μμ±λ Intμ μΆκ°ν΄μ£Όμλ€.
func printIntegerKinds(_ number: [Int]) {
for number in numbers {
switch number.kind {
case .negative:
print("- ", terminator: "")
case .zero:
print("0 ", terminator: "")
case .positive:
print("+ ", terminator: "")
}
}
print("")
}
printIntegerKinds([3, 19, -27, 0, -6, 0, 7])
// "+ + - 0 - 0 + " λ₯Ό μΈμν¨
μμμ μΆκ°ν Kind μ΄κ±°νμ μ¬μ©νμ¬ printIntegerKinds(_: ) λ©μλλ₯Ό μ μνλ€. μ΄ ν¨μλ μ΄λ ν μ μμ λνμ¬ μμλ©΄ -, μμλ©΄ +, 0μ΄λ©΄ 0μ μΆλ ₯νλ€.