[ Swift ] .self .Type .Protocol Self

2020. 10. 7. 17:57Terminology

Metatype

 

타입의 타입

struct Medium {
	static let author = "hebaek"
	func postArticle(name: String) {}
}

let blog: Medium = Medium()

여기서 Medium()instance이고, Medium은 instance를 나타내는 type인것 안다.

 

blog라는 이름으로 생성한 instance에서는 instance method에서는 

postArticle()를 호출할 수 있지만, class propertyauthor에는 접근할 수 없습니다.

 

 

자자 그럼 author에는 어떻게 접근할까요??

 

▶Medium.author를 사용하면 되잖쇼 !

맞아요. class property에 접근하는 가장 흔한 방식이죠. 이것 말고도 다른 방법이 있을까요?

 

▶type(of: blog).author를 사용하쇼 !

그렇습니다. instancetype(of:) 함수 안에 넣는 방법으로도 class property에 접할 수 있습니다.

 

그러면 대체 type(of: blog) 의 타입은 뭐길래 이게 가능한걸까요?

let something = type(of: blog) // Medium.Type

Medium(blog)typeMedium.Type이었네요 !! 조금 이상한것 같긴 하지만

이게 바로 Mediummetatype입니다. 타입의 타입 !

 

 

 

이렇게 메타 타입을 가지고 아래와 같이 init()함수클래스 프로퍼티(author), 메소드(init())를 사용할 수 있어요.

type을 기반으로 한 전반적인 동작을 할 때 유용하겠죠?

let author: String = something.author
let instance: Medium = something.init()

 

 

이런 동작들을 generic한 방식으로도 쉽게 할 수 있어요. metatype을 argument로 넘길 수 있으니까 말이죠!

func createWidget<T: Widget>(ofType: T.Type) -> T {
	let widget = T.init()
	myWidgets.insert(Widget)
	return Widget
}

 

 

Metatype은 아래와 같이 equality check에도 사용될 수 있습니다. 포스팅 저자는 개인적으로 factory 디자인을 할 때 유용하다고 느꼈다네요 ~

func create<T: BlogPost>(blogType: T.Type) -> T {
	switch blogType{
    	case is TutorialBlogPost.Type:
        	return blogType.init(subject: currentSubject)
        case is ArticleBlogPost.Type:
        	return blogType.init(subject: getLatestFeatures().random())
        case is TipBlogPost.Type:
        	return blogType.init(subject: getKnowledge().random())
        default:
        	fatalError("Unknown blog kind!")
        }
}