티스토리 뷰

1편에서는 매크로란 무엇인지, 왜나왔는지, 매크로가 어떤식으로 작동하는지 대략적으로 작성했고, 이번에는 Macro roles에 대해 작성해보려고 합니다.

 

Macro roles(역할)이란?

역할은 매크로에 대한 규칙을 말합니다.

매크로마다 어디에 적용할지, 어떤 코드로 전개될지, 매크로로 전개한 코드가 어디에 삽입될 것인지 등을 미리 결정해주고, 예측이 가능해야 하는데 이를 해주는게 바로 Macro roles 입니다!

 

처음에 이 이야기만 봐서는 이해가 잘 안되었는데, 예시를 하나 들어보자면

 

만약에 제가

1. struct에 AProtocol, BProtocol, CProtocol을 직접 작성하지 않고도 채택하게 해주는 @FirstMacro라는 매크로와 

2. struct에 `let count: Int` 라는 멤버변수를 넣어주는 @SecondMacro라는 매크로를

만들고 싶다면

 

1의 경우에는

// 작성한 코드

@FirstMacro
struct Example {
}

// 실제 매크로가 만들어준 확장된 코드
struct Example { 
}

extension Example: AProtocol, BProtocol, CProtocol {
}

이런식으로 만들어져야 할 것이고,

 

2의 경우에는

// 작성한 코드
@SecondMacro
struct Example2 {
  let k: String
}

// 확장된 코드

struct Example2 {
  let k: String
  let count: Int
}

이렇게 될 것입니다

 

이 두개가 성격(어디에 코드가 들어갈지, 어떻게 들어갈지 등..)이 너무 다른데 ,,

이런 것들을 구분해주는게 role(역할)이라고 생각하면 됩니다!!

 

 

Macro roles의 종류

Swift Macro는 크게는 2가지, 작게는 7가지의 roles(역할)을 제공합니다.

 

 

마지막에 있는 @attached(conformance)는 직접 작성해보니 deprecated 되었고, @attached(extension)을 대신 사용하면 되더라구요?!

 

아무튼 매크로 roles(역할)은 크게 freestanding(독립형), attached(첨부형)으로 나눌 수 있고

각각 freestanding은 2개 (expression, declaration), attached는 5개 (peer, accessor, memberAttribut, member, extension)이 있어요.

 

freestanding 매크로는 #표시, attached 매크로는 @표시를 사용합니다.

 

하나씩 살펴봅시다~

 

@freestanding(expression)

freestanding expression roles(역할)은 결과 값을 만들고 리턴하는 코드를 만들어줍니다. 

 

이런 식으로 보면 = 뒤의 부분 (x+width) * (y+height)를 표현식(expression)이라고 합니다.

근데 이 표현식을 잘 보면, 내부에 (x+width)라는 또 다른 표현식이 있습니다. 

그리고 그 안에 width라는 또 다른 표현식이 있죠..

이를 보면 표현식은 recursive한 구조로 되어있다는 것을 알 수 있습니다.

 

@freestanding(expression)매크로는 표현식 안으로 전개되는 매크로 입니다.

 

 

만약 우리가 강제 언래핑을 해야하는 코드가 있다고 생각해봅시다.

근데 강제언래핑이라는 것은, 앱이 크래시 날 수도 있고 .. 별로 선호하지 않는 방법이죠? 만약 본인이 강제 언래핑을 지양하는 분위기의 팀에 속해있다면, 안전하게 풀어주는 방식을 쓰거나

이처럼 guard 구문을 이용해 체크를 해줘야 합니다.

 

근데 이게 한군데가 아니라 정말 많은 곳에서 작성해줘야 하는 코드라면 굉장히 머리가 아프겠죠,,

이를 간단하게만 작성해도 Swift가 알아서 코드를 다 작성해줄 수 있도록 매크로를 만들어봅시다!

결국 어떤 값을 반환해야 하니까 freestanding expression 역할을 이용해주면 됩니다.!

 

 

WWDC에서는 #unwrap라는 매크로를 보여줬는데요

선언부
적용 후 확장된 코드

 

이런식으로 #unwrap 를 쓰면 직접 guard let 구문을 작성하지 않아도 Swift가 알아서 작성해주게 됩니다 ㅎㅎ

 

중요한건 @freestanding(expression)은 어떤 값을 만들어 리턴해줘야할 때 사용할 수 있는 역할이라는 것!!!!

 

근데 여기서 또 의문인건 이런건 함수를 만들면 되지 않나? 라는 생각을 제가 처음에 했었는데, 

함수로 하는 경우에는 오류메시지나 downloadedImage같은 변수명을 직접 만들 수 없다는 점이 달랐습니다!

매크로로 만들면 더 정교하게 만들 수 있는것 같네요~!

 

만약 @freestanding(expresion)매크로를 구현할거라면, 선언부에는 @freestanding(expression)을, 구현부에는 해당 매크로 코드에 ExpressionMacro라는 프로토콜을 채택해줘야 합니다.

 

 

@freestanding(declaration)

이 매크로는 마치 함수, 변수, 타입 처럼 하나 이상의 declaration(선언)으로 전개됩니다.

 

우리가 2차원 배열, 3차원 배열, 4차원 배열 .. 등등을 1차원 배열로 구현하고 싶어서 Array2D, Array3D, Array4D라는 구조체를 만들어줘야 하는 상황이라고 생각해봅시다. 그리고 각각의 struct 내부에는 위와 같이 storage, width1, width2변수 및 makeIndex 함수, subscript들을 항상 만들어줘야 한다면 정말 귀찮을 것 같네요. ..

만약 100차원 배열까지 있어야 된다는게 요구사항이라면 저걸 100번정도 작성해야겠죠 .. ?

 

Swift Macros를 이용하면 이걸 정말 간단하게 구현 할 수 있습니다!

 

이렇게요 ㅎㅎ

 

이게 어떻게 가능하냐 하면 Swift Macro가 알아서 아래와 같은코드를 작성해주기 때문이죠

 

편안하네요 ..

 

freestanding declaration 매크로를 작성하려면 선언부에는 @freestanding(declaration)을, 구현부에는 DeclarationMacro라는 프로토콜을 채택해줘야 합니다.

 

이렇게 freestanding 매크로 두가지를 봤고, 다음글에서 attached 매크로 다섯개를 가져와보겠습니다!

공지사항
최근에 올라온 글
최근에 달린 댓글
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
글 보관함