我有這個函式將一個向量分成奇數和偶數元素的兩個向量:
pub fn odd_even<T>(x: Vec<T>, upto: usize) -> (Vec<T>, Vec<T>)
where T: Copy
{
let mut odd = Vec::new();
let mut even = Vec::new();
let oddeven: [&mut Vec<T>; 2] = [&mut odd, &mut even];
for n in 0..upto
{
oddeven[1 - n%2].push(x[n]);
}
return (odd, even);
}
這很好用并且適用于動態大小的向量。
但是,我正在考慮為此使用 const 通用長度陣列。LEN_ODD以下代碼會為and的約束(或任何您稱之為的?)生成編譯器錯誤LEN_EVEN,因為LEN它是一個常量,但它應該傳達這個想法。我什至不確定語言是否允許我做這種事情,但我想知道這是否可能。
有沒有辦法說LEN_ODDandLEN_EVEN必須具有與 相對應的某個值LEN,以便編譯器可以自動推斷這兩個常量的值?也許這是一個愚蠢的想法,但我想試試。該代碼將用于實作快速傅立葉變換,其中性能至關重要。也許宏會是實作這一點的更好方法?
fn odd_even<T, const LEN: usize, const LEN_ODD: usize, const LEN_EVEN: usize>
(x: [T; LEN]) -> ([T; LEN_ODD], [T; LEN_EVEN])
where
T: Default, T: Copy,
LEN_ODD == LEN << 1, // this line is invalid
LEN_EVEN == (LEN 1) << 1 // this line is also invalid
{
let mut odd: [T; LEN_ODD] = [Default::default(); LEN_ODD];
let mut even: [T; LEN_EVEN] = [Default::default(); LEN_EVEN];
let oddeven: [&mut [T]; 2] = [&mut odd, &mut even];
for n in 0..LEN
{
oddeven[1 - n%2][n << 1] = x[n];
}
return (odd, even);
}
我是 rust 新手,對明確使用指標的語言沒有太多經驗。那里可能有一個解決方案,我完全錯過了僅參考陣列的第一個元素,但是陣列的長度不會受到編譯器的限制,這很容易讓人困惑。在這一點上,你還不如使用向量,對吧?
使用斷言,編譯器仍然不會推斷LEN_ODD和LEN_EVEN:
fn odd_even<T, const LEN: usize, const LEN_ODD: usize, const LEN_EVEN: usize>
(x: [T; LEN]) -> ([T; LEN_ODD], [T; LEN_EVEN])
where
T: Default, T: Copy
{
assert_eq!(LEN_ODD, LEN << 1);
assert_eq!(LEN_EVEN, (LEN 1) << 1);
let mut odd: [T; LEN_ODD] = [Default::default(); LEN_ODD];
let mut even: [T; LEN_EVEN] = [Default::default(); LEN_EVEN];
let oddeven: [&mut [T]; 2] = [&mut odd, &mut even];
for n in 0..LEN
{
oddeven[1 - n%2][n << 1] = x[n];
}
return (odd, even);
}
上面的最終函式可以這樣成功呼叫:
odd_even::<usize, 4, 2, 2>([0, 2, 3, 5]); // -> [2, 5], [0, 3]
但是必須指定長度,并且不會被推斷。我正在尋找的是一種告訴編譯器如何推斷它們的方法。
uj5u.com熱心網友回復:
對 const 泛型進行算術運算需要generic_const_exprs特性。這是啟用該功能的代碼的作業實作:
#![feature(generic_const_exprs)]
#![allow(incomplete_features)]
fn main() {
let _: ([u32; 2], [u32; 2]) = dbg!(odd_even([0, 2, 3, 5]));
let _: ([u32; 2], [u32; 3]) = dbg!(odd_even([0, 2, 3, 5, 6]));
}
fn odd_even<T, const LEN: usize>(x: [T; LEN]) -> ([T; LEN / 2], [T; (LEN 1) / 2])
where
T: Default,
T: Copy,
{
let mut odd = [Default::default(); LEN / 2];
let mut even = [Default::default(); (LEN 1) / 2];
let oddeven: [&mut [T]; 2] = [&mut odd, &mut even];
for n in 0..LEN {
oddeven[1 - n % 2][n / 2] = x[n];
}
return (odd, even);
}
輸出:
[src/main.rs:5] odd_even([0, 2, 3, 5]) = (
[
2,
5,
],
[
0,
3,
],
)
[src/main.rs:6] odd_even([0, 2, 3, 5, 6]) = (
[
2,
5,
],
[
0,
3,
6,
],
)
操場
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/464402.html
