멤버의 확장(계산 속성)
- 확장을 사용하면 기존 타입에 새로운 기능을 추가할 수 있다
- 특히 계산 속성(타입 계산 속성, 인스턴스 계산 속성)을 추가하여 값을 연산하여 반환할 수 있다
(타입) 계산 속성의 확장 (예시: String)
extension String {
static var defaultGreeting: String {
return "Hello, Swift!"
}
}
print(String.defaultGreeting)
String 타입에 새로운 타입 계산 속성 defaultGreeting을 추가하였다
- 이 계산 속성은 항상
"Hello, Swift!" 라는 값을 반환한다
- 타입 계산 속성이기 때문에 타입 자체에서 호출할 수 있다 (
String.defaultGreeting)
- 확장을 사용하면 기존 타입을 수정하지 않고도 새로운 기능을 추가할 수 있다
(인스턴스) 계산 속성의 확장 (예시: String)
extension String {
var wordCount: Int {
return self.split(separator: " ").count
}
var reversedString: String {
return String(self.reversed())
}
}
let myString = "Swift programming is fun"
print(myString.wordCount)
print(myString.reversedString)
String 타입에 두 가지 인스턴스 계산 속성 wordCount와 reversedString을 추가하였다
wordCount: 공백을 기준으로 문자열을 나누어 단어의 개수를 반환한다
reversedString: 문자열을 뒤집어서 반환한다
- 계산 속성은 읽기 전용으로 정의되었으며, 값을 변경할 수는 없다
- 기존의
String 인스턴스에서도 이 기능을 사용할 수 있다 (myString.wordCount, myString.reversedString)
(인스턴스) 계산 속성 확장의 장점 예시 (예시: Date)
import Foundation
extension Date {
var formatted: String {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
return formatter.string(from: self)
}
var dayOfWeek: String {
let formatter = DateFormatter()
formatter.dateFormat = "EEEE"
return formatter.string(from: self)
}
}
let now = Date()
print(now.formatted)
print(now.dayOfWeek)
Date 타입에 두 가지 인스턴스 계산 속성을 추가하였다 (formatted, dayOfWeek)
formatted: 현재 날짜와 시간을 문자열로 반환한다 (포맷 지정 가능)
dayOfWeek: 현재 날짜의 요일을 반환한다 (예: Monday, Tuesday 등)
- 기존의
Date 인스턴스에서도 이 기능을 사용할 수 있다 (now.formatted, now.dayOfWeek)
- 확장을 사용하면 기존의 타입을 수정하지 않고도 매우 유용한 기능을 추가할 수 있다
(인스턴스) 계산 속성 확장의 장점 예시 (예시: Array)
extension Array where Element == Int {
var sum: Int {
return self.reduce(0, +)
}
var average: Double {
return self.isEmpty ? 0.0 : Double(self.sum) / Double(self.count)
}
}
let numbers = [10, 20, 30, 40, 50]
print(numbers.sum)
print(numbers.average)
Array 타입을 확장하여 Int 타입 배열에 새로운 계산 속성을 추가하였다
sum: 배열의 모든 요소를 더해서 반환한다
average: 배열의 평균값을 계산하여 반환한다
- 기존의
Array 인스턴스에서도 이 기능을 사용할 수 있다 (numbers.sum, numbers.average)
- 제네릭 확장을 활용하여 특정 타입(
Int)의 배열에만 기능을 추가할 수 있다
요약
- 확장을 사용하면 기존 타입을 수정하지 않고도 새로운 기능을 추가할 수 있다
- 타입 계산 속성과 인스턴스 계산 속성을 추가하여 기능을 확장할 수 있다
- 기존의 인스턴스에서도 확장에서 정의한 기능을 사용할 수 있다 (예:
numbers.sum, myString.wordCount)
- 확장은 코드의 가독성과 사용성을 크게 개선할 수 있다
- 특정 타입(예:
Int 배열)에만 기능을 추가할 수도 있다 (제네릭 확장)
멤버의 확장(메서드)
- 확장을 사용하면 기존 타입에 새로운 메서드를 추가할 수 있다
- 타입 메서드와 인스턴스 메서드 모두 확장을 통해 추가할 수 있다
- 구조체나 열거형에서 자기 자신을 변경하는 메서드를 구현할 때는
mutating 키워드가 필요하다
(타입) 메서드의 확장 (예시: Double)
extension Double {
static func random(in range: ClosedRange<Double>) -> Double {
let diff = range.upperBound - range.lowerBound
let randomValue = Double(arc4random()) / Double(UInt32.max)
return range.lowerBound + randomValue * diff
}
static func average(_ value1: Double, _ value2: Double) -> Double {
return (value1 + value2) / 2
}
}
let randomValue = Double.random(in: 1.0...10.0)
print("랜덤 값: \(randomValue)")
let averageValue = Double.average(5.0, 10.0)
print("평균 값: \(averageValue)")
Double 타입에 두 가지 타입 메서드를 추가하였다
• random(in:): 주어진 범위에서 랜덤한 Double 값을 반환한다
• average(_:_:): 두 개의 Double 값 사이의 평균값을 반환한다
- 확장을 사용하여 기존 타입을 수정하지 않고 새로운 타입 메서드를 추가하였다
- 타입 메서드이기 때문에
Double.random(in:) 또는 Double.average(_:_) 형식으로 호출한다
(인스턴스) 메서드의 확장 (예시: String)
extension String {
func containsWord(_ word: String) -> Bool {
return self.components(separatedBy: " ").contains(word)
}
func printRepeatedly(times: Int) {
for _ in 0..<times {
print(self)
}
}
}
let sentence = "Swift programming is fun"
print(sentence.containsWord("Swift"))
print(sentence.containsWord("Python"))
"Hello".printRepeatedly(times: 3)
String 타입에 두 가지 인스턴스 메서드를 추가하였다
• containsWord(_:): 문자열에 특정 단어가 포함되어 있는지 확인한다
• printRepeatedly(times:): 문자열을 주어진 횟수만큼 출력한다
- 인스턴스 메서드이기 때문에 기존의
String 인스턴스에서 호출할 수 있다 (sentence.containsWord("Swift"))
- 확장을 통해 기능을 추가하므로 기존의
String 타입을 수정하지 않아도 된다
mutating 인스턴스 메서드의 확장 (예시: Array)
구조체나 열거형에서, 자신의 속성을 변경하는 메서드는 mutating 키워드가 필요하다
extension Array where Element: Comparable {
mutating func sortAscending() {
self = self.sorted()
}
mutating func doubleValues() where Element == Int {
self = self.map { $0 * 2 }
}
}
var numbers = [5, 2, 9, 1, 7]
numbers.sortAscending()
print(numbers)
var intNumbers = [1, 2, 3, 4, 5]
intNumbers.doubleValues()
print(intNumbers)
Array 타입에 두 가지 mutating 인스턴스 메서드를 추가하였다
• sortAscending(): 배열의 요소를 오름차순으로 정렬한다 (self를 변경하므로 mutating 필요)
• doubleValues(): Int 타입의 배열에만 적용되며, 모든 값을 두 배로 만든다
mutating 키워드는 구조체와 열거형에서 자신을 변경할 수 있도록 허용한다
- 확장을 사용하면 기존 타입의 메서드를 더욱 유용하게 만들 수 있다
요약
- 확장을 사용하여 기존 타입에 새로운 타입 메서드 및 인스턴스 메서드를 추가할 수 있다
mutating 키워드를 사용하여 구조체나 열거형의 속성을 변경하는 메서드를 확장할 수 있다
- 기존의 인스턴스에서도 확장에서 정의한 메서드를 사용할 수 있다
- 확장은 기존 타입을 수정하지 않고도 기능을 추가할 수 있는 강력한 도구이다