聊聊Rust 運(yùn)算符
一元運(yùn)算符
顧名思義,一元操作符是專門對(duì)一個(gè) Rust 元素進(jìn)行操作的運(yùn)算符,主要包括以下幾個(gè):
-
:取負(fù),專門用于數(shù)值類型。實(shí)現(xiàn)了 std::ops::Neg。*
:解引用。實(shí)現(xiàn)了 std::ops::Deref 或 std::ops::DerefMut。!
:取反。例如 !false 相當(dāng)于 true。有意思的是,如果這個(gè)操作符對(duì)數(shù)字類型使用,會(huì)將其每一位都置反!也就是說(shuō),對(duì)一個(gè) 1u8 進(jìn)行 ! 操作,將得到一個(gè) 254u8。實(shí)現(xiàn)了 std::ops::Not。&
和&mut
:租借,borrow。向一個(gè) owner 租借其使用權(quán),分別租借一個(gè)只讀使用權(quán)和讀寫使用權(quán)。
二元運(yùn)算符
算數(shù)操作符
+
:加法。實(shí)現(xiàn)了 std::ops::Add。-
:減法。實(shí)現(xiàn)了 std::ops::Sub。*
:乘法。實(shí)現(xiàn)了 std::ops::Mul。/
:除法。實(shí)現(xiàn)了 std::ops::Div。%
:取余。實(shí)現(xiàn)了 std::ops::Rem。
位運(yùn)算符
&
:與操作。實(shí)現(xiàn)了 std::ops::BitAnd。|
:或操作。實(shí)現(xiàn)了 std::ops::BitOr。- -
^
:異或。實(shí)現(xiàn)了 std::ops::BitXor。 <<
:左移運(yùn)算符。實(shí)現(xiàn)了 std::ops::Shl。>>
:右移運(yùn)算符。實(shí)現(xiàn)了 std::ops::Shr。
惰性 boolean 運(yùn)算符
邏輯運(yùn)算符有三個(gè),分別是 &&
、||
和!
。其中前兩個(gè)叫做惰性 boolean 運(yùn)算符,之所以叫這個(gè)名字,是因?yàn)樵?Rust 中也會(huì)出現(xiàn)其他類 C 語(yǔ)言的邏輯短路問(wèn)題,所以取了這么一個(gè)名字。其作用和 C 語(yǔ)言里的一模一樣。不過(guò)不同的是,Rust 里這個(gè)運(yùn)算符只能用在 bool 類型上。
比較運(yùn)算符
比較運(yùn)算符實(shí)際上也是某些 trait 的語(yǔ)法糖,不過(guò)比較運(yùn)算符所實(shí)現(xiàn)的 trait 只有2個(gè):std::cmp::PartialEq
和 std::cmp::PartialOrd
。
其中,==
和!=
實(shí)現(xiàn)的是 PartialEq,<
、>
、>=
和 <=
實(shí)現(xiàn)的是 PartialOrd。
標(biāo)準(zhǔn)庫(kù)中,std::cmp
這個(gè) mod 下有4個(gè) trait,而且直觀來(lái)看 Ord 和 Eq 豈不是更好?但 Rust 對(duì)于這4個(gè) trait 的處理是很明確的。因?yàn)樵诟↑c(diǎn)數(shù)有一個(gè)特殊的值叫 NaN
,這個(gè)值表示未定義的一個(gè)浮點(diǎn)數(shù)。在 Rust 中可以用0.0f32 / 0.0f32
來(lái)求得其值,這個(gè)數(shù)是一個(gè)都確定的值,但它表示的是一個(gè)不確定的數(shù),那么NaN != NaN
的結(jié)果是啥?標(biāo)準(zhǔn)庫(kù)告訴我們是 true
。但這么寫有不符合Eq
定義里的total equal
(每位一樣兩個(gè)數(shù)就一樣)的定義。因此有了 PartialEq
這么一個(gè)定義,NaN 這個(gè)情況就給它特指了。
為了普適的情況,Rust 的編譯器就選擇了PartialOrd
和PartialEq
來(lái)作為其默認(rèn)的比較符號(hào)的trait
。
類型轉(zhuǎn)換運(yùn)算符
這個(gè)看起來(lái)并不算個(gè)運(yùn)算符,因?yàn)樗莻€(gè)單詞 as。就是類似于其他語(yǔ)言中的顯示轉(zhuǎn)換了。
fn avg(vals: &[f64]) -> f64 { let sum: f64 = sum(vals); let num: f64 = len(vals) as f64; sum / num }
重載運(yùn)算符
上面說(shuō)了很多 trait,就是為了運(yùn)算符重載。Rust 是支持運(yùn)算符重載的。更詳細(xì)的部分,會(huì)在后續(xù)章節(jié)中介紹。這是一個(gè)例子:
use std::ops::{Add, Sub}; \#[derive(Copy, Clone)] struct A(i32); impl Add for A { type Output = A; fn add(self, rhs: A) -> A { A(self.0 - rhs.0) } } impl Sub for A { type Output = A; fn sub(self, rhs: A) -> A{ A(self.0 + rhs.0) } } fn main() { let a1 = A(10i32); let a2 = A(5i32); let a3 = a1 + a2; println!("{}", (a3).0); let a4 = a1 - a2; println!("{}", (a4).0); }
Finished debug [unoptimized + debuginfo] target(s) in 0.0 secs Running `yourpath\hello_world\target\debug\hello_world.exe` 5 15
格式化字符串
Rust 采取了一種類似 Python 里面 format 的用法,其核心組成是5個(gè)宏和兩個(gè) trait :
format!
、format_arg!
、print!
、println!
、write!
和 Debug
、Display
。
之前在 hello_world 里已經(jīng)使用了 print!
或者 println!
這兩個(gè)宏,但是最核心的是 format!
,前兩個(gè)宏只不過(guò)是將format!
的結(jié)果輸出到 console 而已。
先來(lái)分析一個(gè)format!
的應(yīng)用:
fn main() { let s = format!("今天是{0}年{1}月{2}日, {week:?}, 氣溫{3:>0width$} ~ {4:>0width$} 攝氏度。", 2016, 11, 24, 3, -6, week = "Thursday", width = 2); print!("{}", s); }
可以看到,format!
宏調(diào)用的時(shí)候參數(shù)可以是任意類型,而且可以 position 參數(shù)和 key-value 參數(shù)混合使用。但要注意一點(diǎn),key-value 的值只能出現(xiàn)在 position 值之后并且不占用 position。比如把上面的代碼改動(dòng)一下:
fn main() { let s = format!("今天是{0}年{1}月{2}日, {week:?}, 氣溫{3:>0width$} ~ {4:>0width$} 攝氏度。", 2016, 11, 24, week = "Thursday", 3, -6, width = 2); print!("{}", s); }
這樣將會(huì)報(bào)錯(cuò):
Compiling hello_world v0.1.0 (yourpath/hello_world)
error: expected ident, positional arguments cannot follow named arguments
--> main.rs:3:42
|
3 | 2016, 11, 24, week = "Thursday", 3, -6, width = 3);
| ^error: aborting due to previous error
error: Could not compile `hello_world`.
還需要注意的是,參數(shù)類型必須要實(shí)現(xiàn)std::fmt
mod 下的某些 trait。比如原生類型大部分都實(shí)現(xiàn)了 Display
和 Debug
這兩個(gè)宏,整數(shù)類型還額外實(shí)現(xiàn)了Binary
,等等。
可以通過(guò) {:type}
的方式取調(diào)用這些參數(shù)。比如:
format!(":b", 2); // 調(diào)用 `Binary` trait format!(":?", "hello"); // 調(diào)用 `Debug`
如果 type 為空的話默認(rèn)調(diào)用 Display。
冒號(hào) : 后面還有更多參數(shù),比如上面代碼中的{3:>0wth$}
和 {4:>0wth$}
。首先 > 是一個(gè)語(yǔ)義,它表示的是生成的字符串向右對(duì)齊,于是上面的代碼得到了003
和 -06
這兩個(gè)值。與之相對(duì)的還有向左對(duì)齊 <
和居中 ^
。
接下來(lái)0
是一種特殊的填充語(yǔ)法,他表示用 0 補(bǔ)齊數(shù)字的空位,而 wth& 表示格式化后的字符串長(zhǎng)度。它可以是一個(gè)精確的長(zhǎng)度數(shù)值,也可以是一個(gè)以$
為結(jié)尾的字符串,$
前面的部分可以寫一個(gè) key 或者一個(gè) position。
還要注意的是,在 wth 和 type 之間會(huì)有一個(gè)叫精度的區(qū)域,他們的表示通常是以 . 開始的,比如.4
表示小數(shù)點(diǎn)后4位精度。最讓人糟心的是,任然可以在這個(gè)位置引用參數(shù),只需要個(gè)上面 wth 一樣,用.N$
來(lái)表示一個(gè) position 的參數(shù),只是就是不能引用 key-value 類型的。比如:
fn main() { // Hello {arg 0 ("x")} is {arg 1 (0.01) with precision specified inline (5)} println!("Hello {0} is {1:.5}", "x", 0.01); // Hello {arg 1 ("x")} is {arg 2 (0.01) with precision specified in arg 0 (5)} println!("Hello {1} is {2:.0$}", 5, "x", 0.01); // Hello {arg 0 ("x")} is {arg 2 (0.01) with precision specified in arg 1 (5)} println!("Hello {0} is {2:.1$}", "x", 5, 0.01); }
將輸出:
Hello x is 0.01000
Hello x is 0.01000
Hello x is 0.01000
這一位還有一個(gè)特殊的用法,那就是 .*,它不表示一個(gè)值,而是表示兩個(gè)值。第一個(gè)值表示精確的位數(shù),第二個(gè)值標(biāo)表示這個(gè)值本身。例如:
fn main() { // Hello {next arg ("x")} is {second of next two args (0.01) with precision // specified in first of next two args (5)} println!("Hello {} is {:.*}", "x", 5, 0.01); // Hello {next arg ("x")} is {arg 2 (0.01) with precision // specified in its predecessor (5)} println!("Hello {} is {2:.*}", "x", 5, 0.01); // Hello {next arg ("x")} is {arg "number" (0.01) with precision specified // in arg "prec" (5)} println!("Hello {} is {number:.prec$}", "x", prec = 5, number = 0.01); }
這個(gè)例子將輸出:
Hello x is 0.01000
Hello x is 0.01000
Hello x is 0.01000
可以在標(biāo)準(zhǔn)庫(kù)文檔查看更多format!
的說(shuō)明。
到此這篇關(guān)于Rust 運(yùn)算符的文章就介紹到這了,更多相關(guān)Rust 運(yùn)算符內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
從零開始使用Rust編寫nginx(TLS證書快過(guò)期了)
wmproxy已用Rust實(shí)現(xiàn)http/https代理,?socks5代理,?反向代理,?負(fù)載均衡,?靜態(tài)文件服務(wù)器,websocket代理,四層TCP/UDP轉(zhuǎn)發(fā),內(nèi)網(wǎng)穿透等,本文給大家介紹從零開始使用Rust編寫nginx(TLS證書快過(guò)期了),感興趣的朋友一起看看吧2024-03-03Rust?搭建一個(gè)小程序運(yùn)行環(huán)境的方法詳解
rust是一門比較新的編程語(yǔ)言,2015年5月15日,Rust編程語(yǔ)言核心團(tuán)隊(duì)正式宣布發(fā)布Rust?1.0版本,本文給大家介紹Rust?搭建一個(gè)小程序運(yùn)行環(huán)境,以iOS?為例介紹開發(fā)環(huán)境的準(zhǔn)備,感興趣的朋友跟隨小編一起看看吧2022-05-05MacBook Pro安裝rust編程環(huán)境的過(guò)程
rustup是一個(gè)用于管理Rust版本和工具鏈的工具,這篇文章主要介紹了MacBook Pro安裝rust編程環(huán)境的過(guò)程,感興趣的朋友跟隨小編一起看看吧2024-02-02Rust個(gè)人學(xué)習(xí)小結(jié)之Rust的循環(huán)
這篇文章主要介紹了Rust個(gè)人學(xué)習(xí)小結(jié)之Rust的循環(huán),今天主要了解了Rust語(yǔ)言的3種循環(huán)方法:?loop、while、for,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-01-01為什么要使用 Rust 語(yǔ)言、Rust 語(yǔ)言有什么優(yōu)勢(shì)
雖然 Rust 是一種通用的多范式語(yǔ)言,但它的目標(biāo)是 C 和 C++占主導(dǎo)地位的系統(tǒng)編程領(lǐng)域,很多朋友會(huì)問(wèn)rust語(yǔ)言難學(xué)嗎?rust語(yǔ)言可以做什么,今天帶著這些疑問(wèn)通過(guò)本文詳細(xì)介紹下,感興趣的朋友一起看看吧2022-10-10Rust字符串字面值的一些經(jīng)驗(yàn)總結(jié)
字符串有兩種表現(xiàn)形式,一種是基本類型,表示字符串的切片,以&str表示,另一種是可變的string類型,下面這篇文章主要給大家介紹了關(guān)于Rust字符串字面值的相關(guān)資料,需要的朋友可以參考下2022-04-04