新聞中心
你是否遇到過(guò)設(shè)計(jì)比較奇葩的函數(shù)的形參,而你手中沒(méi)有適合的變量類(lèi)型?

創(chuàng)新互聯(lián)建站是少有的成都網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì)、營(yíng)銷(xiāo)型企業(yè)網(wǎng)站、微信平臺(tái)小程序開(kāi)發(fā)、手機(jī)APP,開(kāi)發(fā)、制作、設(shè)計(jì)、買(mǎi)友情鏈接、推廣優(yōu)化一站式服務(wù)網(wǎng)絡(luò)公司,從2013年開(kāi)始,堅(jiān)持透明化,價(jià)格低,無(wú)套路經(jīng)營(yíng)理念。讓網(wǎng)頁(yè)驚喜每一位訪客多年來(lái)深受用戶(hù)好評(píng)
你是否也曾絞盡腦汁的去提取各種嵌套類(lèi)型里的核心變量的引用呢?
只要你搞明白R(shí)ust的幾種常見(jiàn)的類(lèi)型轉(zhuǎn)換,徹底告別編譯器的紅色警告,享受寫(xiě)完就編譯通過(guò)的快感。
什么是類(lèi)型轉(zhuǎn)換?
類(lèi)型轉(zhuǎn)換,是調(diào)用函數(shù)時(shí),根據(jù)函數(shù)要求的參數(shù)簽名類(lèi)型A,將我們手中的類(lèi)型B轉(zhuǎn)換為類(lèi)型A的過(guò)程,而且不能改變B的所有權(quán)。一般的函數(shù)調(diào)用都要求我們傳遞引用,很少需要直接傳遞所有權(quán)的。
很多語(yǔ)言提供了向上轉(zhuǎn)型和向下轉(zhuǎn)型,例如Java和C++等,如此使用(B)A,即可將B強(qiáng)制轉(zhuǎn)換成A。但是強(qiáng)轉(zhuǎn)是有一定的風(fēng)險(xiǎn)的,Java里強(qiáng)轉(zhuǎn)失敗會(huì)拋出CastException,而在C++里有時(shí)候不拋異常,必須使用更高版本的cast系列函數(shù)去轉(zhuǎn)換,才可以保證轉(zhuǎn)換失敗時(shí)給出異常,避免產(chǎn)生內(nèi)存安全的問(wèn)題。
Rust雖然是各種安全風(fēng)險(xiǎn)可控的編程語(yǔ)言,但是也有一些是需要開(kāi)發(fā)人員事先了解的,比如整型之間強(qiáng)轉(zhuǎn)的結(jié)果并不盡如人意。
as操作符
1、在編碼過(guò)程中,使用最多的轉(zhuǎn)換,要數(shù)整型的強(qiáng)制轉(zhuǎn)換了。
我們往往會(huì)遇見(jiàn)這樣的類(lèi)型需求usize,這個(gè)類(lèi)型一般代指長(zhǎng)度或者數(shù)組索引,我們只有i32之類(lèi)的整型變量是不能直接透?jìng)鬟M(jìn)去的,必須使用as關(guān)鍵字作強(qiáng)制轉(zhuǎn)換后,才可以通過(guò)編譯器的檢測(cè)。
但是,這里會(huì)發(fā)生一些意想不到的事情,比如類(lèi)型截?cái)唷?/p>
什么是類(lèi)型截?cái)?,即一個(gè)值范圍較大的變量A轉(zhuǎn)換為值范圍較小的變量B,如果超出范圍,則將A減去B的區(qū)間長(zhǎng)度。
例如,128超出了i8類(lèi)型的范圍(-128,127),強(qiáng)轉(zhuǎn)之后的值等于128-256=-128。
2、在學(xué)習(xí)Trait的時(shí)候,我們發(fā)現(xiàn)一個(gè)問(wèn)題,類(lèi)型A可以實(shí)現(xiàn)很多Trait,有些Trait存在函數(shù)簽名相同的情況,但是內(nèi)部實(shí)現(xiàn)卻不相同,如果使用A為主題去調(diào)用的話(huà),編譯器無(wú)法判斷應(yīng)該調(diào)用哪個(gè)函數(shù),所以必須將A向上強(qiáng)轉(zhuǎn)為特定的Trait,以告知編譯器如何做出判斷。
例如,B和C是有同名含函數(shù)name()的Trait,A分別實(shí)現(xiàn)了他們,當(dāng)A想要調(diào)用B的name()的時(shí)候,需要顯示轉(zhuǎn)換,避免歧義,如::name()。
3、as還可以在父類(lèi)型與子類(lèi)型之間相互轉(zhuǎn)換,比如&’static str和&'a str。'static生命周期是整個(gè)進(jìn)程存活期間有效的,而'a的生命周期較短,我們稱(chēng)&'static是&'a的子類(lèi)型,使用'static:'a來(lái)表示。as可以將父子類(lèi)型自由轉(zhuǎn)換,如&'static str as &'a str,這種做法的意義是為了滿(mǎn)足某些函數(shù)對(duì)生命周期的要求。
From和Into
這2個(gè)Trait定義在標(biāo)準(zhǔn)庫(kù)的convert模塊中,其實(shí)他們做的是同一件事情,不要被From和Into繞暈掉。
舉個(gè)形象的比喻,我吃飯,和飯被我吃,是一回事。只要我在吃飯,那么飯肯定正在被我吃,是一個(gè)道理。
Rust還為此定義了一個(gè)定理:如果類(lèi)型A實(shí)現(xiàn)了From,則B類(lèi)型實(shí)例調(diào)用into方法就可以轉(zhuǎn)換為類(lèi)型A。
例如,我們常見(jiàn)的字符串String類(lèi)型實(shí)現(xiàn)了From(&str),那么&str就可以into()為String。
大多數(shù)情況下,我們只需要實(shí)現(xiàn)From這個(gè)Trait即可,Rust為所有實(shí)現(xiàn)From的自動(dòng)實(shí)現(xiàn)了反方向的Into。
From和Into也不是完全沒(méi)有異常發(fā)生的,當(dāng)我們不確定轉(zhuǎn)換的結(jié)果是我們想要的時(shí)候,可以實(shí)現(xiàn)TryFrom和TryInto這兩個(gè)Trait,以捕獲可能發(fā)生的錯(cuò)誤信息。
AsRef和AsMut
AsRef和AsMut可以將類(lèi)型分別轉(zhuǎn)換為不可變引用和可變引用。這兩個(gè)Trait對(duì)我們實(shí)現(xiàn)可擴(kuò)展的函數(shù)是非常有幫助的。
比如,我們想設(shè)計(jì)一個(gè)允許傳入&String和&str都可以的函數(shù),那么像下圖中的test函數(shù)那樣做:
如果我們自己定義一個(gè)類(lèi)型,最好能實(shí)現(xiàn)AsRef這個(gè)Trait,它會(huì)給我們帶來(lái)很多意想不到的實(shí)惠。
FromStr
Rust內(nèi)置了很多幫助我們類(lèi)型轉(zhuǎn)換的實(shí)現(xiàn),字符串和其他類(lèi)型之間的轉(zhuǎn)換,都會(huì)默認(rèn)實(shí)現(xiàn)FromStr這個(gè)Trait。
如果想把一個(gè)字符串轉(zhuǎn)換為整型,可以使用parse函數(shù),它會(huì)根據(jù)返回值類(lèi)型自動(dòng)解析字符串,以得到正確類(lèi)型的返回值。
整型轉(zhuǎn)換為字符串,就不用多說(shuō)了,直接format宏格式化即可。
寫(xiě)在最后
雖然Rust類(lèi)型繁多,但是類(lèi)型的統(tǒng)一風(fēng)格做的還是不錯(cuò)的,通過(guò)各種Trait讓類(lèi)型與類(lèi)型之間的邏輯脈絡(luò)有了統(tǒng)一的可能性,不得不說(shuō),理解了類(lèi)型轉(zhuǎn)換之后,在設(shè)計(jì)代碼的時(shí)候可以更加的優(yōu)雅,兼容性更好。
作為十幾年的程序員來(lái)說(shuō),語(yǔ)言之間都是有共性的,縱觀所有的編程語(yǔ)言,Rust在類(lèi)型設(shè)計(jì)上并不是那么優(yōu)雅的,特別是泛型與生命周期結(jié)合起來(lái)以后,讓程序員對(duì)代碼的直觀理解降低到了一個(gè)可怕的程度。
既然選擇學(xué)習(xí)Rust,就要有相關(guān)的覺(jué)悟,學(xué)習(xí)曲線(xiàn)陡峭才可以拉開(kāi)與懶惰者的差距。
學(xué)會(huì)努力,比努力本身更重要。
當(dāng)前名稱(chēng):Rust語(yǔ)言:類(lèi)型轉(zhuǎn)換,還可以這么玩,你學(xué)到了嗎
文章源于:http://m.5511xx.com/article/dpgccpc.html


咨詢(xún)
建站咨詢(xún)
