제가 이해하기에, [[T; 4]; 3]
과 [T; 12]
은 같은 레이아웃의 메모리를 가지고 있습니다. 이러한 유형간에 값을 변환하는 가장 좋은 방법은 무엇입니까? 하나의 참조를 다른 참조로 변환 할 수 있습니까? 모든 요소를 복사하지 않아도됩니까? unsafe
이 필요합니까?변환하는 가장 좋은 방법은 무엇입니까 [[T; 4]; 3]을 a [T; 12]?
6
A
답변
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) }
}
비록, 내가 이해하는 것!
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 문제인지 아닌지 궁금합니다. 어쩌면 데이터로 작업하는 방식을 변경하지 않아도됩니다.
관련 문제
- 1. <T>을 Func <T,Tres>으로 변환하는 가장 좋은 방법은 무엇입니까?
- 2. T [] toArray (T [] a) 구현
- 3. 배열을 번갈아 정렬하는 가장 쉬운 방법은 무엇입니까? 예 : T, T, F, F, F, T, F, T, F, F, F에서 T, F, T, F, T, F, T, T, T)?
- 4. 표시 \t \t 가장 2 \t 지불 \t 양 \t 제품 \t에서 \t 모든 \t일
- 5. t-sql : 십진수와 비교하는 가장 좋은 방법은 무엇입니까?
- 6. T-SQL의 트랜잭션 중 로깅을 구현하는 가장 좋은 방법은 무엇입니까?
- 7. T-SQL에서 DateMask를 스타일로 변환하는 방법은 무엇입니까?
- 8. 목록을 변환하는 방법 <T> T [,]
- 9. <T>을 IObservable로 변환하는 방법 <T>
- 10. Vec <T>을 & [T]
- 11. 스칼라. 푸는 가장 좋은 방법은 Option [Future [T]]
- 12. HashBytes() 함수 T-SQL
- 13. CSV를 T-SQL 내부에서 레코드 세트로 변환하는 방법은 무엇입니까?
- 14. 목록 <T>을 사용하고 콜렉션을 노출하는 가장 좋은 방법은 <T>
- 15. 시간을 t-sql로 변환하는 Excel
- 16. String에서 HashMap으로 변환하는 가장 좋은 방법은 무엇입니까?
- 17. 배열을 해시로 변환하는 가장 좋은 방법은 무엇입니까?
- 18. 스칼라 형 확대/추론 [T (T, T) :
- 19. zipE :: Event t a -> 이벤트 t b -> 이벤트 t (a, b)
- 20. 재귀 적 복잡도를 풀는 방법 T (n) = T (n/4) + t (3n/4) +1?
- 21. scala에서 변환하는 방법 Iterator [T] to Option [T]
- 22. T-SQL : 문자열 연결에서 NULL 값을 처리하는 가장 좋은 방법
- 23. 이 매크로 함수에서 A, T, T는 무엇입니까?
- 24. const를 T & T && 대
- 25. T-SQL보기에서 값을 변환하는 방법
- 26. T-SQL을 LINQ로 변환하는 방법?
- 27. T-SQL을 LINQ로 변환하는 방법
- 28. T-SQL 업데이트는 다른 좋은 방법을
- 29. "% S \ t, \ t
- 30. T 유형의 일부 (유형 T)
명확히하기 : 이것은 참조 자체가 아니라 배열의 내용이 아닌 경우 비트 단위로 복사합니까? 나는 확실하지 않았다. –
@ 시몬 : _reference_를 배열로 변환하면 참조 만 복사됩니다. 답에서와 같이 _array_를 직접 변환하면 전체 배열이 복사됩니다. 그러나 컴파일러는 값을 사용하여 수행하는 작업과 코드를 컴파일하는 방법 (디버그 또는 릴리스)에 따라 복사본을 제거 할 수 있습니다. –
위대한 문제 없습니다. 나는 미래에 나 자신을위한 참고 점으로서 어쨌든 나의 대답을 남겨 둘 것이다. 명확히 해 주셔서 감사합니다 :) –