我使用枚舉在不同的函數簽名之間進行選擇。只要該函數具有「正常」(大小)的參數,如u8
,這可以正常工作。但是,只要我用一個片作爲參數使用函數,就會出現編譯器錯誤。我發現了一種解決方法,但我不確定這是否是解決此問題的唯一方法。我不明白爲什麼。假設函數被存儲爲一個指針,參數如何改變可能?使用具有切片參數的函數的枚舉
#[derive(Copy, Clone/*, Debug, Eq, PartialEq*/)]
pub enum Function {
FunctionVal(fn(u8) -> String),
//FunctionSlice(fn(&[u8]) -> String), // E0277
FunctionSlice(&'static fn(&[u8]) -> String), // workaround
}
#[derive(Copy, Clone/*, Debug, Eq, PartialEq*/)]
pub struct FunctionStruct {
pub func: Function,
}
pub static FUNC1: FunctionStruct = FunctionStruct {
func: Function::FunctionVal(convert_u8_to_string),
};
static F2:fn(&[u8]) -> String = convert_u8slice_to_string;
pub static FUNC2: FunctionStruct = FunctionStruct {
func: Function::FunctionSlice(&F2), // to avoid E0308
};
fn convert_u8_to_string(_:u8) -> String { String::from("") }
fn convert_u8slice_to_string(_:&[u8]) -> String { String::from("") }
fn main() {
let f = FUNC1;
match f.func {
Function::FunctionVal(f) => { f(0); }
Function::FunctionSlice(f) => { f(&[0u8]); }
}
}
只要存在切片作爲參數,#[derive(Debug, Eq, PartialEq)]
是不可能的了。但這對我來說不是問題。我不能使FunctionSlice(fn(&[u8]) -> String),
工作。我必須使用具有靜態生命週期的引用類型。否則#[derive(Copy, Clone)]
會失敗。要初始化結構,我必須使用一個額外的靜態。
我目前使用的防鏽1.10
我加入PartialEq'和'Debug'的'的實現,因爲我確實需要他們現在。 (爲我的單位測試)。你的回答也幫助我解決了這個問題! – wimh