[英]Mismatched types when using associated consts and const generics in Rust nightly
[英]Mismatched types parameter error on rust generics
expected type parameter T
, found type parameter A
錯誤顯示。 我也寫了終生實現代碼,但它仍然沒有解決問題。 我做錯了什么?
fn main() {
let x = 3;
let y = 5.0;
let max_value = max(x, y);
println!("The maximum value is {}", max_value);
}
fn max<T: PartialOrd, A: PartialOrd>(x: T, y: A) -> T {
if x > y {
x
} else {
y
}
}
// fn main() {
// let x = 3;
// let y = 5.0;
// let max_value = max(&x, &y);
// println!("The maximum value is {}", max_value);
// }
// fn max<'a, T: PartialOrd + Copy, A: PartialOrd + Copy>(x: &'a T, y: &'a A) -> &'a T {
// if x > y {
// x
// } else {
// y
// }
// }
T
和A
不必是同一類型,所以你有兩個問題。
首先是您將T
和A
限制為PartialOrd
,這與PartialOrd<Self>
相同。 所以你的實際約束是T: PartialOrd<T>, A: PartialOrd<A>
。 這意味着您可以比較T
與其他T
的順序以及A
與其他A
的順序,但是x > y
將T
與A
進行比較。
相反,您需要約束T: PartialOrd<A>
。 (這也失敗了,但由於main()
中的調用——稍后會詳細介紹。)
其次,聲明 function 返回T
但else
塊返回y
,這不是T
。 Rust 是靜態類型的,因此它期望類型完全匹配。
這可以通過要求A
可以轉換為T
(即A: Into<T>
)來解決,然后您可以從else
塊返回y.into()
。
所以在這一點上,我們有:
fn main() {
let x = 3;
let y = 5.0;
let max_value = max(x, y);
println!("The maximum value is {}", max_value);
}
fn max<T: PartialOrd<A>, A: Into<T>>(x: T, y: A) -> T {
if x > y {
x
} else {
y.into()
}
}
但是現在您遇到了更多問題:
T: PartialOrd<A>
的類型T
和A
,其中T
是一個 integer, A
是一個浮點數,因此您不能像在main()
中那樣用3
和5.0
調用這個 function。T
和浮點類型A
A
的Into<T>
的實現。x > y
將移動x
和y
,然后您不能稍后返回它們。 這可以通過將T
和A
都限制為Copy
來輕松解決。 第二個問題可以通過使用一個表示“ T
或A
”的枚舉並返回它來解決。 either
crate有一個名為Either
的類型,我們可以在這里將其用作Either<T, A>
:
use either::Either;
fn main() {
let x = 3;
let y = 5.0;
let max_value = max(x, y);
println!("The maximum value is {}", max_value);
}
fn max<T: PartialOrd<A> + Copy, A: Copy>(x: T, y: A) -> Either<T, A> {
if x > y {
Either::Left(x)
} else {
Either::Right(y)
}
}
( println!
起作用是因為Either<T, A>
在T
和A
都實現時實現了Display
。)
您仍然會遇到整數和浮點數之間沒有內置排序實現的問題。
“萬歲”解決方案可能是要求T
和A
都可以轉換為f64
,然后在比較它們之前將x
和y
轉換為f64
:
use either::Either;
fn main() {
let x = 3;
let y = 5.0;
let max_value = max(x, y);
println!("The maximum value is {}", max_value);
}
fn max<T: Copy + Into<f64>, A: Copy + Into<f64>>(x: T, y: A) -> Either<T, A> {
if x.into() > y.into() {
Either::Left(x)
} else {
Either::Right(y)
}
}
這是我們實際編譯的第一段代碼,這可能足以滿足您的目的。 但是,仍然存在一些問題:
i64
和u64
不能無損轉換為f64
,因此它們沒有實現Into<f64>
,所以如果你改變let x = 3;
let x = 3u64;
(或3i64
)編譯將再次失敗。f64
不實現Ord
,因為可能有兩個f64
值x
和y
不相等但都不大於另一個 - 例如,如果其中一個值為NaN
。 這不會導致您的程序崩潰,但它可能會產生意外或不正確的結果。 我懷疑這是一個學習練習,所以希望這個答案可以幫助您理解原始代碼有什么問題。 我不會在實際程序中推薦這樣的 function; 相反,最好將兩個 arguments 提前轉換為相同的Ord
實現類型,然后您可以使用內置的std::cmp::max
function (或Ord::max
)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.