티스토리 뷰

Swift

[Swift] Extensions

learner._.Kio 2021. 4. 20. 15:33

목차

  • Extension
  • Adding Properties
  • Adding Methods
  • Adding Initializers
  • Adding Subscripts

Extension

Extension은 이름 그대로 형식을 확장한다는 것이다.
Extension으로 확장할 수 있는 대상은 Class, Structure, Enumberation, Protocol

  • Adding Members 🆗
  • Overriding Members ❌

 

Extension 정의

extension Type {
    computedProperty
    computedTypeProperty
    instanceMethod
    typeMethod
    initializer
    subscript
    NestedType
}

extension Type: Protocol, ... {
    requirements
}
  • 속성은 계산 속성으로 제한된다.

 

Extension 예시

struct Size {
    var width = 2
    var height = 3
}

extension Size {
    var area: Int {
        return width * height
    }
}

let a = Size()
a.width // 2
a.height // 3
a.area // 6
  • 원본을 수정할 수 있다면 굳이 Extension을 사용하지 않아도 된다.
  • 하지만, 원본을 수정할 수 없다면 Extension으로 새로운 것을 구현할 수 있다. 
extension Size: Equatable {
    public static func == (lhs: Size, rhs: Size) -> Bool {
        return lhs.width == rhs.width && lhs.height == rhs.height
    }
}
  • 여기에서는 익스텐션을 사용해서 프로토콜 사용을 추가할 수 있다고만 기억하자

Adding Properties

extension 속성 더하기 예시1

extension Date {
    var year: Int {
        let cal = Calendar.current
        return cal.component(.year, from: self)
    }
    
    var Month: Int {
        let cal = Calendar.current
        return cal.component(.month, from: self)
    }
}

let today = Date()
today.year // 2021
today.Month // 4

 

extension 속성 더하기 예시2

extension Double {
    var radianValue: Double {
        return (Double.pi * self) / 180.0
    }
    
    var degreeValue: Double {
        return self * 180.0 / Double.pi
    }
}

let dv = 45.0
dv.radianValue // 0.7853981633974483
dv.radianValue.degreeValue // 45
  • 1 radian = 약 57.3도

Adding Methods

Double 형식에 화씨/섭씨 온도 변환 메소드 추가

extension Double {
    func toFahrenheit() -> Double {
        return self * 9 / 5 + 32
    }
    
    func toCelsius() -> Double {
        return (self - 32) * 5 / 9
    }
    
    static func converToFahrenheit(from celsius: Double) -> Double {
        return celsius.toFahrenheit()
    }
}


let c = 30.0
c.toFahrenheit() // 86
Double.converToFahrenheit(from: 30) // 86

 

Date 형식에 문자열 포멧팅 메소드 추가

extension Date {
    func toString(format: String = "yyyyMMdd") -> String {
        let privateFormatter = DateFormatter()
        privateFormatter.dateFormat = format
        return privateFormatter.string(from: self)
    }
}

let today = Date() // "Apr 20, 2021 at 4:13 PM"
today.toString() // "20210420"

today.toString(format: "MM/dd/yyyy") // "04/20/2021"

 

String 형식에 랜덤 문자열 생성 메소드 추가

extension String {
    static func random(length: Int, charactersIn chars: String = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") -> String {
        var randomString = String()
        randomString.reserveCapacity(length)
        
        for _ in 0 ..< length {
            guard let char = chars.randomElement() else {
                continue
        }
        
            randomString.append(char)
        }
    
        return randomString
    }
}

String.random(length: 5) // "NWYbx"

Adding Initializers

Date 형식에 년,월,일로 초기화 하는 생성자 추가

extension Date {
    init?(year: Int, month: Int, day: Int) {
        let cal = Calendar.current
        var comp = DateComponents()
        comp.year = year
        comp.month = month
        comp.day = day
        
        guard let date = cal.date(from: comp) else {
            return nil
        }
        
        self = date
    }
}

Date(year: 2021, month: 4, day: 20) // "Apr 20, 2021 at 12:00 AM"


UIColor 클래스에 RGB 파라미터를 받는 생성자 추가

extension UIColor {
    convenience init(red: Int, green: Int, blue: Int) {
        self.init(red: CGFloat(red) / 255, green: CGFloat(green) / 255, blue: CGFloat(blue) / 255, alpha: 1.0)
    }
}

UIColor(red: 0, green: 0, blue: 0) // r 0.0   g 0.0   b 0.0   a 1.0


익스텐션으로 생성자를 구현할 때의 장점

struct Size {
    var width = 0.0
    var height = 0.0
}


extension Size {
    init(value: Double) {
        width = value
        height = value
    }
}

Size()
Size(width: 12, height: 34)

Adding Subscripts

String 형식에 정수 인덱스를 처리하는 서브스크립트 추가

extension String {
    subscript(idx: Int) -> String? {
        guard (0..<count).contains(idx) else {
            return nil
        }
        
        let target = index(startIndex, offsetBy: idx)
        return String(self[target])
    }
}


let str = "Swift"
str[1] // w
str[100] // nil


Date 형식에 컴포넌트를 리턴하는 서브스트립트 추가

extension Date {
    subscript(componet: Calendar.Component) -> Int? {
        let cal = Calendar.current
        return cal.component(componet, from: self)
    }
}

let today = Date() // "Apr 20, 2021 at 4:52 PM"
today[.year] // 2021
today[.month] // 4
today[.day] // 20

'Swift' 카테고리의 다른 글

[Swift] Generic  (0) 2021.03.23
[Swift] Error Handling  (0) 2021.03.16
[Swift] Property  (0) 2021.03.11
[Swift] Collection - Array, Dictionary, Set  (0) 2021.03.09
[Swift] Structures and Classes  (0) 2021.03.08
댓글