29.rust类型转换.rs
生活随笔
收集整理的這篇文章主要介紹了
29.rust类型转换.rs
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
/*
1.基本類型可以通過顯示類型轉(zhuǎn)換機(jī)制(as)來實現(xiàn)相互之間的轉(zhuǎn)換。
2.Rust通過使用trait來處理定制類型(enum、struct)之間的類型轉(zhuǎn)換。
3.通用的類型轉(zhuǎn)換一般使用的trait為From和To。Rust孤兒原則:
在聲明trait和impl trait的時候,Rust規(guī)定了一個Orphan Rule(孤兒規(guī)則):impl塊要么與trait的聲明在同一個的crate中,要么與類型的聲明在同一個crate中。
也就是說,不能在一個crate中,針對一個外部的類型,實現(xiàn)一個外部的trait。
*/fn test_1() {/*as 運(yùn)算符有點像 C 中的強(qiáng)制類型轉(zhuǎn)換,區(qū)別在于,它只能用于原始類型(i32 、i64 、f32 、f64 、 u8 、 u32 、 char 等類型),并且它是安全的*///在 Rust 中,不同的數(shù)值類型是不能進(jìn)行隱式轉(zhuǎn)換的//let b: i64 = 1i64; 會出現(xiàn)編譯錯誤,提示無法進(jìn)行類型轉(zhuǎn)換。let b: i64 = 1i32 as i64;let c:i32 = 123.456f32 as i32;//為什么它是安全的?像這種不安全的轉(zhuǎn)換編譯不過//let b = 1i32 as char;Rust 會拒絕轉(zhuǎn)換,這也避免了運(yùn)行時錯誤。
}fn test_2() {/*From和Into trait是成對的存在,它表示了一個類型A通過怎樣的處理能變成類型B,通常我們只需要為類型B實現(xiàn)From trait的from(以類型A為參數(shù))方法,就自動獲得了由類型A的into方法轉(zhuǎn)換成類型B。*/use std::convert::From;//use std::convert::Into;#[derive(Debug)]struct Square {width: i32,height: i32,}impl From<i32> for Square {fn from(size: i32) -> Self {Square {width: size,height: size,}}}impl Square {fn area(&self) -> i32 {self.width * self.height}}/*通過上面的示例,我們很容看到,要將類型A轉(zhuǎn)換成類型B,可以為類型B實現(xiàn)From trait的from(A)方法,將類型A作為參數(shù)實現(xiàn)轉(zhuǎn)換;同時在實現(xiàn)了類型B的From trait后,類型A可以直接調(diào)用into()方法轉(zhuǎn)換成類型B。總結(jié)下來可以用以下偽代碼作為示意:let b = B::from(A);let b:B = A.into();為方便記憶,可以簡化成一句:translate A to B,impl B how to from A.*/let s = Square::from(10_i32);println!("s is {:?},area is {}", s, s.area());let a: Square = 20.into(); //這里的Square類型需要顯示標(biāo)注println!("a is {:?}", a);
}fn test_3() {/*TryFrom與TryInto與From和Into類似,TryFrom和TryInto是類型之間轉(zhuǎn)換的通用的trait。與From和Into不同的是,TryFrom和TryInto被用來處理可能出現(xiàn)失敗的轉(zhuǎn)換,因而,他們返回的是Result類型。*/use std::convert::TryFrom;use std::convert::TryInto;#[derive(Debug, PartialEq)]struct DOT {number: u128,}impl TryFrom<u128> for DOT {type Error = ();fn try_from(size: u128) -> Result<DOT, Self::Error> {Ok(DOT {number: size,})}}impl TryFrom<DOT> for u128 {type Error = ();fn try_from(dot: DOT) -> Result<u128, Self::Error> {Ok(dot.number)}} let d1 = DOT{number:100}; let d2 = DOT{number:100};let t1 = DOT::try_from(8u128);let t2 = u128::try_from(d2); let t3:Result<u128,_> = DOT::try_into(d1);//自己結(jié)構(gòu)體是DOT,try_into把自己向某種類型轉(zhuǎn)換,你不告訴我類型我怎么知道向什么方向轉(zhuǎn)?所以必須聲明返回類型let t4:Result<DOT,_> = u128::try_into(12u128);//同上let d1 = DOT{number:100}; let d2 = DOT{number:100};let t1:Result<DOT,_> = TryFrom::<u128>::try_from(8u128);let t2:Result<u128,_> = TryFrom::<DOT>::try_from(d1);let t3 = TryInto::<u128>::try_into(d2);let t4 = TryInto::<DOT>::try_into(8u128);
}fn test_4() {/*轉(zhuǎn)換為字符串為了把一個類型轉(zhuǎn)為String類型,我們只要實現(xiàn)traitToString就可以了。然而,我們并不會直接的這樣做,我們應(yīng)該實現(xiàn)traitfmt::Display,這個trait會自動提供ToString,而且會可以打印這個類型。*/use std::fmt;struct Circle {radius: i32,}impl fmt::Display for Circle {fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {write!(f, "Circle of radius {}", self.radius)}}let circle = Circle { radius: 6 };println!("{}", circle.to_string());
}fn test_5() {/*解析一個字符串一個最常見的類型轉(zhuǎn)換是把一個字符串轉(zhuǎn)換為一個數(shù)字。實現(xiàn)這個功能的常用方法是使用parse方法,并且使用rust類型類型推斷或者使用turbofish語法來指定類型。我們會在如下的示例代碼中來使用這兩個方法。只要為該類型實現(xiàn)了FromStr,就可以實現(xiàn)從字符串到指定類型的轉(zhuǎn)換。標(biāo)準(zhǔn)庫中的很多類型都實現(xiàn)了該trait。如果要在用戶定義的類型的上獲得該功能,只要實現(xiàn)FromStr就可以了。*/// let parsed: i32 = "5".parse().unwarp();// let turbo_parsed = "10".parse::<i32>().unwarp();// let sum = parsed + turbo_parsed;// println!("Sum: {:?}", sum);
}//解引用強(qiáng)制多態(tài)
fn test_6() {fn print(message: &str) {println!("{}", message);}let message: String = "message".to_string();print(&message);/*print 的形參是 &str 類型,然而在 main 中,我傳遞卻是一個 &String 類型的實參。明顯,這兩個類型不相同!!Rust 為什么會通過這樣的代碼呢?沒錯,這就是 Rust 的 解引用強(qiáng)制多態(tài)。首先,需要了解一個 Deref Trait 。#[lang = "deref"]pub trait Deref {type Target: ?Sized;#[must_use]fn deref(&self) -> &Self::Target;}deref 方法返回一個 &Target 類型的引用。回憶一下 Rust 中的解引用語法,當(dāng) ref 是一個引用或智能指針時,我們可以使用 *ref 的方式解引用。這是類似一個語法糖,對于 *ref 這種寫法,寫全應(yīng)該時 *(ref.deref()) 。回想 Box<T> 的使用,Box<T> 實現(xiàn)了 Deref ,它的 deref 方法返回 &T 的引用,然后使用解引用運(yùn)算符 * ,我們順利拿到一個 T 類型的數(shù)據(jù)。也就是,你可以通過實現(xiàn) Deref 以重載解引用運(yùn)算符。Deref 和這節(jié)的內(nèi)容有什么關(guān)系呢?當(dāng) T 實現(xiàn)了 Deref<Target=U> 時,對于需要 &U 的地方,你可以提供一個 &T 類型的數(shù)據(jù),Rust會為你自動調(diào)用 deref 方法,而這個過程可以重復(fù)多次。比如,我自定義類型 P 實現(xiàn)了 Deref<Target=String> ,那么可以把 &P 類型變量傳遞給一個 &str 類型變量。&P -> &String -> &str ,偽代碼: &P.deref().deref() 。回到這節(jié)開頭的例子,print(&message) 相當(dāng)于 print((&message).deref()) ,正好是一個 &str 類型。*/
}fn main() {test_1();test_2();test_3();test_4();test_5();test_6();
}
?
超強(qiáng)干貨來襲 云風(fēng)專訪:近40年碼齡,通宵達(dá)旦的技術(shù)人生總結(jié)
以上是生活随笔為你收集整理的29.rust类型转换.rs的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 28.特性trait.rs
- 下一篇: 30.并发.rs