[Swift] Extension 확장

임주희·2022년 9월 14일
1

Extension 확장

스위프트에서는 전역 함수나 서브클래싱 할 필요 없이 확장을 사용해 이미 존재하는 타입에 기능을 추가할 수 있다.

https://docs.swift.org/swift-book/LanguageGuide/Extensions.html



기존 객체지향 프로그래밍 언어에서는 기능을 추가하고자 할때 서브클래싱 하여 기능을 추가했다.

  • 원본 클래스의 모든 인스턴스를 새로운 서브 클래스의 인스턴스로 변경해야 한다..
  • 참조 타입만 서브클래싱이 가능하다.
    (스위프트 표준 라이브러리 대부분이 값 타입으로 이뤄졌다. 서브클래싱하여 기능을 추가할 수 없다.)

반면 확장을 사용하면

  • 타입에 새로운 기능을 직접 추가할 수 있다.
    이는 해당 타입의 모든 인스턴스를 수정할 필요없이 새로운 기능을 받게된다는 것을 의미한다.
  • 또한 모든 타입(값 타입, 참조타입, 프로토콜 타입)이 확장이 가능하다.
  • 스위프트 표준 라이브러리에 있는 타입뿐만 아니라 프레임워크, 라이브러리에 있는 타입에 기능을 추가할 수 있다.
    → 프레임워크에 기능을 추가하는 경우, 프레임워크 자체의 소스를 변경하지 않고 확장을 사용해 기능을 추가할 수 있어 프레임워크 버전관리 및 유지 보수에 훨씬 유리하다.
  • 확장은 기능을 추가하게 설계되었으며, 타입의 기능을 변경하는 의미로 설계되지는 않았다.
  • 저장 프로퍼티는 추가할 수 없다.
  • 연산 프로퍼티 추가는 가능하다.

스위프트 표준 라이브러리 타입 중 Int를 확장하여 팩토리얼 메소드 추가하기

// 팩토리얼 만들기
// 5! == 5*4*3*2*1
// 5! == 120

extension Int {
	func factorial() -> Int {
		var answer = 1
		
		for x in (1...self).reversed(){
			answer *= x
		}
		return answer
	}
}
print(5.factorial()) // 120

프로토콜 확장

프로토콜 확장은 특정 프로토콜을 따르는 모든 타입에 공통적인 기능을 제공하기 위해 사용된다.

extension Collection {
	func shuffle() -> [Interator.Element] {
		return sorted(){ left, right in
			return arc4random() < arc4random()
		}
	}
}

var originArray = [1,2,3,4,5]
var ranArray = originArray.shuffle() //← 구현안하고 바로 사용함 

Collection 프로토콜을 따르는 모든 타입은 shuffle() 함수를 받게 될 것이다.

→ 프로토콜 확장에 정의된 메서드는 요구사항에 포함되지 않는다. 프로토콜을 따르는 타입에서 해당 메서드를 구현하지 않고 바로 사용할 수 있다.


프로토콜 확장에서 정의된 기능을 전달받을 수 있는 타입을 제한하는 제약 을 확장에 추가할 수도 있다.

  • Where 키워드를 사용
// Collection 프로토콜 확장에서는 ExpressibleBytArrayLiteral 프로토콜을 따르는 타입만 확장에서 정의한 기능을 전달 받을 수 있다.
extension Collection where Self: ExpressibleBytTrrayLiteral {
	// 확장 코드 ...
}
// 컬렉션 안에 있는 요소가 Comparable 프로토콜을 따르도록
extension Collection where Iterator.Element: Comparable {
	...
}

[출처] 스위프트4 프로토콜지향 프로그래밍 3/e, 존 호프만 저
[참고] Swift LanguageGuide (https://docs.swift.org/swift-book/LanguageGuide/Generics.html)

0개의 댓글

관련 채용 정보