2017-03-13 8 views
2

직교 제품 :내가 <em>불완전</em> 유형의 두 세트 (즉, 구조체 이름 일반 매개 변수 및 수명 누락)을 가지고 있고, 나는 몇 가지 코드가 조합의 각 쌍에 대해 실행 한 필요가 일치

// these are my types 
struct A<T> { ... } 
struct B<'a, 'b, T> { ... } 
struct C { ... } 

struct X<T> { ... } 
struct Y { ... } 
struct W<'a> { ... } 
struct Z<T, D> { ... } 

// this is the code I need to generate 
match (first_key, second_key) { 
    ("a", "x") => { ... A ... X ... } 
    ("a", "y") => { ... A ... Y ... } 
    ("a", "w") => { ... A ... W ... } 
    ("a", "z") => { ... A ... Z ... } 
    ("b", "x") => { ... B ... X ... } 
    ("b", "y") => { ... B ... Y ... } 
    // ... 
} 

첫번째 세트 (A, B, C)와 두 번째 세트에있는 것들의 구조물 (X, Y, WZ)의 경우 ("a", "x") 서로 (예에 따라 일반 파라미터가 실제 유형이 사용될 것임을 A<X>X< A<X>::Color >). 이런 이유로 제네릭 함수 나 유사한 것을 사용하는 솔루션을 찾을 수 없었습니다.

매크로를 사용하여 문제를 쉽게 해결할 수 있다고 생각합니다.

macro_rules! my_code { 
    ($first_type:tt), $second_type:tt) => { 
     // ... $first_type ... $second_type ... 
    } 
} 

product_match!((first_key, second_key) { 
    { "a" => A, "b" => B, "c" => C }, 
    { "x" => X, "y" => Y, "w" => W, "z" => Z } 
} => my_code) 

하지만 난 이미에 몇 시간 동안 근무 후 product_match 구현에 실패 뭔가있다. 반복을 중첩하는 쉬운 방법을 찾지 못했습니다. 유일한 해결책은 매크로를 사용하여 대/소문자 목록을 값의 중첩 된 튜플로 변환 한 다음 다시 반복하는 것이지만 구현하기가 매우 어려웠다 고 생각합니다.

다른 옵션은 빌드 스크립트를 사용하여 큰 match 코드를 생성 할 수 있지만이 솔루션은 상당히 더러워 보입니다.

내가 놓친이 문제에 대한 쉬운 해결책이 있습니까? product_match!을 구현하는 쉬운 방법이 있습니까? 논리를 구현하려면 어떻게해야합니까?

+2

아야는, 고통스러운 보이는 :(나는 당신에게 소원을 빌어 –

+0

나는 문제가 매크로 *에 쉽게 풀 수있을 수 있다고 생각. * - 매크로 녹의 기능을 실제 마술을 추가하지 않습니다, 그들은 단순히 상용구를 제거 그러나, 당신은 * 우리에게 상용구 *를 보여주지 않았지만, 문제의 고기는'...'로 생략했다. 나는 우리가 확장 매크로를 생성하기를 원하지 않는다고 확신한다. 리터럴 '...'로 변환 할 수 있지만, 무엇을해야할지 모르겠습니다. [MCVE]를 만드는 방법을 검토하십시오. 2 가지 유형의 2 세트와 – Shepmaster

+0

@Shepmaster by'... A ... X ...'나는'f (A, X)'를 의미한다고 생각했다. 최소한의 완전하고 검증 가능한 예입니다.필자가 특정한 경우에'$ first'에 의해 구현 된 형질과 관련된 타입을 전송하기위한 채널을 생성 한 다음'$ second'를 인스턴스화하고 함수 ('f1')로 전달하는 스레드를 시작해야합니다. 메인 스레드에서'$ first'에 함수 ('f2')를 호출하십시오. 'f2'는'$ first'가 일반적인 매개 변수가'$ second'에 대한 특성 구현의 관련 유형이어야하고'f1'이'$ second'를 요구하는 특성을 구현할 것을 요구합니다. – peoro

답변

1

매크로를 사용하여 카티 전 곱을 구현하는 것이 가장 좋습니다.

match 표현식을 원하는 내용으로 잘 모르겠습니다. 따라서 implemented 반복되는 함수 호출이 있습니다. 그러나 매크로 배관은 거의 동일해야합니다. 바라건대 당신은 여기에서 그것을 가져갈 수 있습니다.

macro_rules! cp_inner { 
    ($f: expr, $x: expr, [$($y: expr),*]) => { 
     $($f($x, $y);)* 
    } 
} 

macro_rules! cartesian_product { 
    ($f: expr, [$($x: expr),*], $ys: tt) => { 
     $(cp_inner!($f, $x, $ys);)*; 
    } 
} 

fn print_pair(x: u32, y: &'static str) { 
    println!("({}, {})", x, y); 
} 

pub fn main() { 
    cartesian_product!(print_pair, [1, 2, 3], ["apple", "banana", "cherry"]); 
}