[英]Rust won't let me return an instance of a type from a match, keeps thinking I'm trying to return a value
根據這個答案到這個問題 ,我需要做下面的返回一個實例Trait
:
trait Shader {}
struct MyShader;
impl Shader for MyShader {}
struct GraphicsContext;
impl GraphicsContext {
fn create_shader(&self) -> impl Shader {
let shader = MyShader;
shader
}
}
但是當我嘗試這樣做時:
pub trait Component { }
struct Kind {}
struct Location {}
impl Component for Kind {}
impl Component for Location {}
pub fn get(comp_name: &String) -> impl Component {
match comp_name.as_ref() {
"kind" => Kind,
"location" => Location
}
}
我剛得到錯誤:
錯誤[E0423]:期望值,找到結構
Kind
-> src / main.rs:17:24| 17 | "kind" => Kind, | ^^^^ did you mean `Kind { /* fields */ }`?
錯誤[E0423]:期望值,找到結構
Location
-> src / main.rs:18:24| 18 | "location" => Location | ^^^^^^^^ did you mean `Location { /* fields */ >}`?
impl Component
作為返回類型基本上是T where T: Component
,其中T
由函數本身而不是調用方選擇。
T
可以是Kind
, T
可以是Location
,但T
不能同時是兩者。
兩種解決方案:
動態地:返回Box<dyn Component>
並返回Box::new(Kind{})
或Box::new(Location{})
。 缺點是它會導致堆分配。
靜態地,通過返回一個enum
:
enum KindOrLocation {
Kind(Kind),
Location(Location),
}
要使其可用作Component
,可以實現Deref<Target = dyn Component>
:
impl Deref for KindOrLocation {
type Target = dyn Component + 'static;
fn deref(&self) -> &Self::Target {
match self {
KindOrLocation::Kind(x) => x,
KindOrLocation::Location(x) => x,
}
}
}
這里的缺點是您必須編寫此樣板代碼。
順便說說:
{}
定義一個結構,例如struct Kind {}
,則可以通過編寫Kind{}
創建對象,而不僅僅是Kind
。 _
情況: _ => panic!()
。 &String
,而應使用&str
。 然后,它同時適用於&String
並&str
。 編譯器必須知道在編譯時要在堆棧上保留多少空間。 如鏈接的答案所述,如果具體的返回類型是有條件的,則直到運行時才能知道所需的空間量。 這就是答案的含義:
它的確有局限性,例如,當具體的返回類型是有條件的時,就不能使用它。 在這種情況下,您需要使用以下特征對象答案。
如果要有條件地返回Kind
或Location
則應使用該答案中顯示的函數的第二種形式。 在這種情況下,將在堆而不是堆棧上創建Kind
或Location
。 堆棧將包含一個Box
擁有該堆參考,和Box
是一個類型,其尺寸在編譯時是已知的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.