2014-07-23 5 views
6

나는 다음과 같은 것을 할 수있을 싶어요 :기능/메소드 서명으로 확장되는 Rust 매크로를 작성할 수 있습니까?

macro_rules! impl_a_method(
    ($obj:ident, $body:block) => (
     fn a_method(foo: Foo, bar: Bar, baz: Baz) -> $obj $body 
    ) 
) 

// Implementation would look like: 

impl_a_method!(MyType, { 
    MyType { 
     foo: foo.blah(), 
     bar: bar.bloo(), 
     baz: baz.floozy(), 
    } 
}) 

내 실제 예를 들어 내가 30 개 + 다른 유형에 대해 고유 한 방식으로 구현해야 훨씬 더 큰 서명 방법을 제공합니다.

나는 그러나 나는 (I 매크로 선언 어휘 사용을 앞에 확신에도 불구하고) rustc가 확장 사이트에서 foo, barbaz 해결되지 않은 이름을 고려 오류로 실행, 위의 매크로 비슷한 노력했다.

이렇게 할 수 있습니까?

그렇지 않은 경우 비슷한 결과를 얻을 수있는 방법을 권장 할 수 있습니까?

답변

5

매크로 위생 때문에 가능하지 않습니다. 매크로 본문에 도입 된 모든 식별자는 매크로 호출 사이트의 식별자와 다르게 보장됩니다.

macro_rules! impl_a_method(
    ($obj:ty, ($_foo:ident, $_bar:ident, $_baz:ident), $body:expr) => (
     fn a_method($_foo: Foo, $_bar: Bar, $_baz: Baz) -> $obj { $body } 
    ) 
) 

당신이 정말로 여기에 저장하고있는 유일한 방법은 쓰고 유형 :

impl_a_method!(MyType, (foo, bar, baz), { 
    MyType { 
     foo: foo.blah(), 
     bar: bar.bloo(), 
     baz: baz.floozy(), 
    } 
}) 

이이 매크로에 의해 수행됩니다 : 당신은 다소 매크로의 목적을 무시 모든 식별자 자신을, 제공해야 메소드 매개 변수의.

+0

좋은 대답은, 나는 녹이 매크로를하는 방식의 팬이 아니라고 말하고 있습니다. 매크로의 요점은 텍스트를 맹목적으로 대체한다는 것이고, "매크로 위생"은 모순이라고합니다. 단지 C에서 이와 같이 위험한 일을하는 데 문제가없는 반면 더 많은 구문을 다루어야 만합니다. – sudo

+3

"매크로 위생"은 실제로 매우 잘 정의 된 아이디어입니다 : https://en.wikipedia.org/위키/Hygienic_macro – solidsnack