gm怎么刷东西 rust_Rust语言:解引用详述,搞不明白这个概念,趁早放弃Rust
Rust是內存安全的,對新手來說,最大的困難是可惡的編譯器,在其他語言上面叱咤風云,偏偏被Rust搞到崩潰。所以,大家都戲謔道,Rust是面向編譯器編程。
和編譯器做斗爭的過程中,遇到最多的是,變量所有權被move了,某個api需要傳入可變引用而我卻不知道如何獲取。
只要你了解了如何解引用,如何做類型轉換,這些問題都將迎刃而解。
什么是解引用
引用是對內存塊的借用,Rust里每一個內存塊都是有主人的,主人就是對內存擁有所有權的變量,沒有主人的內存塊我們稱之為內存泄露了。
解引用是通過引用找到內存塊真正的主人,然后你可以跟主人借一些不同類型的引用,比如從&mut T借成Pin<&mut T>。
這個主人可能被包了很多層,當你以為你找了主人,其實它只是個皮,所以會存在不斷解引用的情況,你可能需要加很多個*,當然很多個*不符合設計美感。
Rust語法規定,同一塊內存只能有一個可變引用,或者有多個不可變引用。這給習慣于C++或者Java等語言的編程人員造成了很大的困擾,違反了多年以來養成的編程習慣,特別的別扭,因為他們眼中元原本的理解是所有的引用都是可變引用。
Rust之所以這么規定,一個非常大的優點是避免了內存被多處修改的潛在隱患,避免了資源的復雜環境競爭,降低了程序的調試難度。
那么,程序編寫過程中必然會在不同的函數塊里調用同一塊內存,所以引用的使用將會變得非常頻繁,我們犯的錯誤大多也在此。
解引用的方法
解引用可以分為,自動解引用和手動解引用。
Rust為了減少某些場合下重復解引用導致的代碼美觀問題,在編譯期做了一些智能識別功能,比如帶有&T參數的函數被調用的時候,你傳&&&......&&&T都可以自動解引用,直到符合函數的參數類型為止。
手動解引用,就是和其他語言類似,借用是&操作符,解引用是*操作符。
我們也可以通過自行實現Deref這個Trait來自定義解引用的最終目標是什么,而恰恰這個也是Rust語言最難的地方,你得了解每個類型是否實現了Deref,而Rust類型實在是太多了,連&T借用也算一個新的類型,&T是不能繼承T的所有特性的。
如果想要學好Rust,對Deref不做深入的研究,將會死的很難看。
解引用進階篇
1、手動實現Deref
Rust已經為所有的&T和&mut T的類型默認實現了簡陋版的Deref,解引用就是得到T本身。
當然我們也可以給類型T本身添加一個Deref,這樣T本身就可以被接引用,相當于T也是一個引用類型,其實T不是。
下面這個短暫的動態圖片形象的闡述了Deref是如何自定義的,以及遇到類型不匹配的函數時,Rust是會自動解引用直到類型匹配為止。
2、以Pin<P>為例子,來談談解引用
如果P沒有實現Deref,即P不可以解引用,那么Pin<P>是不能被*操作符操作的。
當P實現了Deref,那么*Pin<P>的解引用會先觸發P解引用操作,得到P的Target的引用,再使用*操作符,最終的結果是P的Target被返回了。然而Pin<P>本身使用deref()得到的是&Target。
所有實現Deref的類型,使用deref函數得到的結果,肯定是一個引用類型。
*操作符為了更通用和方便,原理就是將被解引用的對象,先使用deref調用一下,再解引用。
項目中,最常遇見的是Pin<&mut T>,我們希望得到T的Target的可變引用,一般使用&mut **Pin<&mut T>。如果不了解它是怎么執行的,那么肯定會很疑惑,這個結果是啥。
3、Option<T>如何得到T的Target引用
大多數情況下,我們得到的是Option<T>,可是我們想調用的函數需要傳入&T或者T的Target引用,這樣就會很疑惑,該怎么得到這個&T呢?
這里也涉及到幾個類型的deref函數的調用,首先是要把Option<T>轉化為Option<&T>,然后再將T轉化為Target引用,如Option.as_ref().map(|s| { s.deref()}),或者直接使用Option自帶的as_deref()。
4、Box<T>是個特例
嚴格說Box這個語法在Rust里是特權一般的存在,各種小后門開的不亦樂乎。
Box<T>在實現Deref這個Trait時,竟然使用的是&**語法,可是*操作符必須作用在實現Deref的類型上,這到底是先有的雞,還是先有的蛋呢?
所以,不需要糾結這種被Rust開洞的特例,會使用即可。
寫在最后
*操作符的特性是,先將作用對象進行deref得到一個引用,再將&引用清除。如果只是想得到一個引用,那么使用&*或者deref()。
如果不好理解,可以這么去記憶:*是用來消除&和box符號的,當發現目標沒有&和box,就會調用deref函數去生成帶有&符號的類型,然后就可以愉快的消除了。
掌握好這個技巧,在遇到各種&和*操作符的時候,才不至于被迷惑,找不到深層次的代碼的實現原理。
如果你對技術也有追求,對現實迷茫,請關注我,帶你一起學習成長。總結
以上是生活随笔為你收集整理的gm怎么刷东西 rust_Rust语言:解引用详述,搞不明白这个概念,趁早放弃Rust的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何取消 登录_LSAT | 退考、缺考
- 下一篇: ad如何镜像器件_使用 Dockerfi