티스토리 뷰
Extension을 이용해 클래스, 구조체, 열거형 혹은 프로토콜 타입에 기능을 추가할 수 있습니다.
원본 코드를 몰라도 해당 타입에 대한 기능을 확장할 수 있습니다.
특징
- 계산된 인스턴스 프로퍼티와 계산된 타입 프로퍼티의 추가
- 인스턴스 메소드와 타입 메소드의 추가
- 새로운 이니셜라이저 제공
- 서브스크립트 정의
- 중첩 타입의 선언과 사용
- 특정 프로토콜을 따르는 타입 만들기
NOTE
Extension은 타입에 새 기능을 추가할 수 있지만 재정의 (Override) 는 할 수 없습니다.
Extension 문법 (Extension Syntax)
extension 키워드를 사용해 선언합니다.
extension SomeType {
// new functionality to add to SomeType goes here
}
한개의 extension에서 여러개의 프로토콜을 채택하도록 할 수 있습니다.
extension SomeType: SomeProtocol, AnotherProtocol {
// implementation of protocol requirements goes here
}
하지만, 가독성을 위해 하나씩 1 extension , 1 protocol 로 하는편 입니다.
좋은예)
extension SomeType: SomeProtocol {
// implementation of protocol requirements goes here
}
extension SomeType: AnotherProtocol {
// implementation of protocol requirements goes here
}
연산 프로퍼티 (Computed Properties)
extension을 이용해 존재하는 타입에 연산 프로퍼티와 타입 프로퍼티를 추가할 수 있습니다.
아래 예제는 Double 타입에 5개의 연산 프로퍼티를 추가하는 예제 입니다.
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")
// Prints "One inch is 0.0254 meters"
let threeFeet = 3.ft
print("Three feet is \(threeFeet) meters")
// Prints "Three feet is 0.914399970739201 meters"
기존 Double이라는 타입에 km, m, cm, mm, ft 의 단위를 붙여 meter로 변경하는 연산 프로퍼티 입니다.
단위 변환은 m(미터)를 기준으로 합니다.
이 프로퍼티들은 읽기 전용 연산 프로퍼티이기 때문에 간결함을 위해 get이 생략 되었습니다.
아래와 같이 각 변환 값의 연산도 가능합니다.
let marathon = 42.km + 195.m
print("A marathon is \(marathon) meters long")
// Prints "A marathon is 42195.0 meters long"
NOTE
extension은 저장 프로퍼티나 프로퍼티 옵저버를 추가할 수 없습니다.
이니셜라이저 (Initializers)
class에 새로운 편의 이니셜라이져 (convenience initializer)를 추가할 수 있습니다.
지정 이니셜라이저(designated) 디이니셜라이저(deinitializers)는 추가할 수 없음
designated init은 class의 모든 저장 프로퍼티들의 초기화를 책임지고 super.init 관련 일을 수행하기 때문
struct의 경우 Init을 추가할 수 있고, class의 편의 이니셜라이저 처럼 추가한 init 안에서 struct가 제공하는 memberwise init을 불러서
나머지 프로퍼티들에 대한 초기화를 해주면 됩니다.
아래는 extension을 활용한 중앙 지점을 통해 직사각형을 생성하는 init을 추가한 예시 입니다.
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()
}
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) // memberwise init 호출
}
}
메소드 (Methods)
extension을 이용해 존재하는 타입에 인스턴스 메소드나 타입 메소드를 추가할 수 있습니다.
다음 예제는 Int타입에 repetitions라는 인스턴스 메소드를 추가한 예제 입니다.
extension Int {
func repetitions(task: () -> Void) {
for _ in 0..<self {
task()
}
}
}
5.repetitions {
print("호")
}
// 호
// 호
// 호
// 호
// 호
repetitions(task:) 메소드는 () -> Void 타입의 하나의 인자를 받고 파라미터, 반환 값이 없는 함수 입니다.
함수를 실행하면 함수 안의 task를 repetitions앞에 지정한 숫자만큼 반복 실행합니다.
변경 가능한 인스턴스 메소드 (Mutating Instance Methods)
extension에서 추가된 인스턴스 메소드는 인스턴스 자신(self)을 변경할 수 있습니다.
또한 구조체와 열거형에서 자기 자신(self)을 변경하는 인스턴스 메소드는 mutating 메소드를 사용해줍니다.
(구조체, 열거형에서는 인스턴스 메소드로 내부 데이터를 변경할 수 없기 때문)
아래는 mutating 메소드를 추가, 호출하는 예제입니다.
extension Int {
mutating func square() {
self = self * self
}
}
var someInt = 3
someInt.square()
// someInt is now 9
서브스크립트 (Subscripts)
extension을 이용해 존재하는 타입에 새로운 서브스크립트를 추가할 수 있습니다.
아래는 Int 타입에 서브스크립트를 추가한 예제 입니다.
extension Int {
subscript(digitIndex: Int) -> Int {
var decimalBase = 1
for _ in 0..<digitIndex {
decimalBase *= 10
}
return (self / decimalBase) % 10
// 10 * n번째 수로 현재 수를 나눈 것의 나머지
}
}
746381295[0]
// returns 5
746381295[1]
// returns 9
746381295[2]
// returns 2
746381295[8]
// returns 7
// 만약 Int 값에서 요청한 값이 처리할 수 있는 자릿 수를 넘어가면 서브스크립트 구현에서 0을 반환 합니다.
// 9로 처리할 수 있는 자릿 수를 넘어가면 0을 반환
746381295[9]
// return 0
0746381295[9]
// return 0
풀이
// 746381295[0]
extension Int {
subscript(digitIndex: 0) -> Int {
var decimalBase = 1
for _ in 0..<0 {
// decimalBase *= 10
반복문 통과
}
return (self / 1) % 10
// 746381295 % 10 = 5
// return 5
}
}
// 746381295[1]
extension Int {
subscript(digitIndex: 1) -> Int {
var decimalBase = 1
for _ in 0..<1 {
1 *= 10
// decimalBase = 10
}
return (self / decimalBase) % 10
// 746381295 / 10 = 74638129.5
// 74638129.5 % 10 = 9
// return 9
}
}
중첩 타입 (Nested Types)
extension을 이용해 존재하는 클래스, 구조체, 열거형에 중첩 타입을 추가할 수 있습니다.
아래는 Int에 중첩형 enum을 추가한 예제 입니다.
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
}
}
}
3.kind
// positive
0.kind
// zero
열거형 Kind는 Int를 음수, 0, 양수로 표현 합니다.
아래 예제는 새로운 연산 프로퍼티 kind를 이용해 특정 수가 음수, 0, 양수 중 어떤 것인지 나타내는 예제 입니다.
func printIntegerKinds(_ numbers: [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])
// Prints "+ + - 0 - 0 + "
'iOS' 카테고리의 다른 글
[Swift] ~= 연산자 (0) | 2022.07.13 |
---|---|
[iOS] Unit Test (0) | 2022.07.10 |
[Swift] 중첩 타입 (Nested Types) (0) | 2022.06.24 |
[iOS] indexPath.row , IndexPath.item 의 차이점 (0) | 2022.06.22 |
[Swift] ARC (Automatic Reference Counting) (0) | 2022.06.19 |
- Total
- Today
- Yesterday
- Swift 내림차순
- swift reduce
- swift protocol
- Combine: Asynchronous Programming with Swift
- Swift RIBs
- Swift init
- RTCCameraVideoCapturer
- swift 고차함수
- Swift joined
- Swift
- removeLast()
- RIBs tutorial
- Swift inout
- Swift ModernRIBs
- swift programmers
- Swift 프로그래머스
- Class
- Swift joined()
- CS 네트워크
- Swift 프로퍼티
- Swift Leetcode
- ios
- 2023년 회고
- Swift 알고리즘
- iOS error
- Swift Error Handling
- Swift final
- swift property
- 원티드 프리온보딩
- swift (programmers)
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |