簡體   English   中英

錯誤[E0308]:類型不匹配,默認泛型類型無效

[英]error[E0308]: mismatched types , Default generic type is invalid

我嘗試在兩個不同的地方指定類型,但編譯器仍然拋出錯誤。

use serde::Serialize;

// 1: try to set default type.
struct Student<T = Option<String>> {
    age: i32,
    data: T
}

impl<T> Student<T> where T: Serialize {
    
    fn new(age: i32) -> Self {
        Student {
            age, 
            data: <Option<String>>::None // 2. try to set default type
        }
    }
    
    
    // fn new_with_data(age: i32, data: T) -> Self {
    //     Student {
    //         age,
    //         data
    //     }
    // }
}


fn main() {
 
    let stu1 = Student::new(123);
    
    //let stu2 = Student::new_with_data(123, <Option<()>>::None);
    
}

得到錯誤:

   Compiling playground v0.0.1 (/playground)
error[E0308]: mismatched types
  --> src/main.rs:13:19
   |
8  | impl<T> Student<T> where T: Serialize {
   |      - this type parameter
...
13 |             data: <Option<String>>::None
   |                   ^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `T`, found enum `std::option::Option`
   |
   = note: expected type parameter `T`
                        found enum `std::option::Option<std::string::String>`

For more information about this error, try `rustc --explain E0308`.
error: could not compile `playground` due to previous error

播放鏈接: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=749e31fae6091226b99e233a016ca0c8

問題是當您設置默認類型時, impl塊不要求T是默認類型。 <Option<String>>::None僅在類型為Option<String>時才是有效值,但這並不要求必須如此。

/// `T` is unconstrained and may or may not be `Option<T>`
impl<T> Student<T> {}

/// This implements student for only one specific generic type (`Option<String>`). This
/// functionality will not be available for other generic types.
impl Student<Option<String>> {}

/// Here we don't include the generic so it implements for only the default generic. This is
/// equivalent to the previous version, but the generic is assumed to be the default value. 
impl Student {}

我懷疑您想要做的是使數據通用。 我們沒有將Option設為通用,而是將其保存的數據設為通用。 我們仍然可以設置默認值而不會遇到這個問題。

struct Student<T = String> {
    age: i32,
    /// Some optional generic data
    data: Option<T>
}

impl<T> Student<T> where T: Serialize {
    fn new(age: i32) -> Self {
        Student {
            age, 
            data: None,
        }
    }
    
    
    fn new_with_data(age: i32, data: T) -> Self {
        Student {
            age,
            data: Some(data),
        }
    }
}

另一種選擇是保持類型相同,但將impl分成兩部分。 這樣,如果數據不是Option ,我們可以要求使用new_with_data ,但在某些情況下仍然允許使用new

struct Student<T = Option<String>> {
    age: i32,
    data: T
}

impl<T> Student<Option<T>> where T: Serialize {
    fn new(age: i32) -> Self {
        Student {
            age, 
            data: None,
        }
    }
}

impl<T> Student<T> where T: Serialize {
    fn new_with_data(age: i32, data: T) -> Self {
        Student { age, data }
    }
}

根據你的方法,我做了一點修改,就實現了我想要的。

use serde::Serialize;

struct Student<T = Option<String>> {
    age: i32,
    /// Some optional generic data
    data: T
}

impl Student<Option<String>> {
    fn new(age: i32) -> Self {
        Student {
            age, 
            data: None,
        }
    }
}

impl<T> Student<T> where T: Serialize {
    
    fn new_with_data(age: i32, data: T) -> Self {
        Student {
            age, data
        }
        
    }
}

fn main() {
 
    let stu1 = Student::new(123);
    let stu2 = Student::new_with_data(123, 2222);
    
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM