2016-12-13 2 views

답변

9

예, [[T; 4]; 3]에 대한 참조를 [T; 12]에 대한 참조로 변환 할 수 있지만 안전하지 않은 코드 인 경우에만 mem::transmute을 사용합니다. transmute은 참조가 가져야하는 것보다 더 큰 수명의 참조를 얻을 수 있도록 결과 참조에 적절한 수명이 할당되도록 함수에서이 값을 감싸는 것이 가장 좋습니다.

fn convert<'a>(a: &'a [[u8; 4]; 3]) -> &'a [u8; 12] { 
    unsafe { std::mem::transmute(a) } 
} 

은 평생 생략 규칙에 감사를 단축 할 수 있습니다 안전하지 않은 코드를 처리 할 때 당신은 더 명시 적으로 버전을 선호하는 경우

fn convert(a: &[[u8; 4]; 3]) -> &[u8; 12] { 
    unsafe { std::mem::transmute(a) } 
} 

비록, 내가 이해하는 것!

+1

명확히하기 : 이것은 참조 자체가 아니라 배열의 내용이 아닌 경우 비트 단위로 복사합니까? 나는 확실하지 않았다. –

+3

@ 시몬 : _reference_를 배열로 변환하면 참조 만 복사됩니다. 답에서와 같이 _array_를 직접 변환하면 전체 배열이 복사됩니다. 그러나 컴파일러는 값을 사용하여 수행하는 작업과 코드를 컴파일하는 방법 (디버그 또는 릴리스)에 따라 복사본을 제거 할 수 있습니다. –

+0

위대한 문제 없습니다. 나는 미래에 나 자신을위한 참고 점으로서 어쨌든 나의 대답을 남겨 둘 것이다. 명확히 해 주셔서 감사합니다 :) –

3

면책 조항 : 저는 아직 녹의 로우 레벨면과는 달리, 저급 녹에서 "우수 사례"로 간주되는 것을 모르겠습니다. 여기에 제시된 조언은 좋은 생각이 아닐 수도 있습니다. 나는 ... 글쎄, 그들은 일하기 때문에 나는 그들을 여기에두고있다.

You could transmute them. 문제는 복사본이 될 것이므로 설명서에 memcpy 호출과 동일한 것입니다. 이것은 당신이 원하는 것을 아니지만, 여기 어쨌든입니다 :

fn main() { 
    let a: [[u8; 4]; 3] = [[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]]; 
    let b: [u8; 12] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; 

    println!("a: {:?}", a); 
    println!("b: {:?}", b); 

    let c = unsafe { std::mem::transmute::<[[u8; 4]; 3], [u8; 12]>(a) }; 

    println!("c: {:?}", c); 
} 

귀하의 다른 옵션 is to work with a raw pointer : 중 특히 잘되지 않습니다

fn main() { 
    let a: [[u8; 4]; 3] = [[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]]; 
    let b: [u8; 12] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; 

    println!("a: {:?}", a); 
    println!("b: {:?}", b); 

    let c = &a as *const _ as *const [u8; 12]; 
    // Or it can be this: let c = &mut a as *mut [[u8; 4]; 3]; 

    for i in 0..12 { 
     let p = c as *const u8; 
     let v = unsafe { *p.offset(i) }; 
     println!("{}", v); 
    } 
} 

.

포인터는 (&mut T*mut T에 캐스팅 될 수 있기 때문에) 같은 유형에 대한 포인터 또는 변경 가능한 포인터 될 수 있으며, 위의 코드를 정확히 동일하게 작동합니다 (a으로는 가변 표시) :

let c = &mut a as *mut [[u8; 4]; 3]; 

이것이 약간의 XY 문제인지 아닌지 궁금합니다. 어쩌면 데이터로 작업하는 방식을 변경하지 않아도됩니다.

관련 문제