我想在a中返回一个向量pub extern "C" fn.由于向量具有任意长度,我想我需要返回一个结构
指向矢量的指针,和
向量中的元素数量
我目前的代码是:
extern crate libc;
use self::libc::{size_t, int32_t, int64_t};
// struct to represent an array and its size
#[repr(C)]
pub struct array_and_size {
values: int64_t, // this is probably not how you denote a pointer, right?
size: int32_t,
}
// The vector I want to return the address of is already in a Boxed struct,
// which I have a pointer to, so I guess the vector is on the heap already.
// …Run Code Online (Sandbox Code Playgroud) 像这样的东西:
let source = [0u8; 40];
let a = source[0..11];
let b = source[11..40];
Run Code Online (Sandbox Code Playgroud) 我正在计算给定数据的 SHA256:
let hashvalue = sha2::Sha256::digest(&data);
Run Code Online (Sandbox Code Playgroud)
计算后,我想将此值放入结构的字段中:
let x = Hash { value: hashvalue };
Run Code Online (Sandbox Code Playgroud)
但是,Hash结构需要 value 的类型[u8; 32],而我的hashvalue变量是 type GenericArray<u8, ?>。我怎样才能转换hashvalue成正确的类型?我尝试使用as [u8; 32],arr!但没有用。
我有一个,&[u8]并希望把它变成一个&[u8; 3]没有复制.它应该引用原始数组.我怎样才能做到这一点?
我正在使用Vec<u8>缓冲区将二进制文件读入Rust程序.流中的两个字节代表一个big-endian u16.
到目前为止,我已经想出如何转换为原语的唯一方法是先将u16两个元素转换为Strings,看起来很糟糕.
码:
let vector: Vec<u8> = [1, 16].to_vec();
let vector0: String = format!("{:02x}", vector[0]);
let vector1: String = format!("{:02x}", vector[1]);
let mut vector_combined = String::new();
vector_combined = vector_combined + &vector0.clone();
vector_combined = vector_combined + &vector1.clone();
let number: u16 = u16::from_str_radix(&vector_combined.to_string(), 16).unwrap();
println!("vector[0]: 0x{:02x}", vector[0]);
println!("vector[1]: 0x{:02x}", vector[1]);
println!("number: 0x{:04x}", number);
Run Code Online (Sandbox Code Playgroud)
输出:
vector[0]: 0x01
vector[1]: 0x10
number: 0x0110
Run Code Online (Sandbox Code Playgroud) 相关:切片到固定大小的数组,但我正在寻找更具体的形式.
理想情况下,我想构建一个具有以下签名的函数:
fn make_array<T; N>(slice: &[T]) -> [T; N];
Run Code Online (Sandbox Code Playgroud)
因为这还不可能(因为非类型参数不是一个东西),我反而想到让函数直接接受数组:
fn make_array<A>(slice: &[T]) -> A;
Run Code Online (Sandbox Code Playgroud)
人们可以替代[T; N]的地方A.
到目前为止,这是我最有希望的尝试:
use std::ops::DerefMut;
fn make_array<A, T>(slice: &[T]) -> A
where A: Sized + Default + DerefMut<Target = [T]>
{
let mut a = Default::default();
(&mut a[..]).copy_from_slice(slice);
a
}
fn main() {
let original = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let a: [u8; 4] = make_array(&original[0..4]);
println!("{:?}", a);
}
Run Code Online (Sandbox Code Playgroud)
但是我错过了允许将数组强制转换为切片的特性(提示:它不是DerefMut).
只要我可以将函数仅用于小数组,有没有办法使用安全代码构建这样的函数?
我看到了解决方法,它们有点长。我是否缺少 Rust 的某个功能或简单的解决方案(重要:不是解决方法)。我觉得我应该能够用一个简单的宏来做到这一点,但 arrayref crate 实现不是我想要的。这是一个需要添加到 Rust 的功能吗?还是在较小的范围内从固定大小的数组创建固定大小的切片是一件坏事。基本上我想做的是这个;
fn f(arr:[u8;4]){
arr[0];
}
fn basic(){
let mut arr:[u8;12] = [0;12];
// can't I borrow the whole array but but a fixed slice to it?
f(&mut arr[8..12]); // But this is know on compile time?
f(&mut arr[8..12] as &[u8;4]); // Why can't I do these things?
}
Run Code Online (Sandbox Code Playgroud)
我想要的可以通过下面的代码来实现(来自其他线程)
use array_ref;
fn foo(){
let buf:[u8;12] = [0;12];
let (_, fixed_slice) = mut_array_refs![
&mut buf,
8,
4
];
write_u32_into(fixed_slice,0);
}
fn write_u32_into(fixed_slice:&mut …Run Code Online (Sandbox Code Playgroud) 在这段代码中:
fn unpack_u32(data: &[u8]) -> u32 {
assert_eq!(data.len(), 4);
let res = data[0] as u32 |
(data[1] as u32) << 8 |
(data[2] as u32) << 16 |
(data[3] as u32) << 24;
res
}
fn main() {
let v = vec![0_u8, 1_u8, 2_u8, 3_u8, 4_u8, 5_u8, 6_u8, 7_u8, 8_u8];
println!("res: {:X}", unpack_u32(&v[1..5]));
}
Run Code Online (Sandbox Code Playgroud)
该函数unpack_u32只接受长度为 4 的切片。有没有办法assert_eq用编译时检查替换运行时检查?
我目前正在处理向量,并试图确保我在堆栈上拥有本质上是向量数组的内容。我无法调用,Vec::into_boxed_slice因为我正在动态分配Vec. 这是可能吗?
阅读了关于如何实现的VecRustonomicon 后,它似乎跨越了堆上的指针,在每个条目处取消引用。我想将Vec堆中的条目分块到堆栈中以便快速访问。
由于数组的长度,我不能使用i32::from_ne_bytes(),但当然,以下工作特别是因为代码将仅在支持未对齐访问的 cpu 架构上运行(或者由于长度小,整个数组可能会被存储跨越多个 cpu 寄存器)。
fn main() {
let buf: [u8; 10] = [0, 0, 0, 1, 0x12, 14, 50, 120, 250, 6];
println!("1 == {}", unsafe{std::ptr::read(&buf[1])} as i32);
}
Run Code Online (Sandbox Code Playgroud)
但是有没有更干净的方法来做到这一点,同时仍然不复制数组?