我想出了一個函式,它應該是采取任何有符號或無符號的整數,并將其映射到一個u8。每個負值都變成了0,而每個高于255的值都應該是255。我知道這很微不足道,我的目的只是想了解泛型的作業原理。
use std::convert::tryInto;
fn as_byte<T>(source: T) ->/span> u8
where
T: TryInto<u8> 。
T: PartialOrd<u8> 。
{
if source < 0 {
return 0;
}
if source > 255 {
return 255;
}
source.try_into().unwrap_or(0)。
}
我認為將我的泛型限制在我真正想對source做的事情上是有意義的,所以我宣告我希望能夠將其與u8進行比較,并且能夠對u8進行轉換(如果我之前抓到一個超出范圍的值,則應該不會失敗)。
如果我呼叫as_byte(1234i32),它將會失敗,因為對于i32沒有實作PartialOrd<u8>。即使有一個實作,這也會失敗,因為source在第一次比較時被移動,然后在第二次檢查時被移動后使用。
如果我通過參考來傳遞source,比如as_byte(&1234i32),情況會變得更糟。現在TryInto<u8>特質也沒有實作,因為沒有From<&i32>用于u8。
我明白為什么會出現這些問題,但我無法弄清楚如何解決這些問題。我試圖將約束條件改為where &'a T,或者將引數改為source: &T,或者兩者都是。這給我留下了類似的問題,即參考型別的特質沒有被實作。這讓我覺得我一開始就沒有正確理解借用/參考的概念。
錯誤在哪里?
我的思維程序中的錯誤在哪里?
我的思維程序中的錯誤在哪里?
如果
PartialOrd<u8> for i32存在,這個方法的宣告應該是什么樣子?知道
PartialOrd<u8> for i32不存在,我還應該如何約束型別引數?為什么我得到錯誤 "trait `Foo`沒有為`&mut T`實作",即使T實作了trait?是相關的,并且在某種程度上回答了我的問題 - 但是我可以(并且可能應該)不為原始/std型別實作trait,是嗎?
uj5u.com熱心網友回復:
你可以這樣寫as_byte():
fn as_byte<T>( source: T) -> u8
where
T: TryInto<u8> From<u8> PartialOrd,
{
if source < 0.into() {
return 0;
}
if source > 255.into() {
return 255;
}
source.try_into().unwrap_or_else(|_| unreachable!()
}
由于u8非常小,將0和255轉換為T然后再進行比較比其他方式更有意義。要求PartialOrd<u8>使得as_bytes可以單獨編譯,但是當呼叫一個具體的整數型別時就不能編譯。這是因為Rust的整數型別目前沒有實作與不同寬度型別的比較,你需要將兩個運算元轉換為同一型別。
我不確定為什么你會遇到source被移動的問題--PartialOrd定義了對&self和&rhs的比較,所以它應該不會引起移動。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/318638.html
標籤:
