티스토리 뷰

@1편에서는 매크로가 뭔지에 대해, 2편에서는 매크로의 role이 뭔지, 그 중 freestanding 매크로에 대해 작성해봤는데, 이번에는 macro의 role중 attached macro에 대해 써보려고 합니다.

 

macro roles

freestanding매크로의 경우에는 오직 전달된 인수만 받는데, attached매크로의 경우에는 매크로와 연결된 선언부분에 대한 정보를 가져올 수도 있다는 차이점이 있습니다.

@attached(peer)

attached peer매크로는 매크로가 적용된 선언부분 옆에 새로운 선언을 만들 수 있습니다.

예를들어, async함수인 fetchAvatar()라는 함수를 만들었다고 했을 때, 옛날 방식인 completion방식도 필요하다고 생각해봅시다.

그러면 async함수를 작성한 후, 또 매개변수에 onCompletion을 추가하고, return값을 없애서 예전 방식의 선언도 하나 새로 만들어줘야 합니다. 

 

근데 이렇게 새로운 async방식, 예전 completion방식이 100개의 API에서 둘다 필요하다면.. 이걸 다 두개씩 적어줘야 할까요?

이 작업을 직접하지 않고 매크로가 대신 하게 해 줄 수 있습니다!

AddCompletionHandler라는 peer attached 매크로를 만들고, parameterName으로 completion의 파라미터 이름을 받아줍니다.

그리고 만들어준 async함수에 매크로를 적용해줍니다.

 

이렇게 해주면 Swift가 알아서 새로운 completion버전의 코드를 작성해줍니다!

 

Swift가 원래 선언을 가지고 새로운 선언을 만든것이죠 ㅎㅎ 이럴때 peer 매크로를 사용하면 됩니다!

 

@attached(accessor)

attached accessor 매크로는 변수나 subscript들에 첨부될 수 있고, get, set, willSet, didSet 같은 것들을 추가할 수 있습니다!

 

만약 이런 코드가 있다고 해봅시다.

 

이 코드는 dictinary가 있고, 이 딕셔너리에 접근할 수 있는 키가 정의되어 있는 변수들 (ex. name, height, birthDate)이 있습니다. 만약 딕셔너리에 키를 추가한다고 하면, 추가하는 변수에 get, set을 또 똑같이 정의해줘야 할 것입니다.. 귀찮죠? ㅋㅋ

 

이를 Swift가 알아서 작성하도록 만들어봅시다.

 

DictionaryStorage라는 attached accessor매크로를 만들어주고, 딕셔너리에 들어갈 key를 매개변수로 받아봅시다. 이 매크로는 key가 nil이면 프로퍼티 이름을 바로 가져다가 딕셔너리 키값으로 쓰게 됩니다. attached니까 원래 선언부에 대한 정보를 가져올 수 있으니까요!!!

 

 

매크로를 만들어준 후, 이를 위처럼 이용해주면,

이제 get과 set에 대한 내용은 스위프트가 나대신 작성해줍니다!! (감사감사 ㅋ)

 

@attached(memberAttribute)

attached memberAttribute 매크로는 type혹은 extension에 추가되어서 속성을 추가할 수 있습니다.

WWDC에서 memberAttribute에 대한 예시는 위에서 이미 정의한 accessor 매크로 위에 role을 추가해줬습니다.

이렇게 attached role들은 중복으로 추가해줄 수 있습니다! (freestanding 2개를 제외하고는 어떤 조합이든 구성할 수 있습니다.

이렇게 되면, 프로퍼티에 매크로를 추가하면 accessor의 역할이, 타입에 첨부하면 memberAttribute역할을 하게 될 것입니다. 만약 위 상황에서 함수에 매크로를 추가하면 작동될 수 없고 컴파일 에러가 나겠죠??

이런식으로 추가하면 자동으로 전체 유형에 추가할 수도 있습니다.

 

해당 타입의 멤버에 속성을 추가하기 위해서는 memberAttribute를 사용합니다!

 

@attached(member)

attached member 매크로는 타입이나 extension에 적용할 수 있는데, 기존에 갖고 있던 멤버에 속성을 추가하는게 아니라, 새로운 멤버를 추가하는 매크로입니다.

그래서 이미 존재하는 클래스, 구조체 등에 메서드나 프로퍼티, init등을 추가할 수 있습니다.

위의 코드에서 이젠 init과 dictionary 프로퍼티 써주는거 마저 귀찮아졌으니 ..

이를 Swift가 대신 작성해주도록 만들어봅시다.

 

이를 만들려면 attached member매크로를 사용하면 됩니다.

 

근데 위 코드를 보다보면 드는 생각이 저렇게 매크로가 세개씩 있으면 어떤순서로 전개될까 ? 하는 생각이 들 수도 있죠 .. 그치만 상관 없습니다 ㅎ 

각각은 전개식을 보는게 아니라, 처음 선언된 걸 보기 때문에 어떤 순서로 전개하던 결과는 같습니다!

 

member 매크로가 적용된 후 매크로에서 init, dictionary부분도 작성해주는 것을 볼 수 있습니다!

 

@attached(extension)

마지막으로 WWDC에 나왔던 confromance가 deprecated되고 extension이 나왔기 때문에 extension매크로를 보도록 합시다.

이 매크로는 extension에 프로토콜을 채택해주는 역할을 합니다.

wwdc는 confromance로 나오지만 extension으로 지정해주면 됩니다.

 

struct에 항상 DictionaryRepresentable이라는 프로토콜을 채택해줘야하는데..귀찮다

이걸 항상 Swift가 채택해주도록 extension 을 만들면

 

@DictionaryStorage struct Person {
	var name: String
    var height: Measurement<UnitLength>
    
    @DictionaryStorage(key: "birth_date")
    var birthDate: Date?
}

// 확장된 코드
extension Person: DictionaryRepresentable { 

}

이런식으로 프로토콜 채택해서 확장해줍니다!

 

프로토콜 채택은 되는데, 클래스 상속은 안된다!!!!!!!!!!!

 

 

이 매크로들을 이용하면

이거 말고 나머지는 다 Swift가 알아서 짜주는것이죠~ 굿~

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
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
글 보관함