日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

gm怎么刷东西 rust_Rust语言:解引用详述,搞不明白这个概念,趁早放弃Rust

發布時間:2023/12/2 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。