第12ç« è¿ç®ç¬¦éè½½
# 第12ç« è¿ç®ç¬¦éè½½
å¨ç¬¬2ç« å±ç¤ºçæ¼å¾·å¸æ´ç¹éåç»å¾ç¨åºä¸ï¼æä»¬ä½¿ç¨numåºçComplexç±»åæ¥è¡¨ç¤ºå¤å¹³é¢ä¸çæ°åï¼
#[derive(Clone, Copy, Debug)]
struct Complex<T> {
/// 夿°çå®é¨
re: T,
/// 夿°çèé¨
im: T,
}
2
3
4
5
6
7
æä»¬è½å¤å使ç¨ä»»ä½å
ç½®æ°å¼ç±»å䏿 ·ï¼ä½¿ç¨Rustç+å*è¿ç®ç¬¦å¯¹Complexæ°åè¿è¡å æ³å乿³è¿ç®ï¼
z = z * z + c;
éè¿å®ç°ä¸äºå ç½®ç¹æ§ï¼ä½ ä¹å¯ä»¥è®©èªå·±å®ä¹çç±»åæ¯æç®æ¯è¿ç®åå ¶ä»è¿ç®ç¬¦ãè¿è¢«ç§°ä¸ºè¿ç®ç¬¦éè½½ï¼å ¶ææä¸C++ãC#ãPythonåRubyä¸çè¿ç®ç¬¦éè½½é常ç¸ä¼¼ã
æ ¹æ®ææ¯æçè¯è¨åè½ï¼ç¨äºè¿ç®ç¬¦éè½½çç¹æ§å¯å为å ç±»ï¼å¦è¡¨12-1æç¤ºã卿¬ç« ä¸ï¼æä»¬å°æ¶µçæ¯ä¸ç±»ç¹æ§ãæä»¬çç®æ ä¸ä» æ¯å¸®å©ä½ å°èªå·±å®ä¹çç±»åå¾å¥½å°èå ¥å°Rustè¯è¨ä¸ï¼è¿å¸æè®©ä½ æ´å¥½å°çè§£å¦ä½ç¼åå âååå·¥ç¨çº¦æâ ä¸æè¿°çç¹ç§¯å½æ°é£æ ·çæ³å彿°ï¼è¿äºæ³å彿°è½ä»¥æèªç¶çæ¹å¼å¯¹ä½¿ç¨è¿äºè¿ç®ç¬¦çç±»åè¿è¡æä½ãæ¬ç« è¿å°è®©ä½ æ·±å ¥äºè§£Rustè¯è¨æ¬èº«çä¸äºç¹æ§æ¯å¦ä½å®ç°çã 表12-1 è¿ç®ç¬¦éè½½ç¹æ§æ»ç»
| ç±»å« | ç¹æ§ | è¿ç®ç¬¦ |
|---|---|---|
| ä¸å è¿ç®ç¬¦ | std::ops::Neg | -x |
std::ops::Not | !x | |
| ç®æ¯è¿ç®ç¬¦ | std::ops::Add | x + y |
std::ops::Sub | x - y | |
std::ops::Mul | x * y | |
std::ops::Div | x / y | |
std::ops::Rem | x % y | |
| ä½è¿ç®ç¬¦ | std::ops::BitAnd | x & y |
std::ops::BitOr | x | y | |
std::ops::BitXor | x ^ y | |
std::ops::Shl | x << y | |
std::ops::Shr | x >> y | |
| å¤åèµå¼ç®æ¯è¿ç®ç¬¦ | std::ops::AddAssign | x += y |
std::ops::SubAssign | x -= y | |
std::ops::MulAssign | x *= y | |
std::ops::DivAssign | x /= y | |
std::ops::RemAssign | x %= y | |
| å¤åèµå¼ä½è¿ç®ç¬¦ | std::ops::BitAndAssign | x &= y |
std::ops::BitOrAssign | x |= y | |
std::ops::BitXorAssign | x ^= y | |
std::ops::ShlAssign | x <<= y | |
std::ops::ShrAssign | x >>= y | |
| æ¯è¾è¿ç®ç¬¦ | std::cmp::PartialEq | x == yï¼x != y |
std::cmp::PartialOrd | x < yï¼x <= yï¼x > yï¼x >= y | |
| ç´¢å¼è¿ç®ç¬¦ | std::ops::Index | x[y]ï¼&x[y] |
std::ops::IndexMut | x[y] = zï¼&mut x[y] |
# ç®æ¯è¿ç®ç¬¦åä½è¿ç®ç¬¦
å¨Rustä¸ï¼è¡¨è¾¾å¼a + bå®é
䏿¯a.add(b)çç®åå½¢å¼ï¼è¿æ¯å¯¹æ ååºä¸std::ops::Addç¹æ§çaddæ¹æ³çè°ç¨ãRustçæ åæ°å¼ç±»åé½å®ç°äºstd::ops::Addã为äºè®©a + bè¿æ ·ç表达å¼å¯¹Complexå¼ä¹è½èµ·ä½ç¨ï¼numåºä¹ä¸ºComplexå®ç°äºè¿ä¸ªç¹æ§ã类似çç¹æ§æ¶µçäºå
¶ä»è¿ç®ç¬¦ï¼a * bæ¯a.mul(b)çç®åï¼a.mul(b)æ¯std::ops::Mulç¹æ§çä¸ä¸ªæ¹æ³ï¼std::ops::Negæ¶µçäºåç¼-ååè¿ç®ç¬¦ï¼ççã
å¦æä½ æ³å°è¯ååºz.add(c)ï¼å°±éè¦å°Addç¹æ§å¼å
¥ä½ç¨åï¼è¿æ ·å®çæ¹æ³æè½å¯è§ã宿è¿ä¸æ¥åï¼ä½ å¯ä»¥æææç®æ¯è¿ç®å½ä½å½æ°è°ç¨ï¼
use std::ops::Add;
assert_eq!(4.125f32.add(5.75), 9.875);
assert_eq!(10.add(20), 10 + 20);
2
3
ä¸é¢æ¯std::ops::Addçå®ä¹ï¼
trait Add<Rhs = Self> {
type Output;
fn add(self, rhs: Rhs) -> Self::Output;
}
2
3
4
æ¢å¥è¯è¯´ï¼Add<T>ç¹æ§è¡¨ç¤ºè½å¤å°ä¸ä¸ªTç±»åçå¼ä¸èªèº«ç¸å ãä¾å¦ï¼å¦æä½ 叿è½å¤å°i32åu32ç±»åçå¼ä¸ä½ çç±»åç¸å ï¼é£ä¹ä½ çç±»åå¿
须忶å®ç°Add<i32>åAdd<u32>ãè¯¥ç¹æ§çç±»ååæ°Rhsé»è®¤ä¸ºSelfï¼æä»¥å¦æä½ è¦å®ç°ç¸åç±»åç两个å¼ä¹é´çå æ³ï¼è¿ç§æ
åµä¸ç®åå°åAddå³å¯ãå
³èç±»åOutputæè¿°äºå æ³è¿ç®çç»æã
ä¾å¦ï¼ä¸ºäºè½å¤å°Complex<i32>ç±»åçå¼ç¸å ï¼Complex<i32>å¿
é¡»å®ç°Add<Complex<i32>>ãå 为æä»¬æ¯å°ä¸ä¸ªç±»åä¸å
¶èªèº«ç¸å ï¼æä»¥è¿éåªåAddï¼
use std::ops::Add;
impl Add for Complex<i32> {
type Output = Complex<i32>;
fn add(self, rhs: Self) -> Self {
Complex {
re: self.re + rhs.re,
im: self.im + rhs.im,
}
}
}
2
3
4
5
6
7
8
9
10
11
å½ç¶ï¼æä»¬ä¸åºè¯¥åå«ä¸ºComplex<i32>ãComplex<f32>ãComplex<f64>çå®ç°Addãé¤äºæ¶åçç±»åä¸åï¼ææè¿äºå®ä¹çèµ·æ¥é½å®å
¨ä¸æ ·ï¼æä»¥åªè¦å¤æ°ç»ä»¶æ¬èº«çç±»åæ¯æå æ³ï¼æä»¬å°±åºè¯¥è½å¤ç¼åä¸ä¸ªéç¨çå®ç°æ¥æ¶µçæææ
åµï¼
use std::ops::Add;
impl<T> Add for Complex<T>
where
T: Add<Output = T>,
{
type Output = Self;
fn add(self, rhs: Self) -> Self {
Complex {
re: self.re + rhs.re,
im: self.im + rhs.im,
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
éè¿ç¼åwhere T: Add<Output=T>ï¼æä»¬å°Téå¶ä¸ºå¯ä»¥ä¸èªèº«ç¸å 并产çå¦ä¸ä¸ªTç±»åå¼çç±»åãè¿æ¯ä¸ä¸ªåççéå¶ï¼ä½æä»¬è¿å¯ä»¥è¿ä¸æ¥æ¾å®½æ¡ä»¶ï¼Addç¹æ§å¹¶ä¸è¦æ±+è¿ç®ç¬¦ç两个æä½æ°å
·æç¸åçç±»åï¼ä¹ä¸éå¶ç»æç±»åãæä»¥ï¼ä¸ä¸ªæå¤§é度éç¨çå®ç°å¯ä»¥è®©å·¦å³æä½æ°ç¬ç«ååï¼å¹¶äº§çç±å æ³è¿ç®ç»æç±»åä½ä¸ºç»ä»¶ç±»åçComplexå¼ï¼
use std::ops::Add;
impl<L, R> Add<Complex<R>> for Complex<L>
where
L: Add<R>,
{
type Output = Complex<L::Output>;
fn add(self, rhs: Complex<R>) -> Self::Output {
Complex {
re: self.re + rhs.re,
im: self.im + rhs.im,
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
ç¶èå¨å®è·µä¸ï¼Rustå¾åäºé¿å
æ¯ææ··åç±»åè¿ç®ãç±äºæä»¬çç±»ååæ°Lå¿
é¡»å®ç°Add<R>ï¼é常æ
åµä¸LåR伿¯ç¸åçç±»åï¼å®é
ä¸ï¼è½è®©Lå®ç°å
¶ä»ç±»åå æ³çæ
åµå¹¶ä¸å¤ãæä»¥æç»ï¼è¿ä¸ªæå¤§é度éç¨ççæ¬å¯è½å¹¶ä¸æ¯ä¹åé£ä¸ªæ´ç®åçéç¨å®ä¹æ´æç¨ã
Rustä¸ç¨äºç®æ¯åä½è¿ç®ç¬¦çå ç½®ç¹æ§å为ä¸ç»ï¼ä¸å è¿ç®ç¬¦ãäºå è¿ç®ç¬¦åå¤åèµå¼è¿ç®ç¬¦ã卿¯ç»ä¸ï¼ç¹æ§åå ¶æ¹æ³é½å ·æç¸åçå½¢å¼ï¼æä»¥æä»¬å°ä»æ¯ç»ä¸éåä¸ä¸ªç¤ºä¾è¿è¡ä»ç»ã
# ä¸å è¿ç®ç¬¦
é¤äºè§£å¼ç¨è¿ç®ç¬¦*ï¼æä»¬å°å¨ âDerefåDerefMutâ ä¸åç¬ä»ç»ï¼ï¼Rustæä¸¤ä¸ªå¯ä»¥èªå®ä¹çä¸å
è¿ç®ç¬¦ï¼å¦è¡¨12-2æç¤ºã
表12-2 ä¸å
è¿ç®ç¬¦çå
ç½®ç¹æ§
| ç¹æ§åç§° | è¡¨è¾¾å¼ | çæè¡¨è¾¾å¼ |
|---|---|---|
std::ops::Neg | -x | x.neg() |
std::ops::Not | !x | x.not() |
Rustçæææç¬¦å·æ°å¼ç±»åé½å®ç°äºstd::ops::Negï¼ç¨äºä¸å
ååè¿ç®ç¬¦-ï¼æ´æ°ç±»ååboolç±»åå®ç°äºstd::ops::Notï¼ç¨äºä¸å
è¡¥ç è¿ç®ç¬¦!ã对äºè¿äºç±»åçå¼ç¨ä¹æç¸åºçå®ç°ã
注æï¼!对boolå¼è¿è¡ååï¼å¯¹æ´æ°æ§è¡æä½ååï¼å³ç¿»è½¬ææä½ï¼æä½ï¼å®å
¼å
·CåC++ä¸!å~è¿ç®ç¬¦çåè½ã
è¿äºç¹æ§çå®ä¹å¾ç®åï¼
trait Neg {
type Output;
fn neg(self) -> Self::Output;
}
trait Not {
type Output;
fn not(self) -> Self::Output;
}
2
3
4
5
6
7
8
9
对ä¸ä¸ªå¤æ°ååï¼åªé对å
¶æ¯ä¸ªåéååå³å¯ãä¸é¢æ¯æä»¬å¯è½ä¸ºComplexå¼ç¼åçéç¨ååå®ç°ï¼
use std::ops::Neg;
impl<T> Neg for Complex<T>
where
T: Neg<Output = T>,
{
type Output = Complex<T>;
fn neg(self) -> Complex<T> {
Complex {
re: -self.re,
im: -self.im,
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
# äºå è¿ç®ç¬¦
Rustçäºå ç®æ¯è¿ç®ç¬¦åä½è¿ç®ç¬¦åå ¶å¯¹åºçå ç½®ç¹æ§å¦è¡¨12-3æç¤ºã 表12-3 äºå è¿ç®ç¬¦çå ç½®ç¹æ§
| ç±»å« | ç¹æ§åç§° | è¡¨è¾¾å¼ | çæè¡¨è¾¾å¼ |
|---|---|---|---|
| ç®æ¯è¿ç®ç¬¦ | std::ops::Add | x + y | x.add(y) |
std::ops::Sub | x - y | x.sub(y) | |
std::ops::Mul | x * y | x.mul(y) | |
std::ops::Div | x / y | x.div(y) | |
std::ops::Rem | x % y | x.rem(y) | |
| ä½è¿ç®ç¬¦ | std::ops::BitAnd | x & y | x.bitand(y) |
std::ops::BitOr | x | y | x.bitor(y) | |
std::ops::BitXor | x ^ y | x.bitxor(y) | |
std::ops::Shl | x << y | x.shl(y) | |
std::ops::Shr | x >> y | x.shr(y) |
Rustçæææ°å¼ç±»åé½å®ç°äºç®æ¯è¿ç®ç¬¦ãRustçæ´æ°ç±»ååboolç±»åå®ç°äºä½è¿ç®ç¬¦ã对äºè¿äºç±»åçå¼ç¨ä½ä¸ºä¸ä¸ªæä¸¤ä¸ªæä½æ°çæ
åµï¼ä¹æç¸åºçå®ç°ã
è¿éææçç¹æ§é½å
·æç¸åçä¸è¬å½¢å¼ãç¨äº^è¿ç®ç¬¦çstd::ops::BitXorçå®ä¹å¦ä¸ï¼
trait BitXor<Rhs = Self> {
type Output;
fn bitxor(self, rhs: Rhs) -> Self::Output;
}
2
3
4
卿¬ç« å¼å¤´ï¼æä»¬è¿å±ç¤ºäºstd::ops::Addï¼å®æ¯è¿ä¸ç±»ç¹æ§ä¸çå¦ä¸ä¸ªï¼ä»¥åå 个示ä¾å®ç°ã
ä½ å¯ä»¥ä½¿ç¨+è¿ç®ç¬¦å°Stringä¸&stråçæå¦ä¸ä¸ªStringè¿æ¥èµ·æ¥ãç¶èï¼Rustä¸å
许+çå·¦æä½æ°æ¯&strï¼è¿æ¯ä¸ºäºé¿å
éè¿ä¸æå¨å·¦è¾¹è¿æ¥å°çæ®µæ¥æå»ºé¿å符串ï¼è¿ç§æ¹å¼æ§è½è¾å·®ï¼æéæ¶é´ä¸æç»å符串é¿åº¦çå¹³æ¹ææ£æ¯ï¼ãä¸è¬æ¥è¯´ï¼write!宿´éåéæ®µæå»ºåç¬¦ä¸²ï¼æä»¬å°å¨ â追å åæå
¥ææ¬â ä¸å±ç¤ºå¦ä½æä½ã
# å¤åèµå¼è¿ç®ç¬¦
å¤åèµå¼è¡¨è¾¾å¼ï¼å¦x += yæx &= yï¼è¿ç±»è¡¨è¾¾å¼æä¸¤ä¸ªæä½æ°ï¼å¯¹å®ä»¬æ§è¡å æ³ææä½ä¸çè¿ç®ï¼å¹¶å°ç»æåå¨åå·¦æä½æ°ä¸ãå¨Rustä¸ï¼å¤åèµå¼è¡¨è¾¾å¼çå¼å§ç»æ¯()ï¼è䏿¯åå¨çç»æå¼ã
许å¤è¯è¨é½æç±»ä¼¼çè¿ç®ç¬¦ï¼é常å°å®ä»¬å®ä¹ä¸ºx = x + yæx = x & yç表达å¼çç®åå½¢å¼ãç¶èï¼Rustå¹¶ä¸éç¨è¿ç§æ¹å¼ã
ç¸åï¼x += yæ¯æ¹æ³è°ç¨x.add_assign(y)çç®åå½¢å¼ï¼å
¶ä¸add_assignæ¯std::ops::AddAssignç¹æ§çå¯ä¸æ¹æ³ï¼
trait AddAssign<Rhs = Self> {
fn add_assign(&mut self, rhs: Rhs);
}
2
3
表12-4å±ç¤ºäºRustçææå¤åèµå¼è¿ç®ç¬¦ä»¥åå®ç°å®ä»¬çå ç½®ç¹æ§ã 表12-4 å¤åèµå¼è¿ç®ç¬¦çå ç½®ç¹æ§
| ç±»å« | ç¹æ§åç§° | è¡¨è¾¾å¼ | çæè¡¨è¾¾å¼ |
|---|---|---|---|
| ç®æ¯è¿ç®ç¬¦ | std::ops::AddAssign | x += y | x.add_assign(y) |
std::ops::SubAssign | x -= y | x.sub_assign(y) | |
std::ops::MulAssign | x *= y | x.mul_assign(y) | |
std::ops::DivAssign | x /= y | x.div_assign(y) | |
std::ops::RemAssign | x %= y | x.rem_assign(y) | |
| ä½è¿ç®ç¬¦ | std::ops::BitAndAssign | x &= y | x.bitand_assign(y) |
std::ops::BitOrAssign | x |= y | x.bitor_assign(y) | |
std::ops::BitXorAssign | x ^= y | x.bitxor_assign(y) | |
std::ops::ShlAssign | x <<= y | x.shl_assign(y) | |
std::ops::ShrAssign | x >>= y | x.shr_assign(y) |
Rustçæææ°å¼ç±»åé½å®ç°äºç®æ¯å¤åèµå¼è¿ç®ç¬¦ãRustçæ´æ°ç±»ååboolç±»åå®ç°äºä½å¤åèµå¼è¿ç®ç¬¦ã
为æä»¬çComplexç±»åç¼åä¸ä¸ªéç¨çAddAssignå®ç°å¾ç®åï¼
use std::ops::AddAssign;
impl<T> AddAssign for Complex<T>
where
T: AddAssign<T>,
{
fn add_assign(&mut self, rhs: Complex<T>) {
self.re += rhs.re;
self.im += rhs.im;
}
}
2
3
4
5
6
7
8
9
10
11
å¤åèµå¼è¿ç®ç¬¦çå
ç½®ç¹æ§ä¸ç¸åºäºå
è¿ç®ç¬¦çå
ç½®ç¹æ§æ¯å®å
¨ç¬ç«çãå®ç°std::ops::Addå¹¶ä¸ä¼èªå¨å®ç°std::ops::AddAssignï¼å¦æä½ 叿Rustå
è®¸ä½ çç±»åä½ä¸º+=è¿ç®ç¬¦çå·¦æä½æ°ï¼å°±å¿
é¡»èªå·±å®ç°AddAssignã
# çä»·æ¯è¾
Rustçç¸çè¿ç®ç¬¦==å!=æ¯å¯¹std::cmp::PartialEqç¹æ§çeqåneæ¹æ³è°ç¨çç®åå½¢å¼ï¼
assert_eq!(x == y, x.eq(&y));
assert_eq!(x != y, x.ne(&y));
2
ä¸é¢æ¯std::cmp::PartialEqçå®ä¹ï¼
trait PartialEq<Rhs = Self>
where
Rhs: ?Sized,
{
fn eq(&self, other: &Rhs) -> bool;
fn ne(&self, other: &Rhs) -> bool {
!self.eq(other)
}
}
2
3
4
5
6
7
8
9
ç±äºneæ¹æ³æé»è®¤å®ä¹ï¼æä»¥è¦å®ç°PartialEqç¹æ§ï¼ä½ åªéè¦å®ä¹eqæ¹æ³å³å¯ãä¸é¢æ¯Complexç±»åç宿´å®ç°ï¼
impl<T: PartialEq> PartialEq for Complex<T> {
fn eq(&self, other: &Complex<T>) -> bool {
self.re == other.re && self.im == other.im
}
}
2
3
4
5
æ¢å¥è¯è¯´ï¼å¯¹äºä»»ä½æ¬èº«å¯ä»¥è¿è¡ç¸çæ¯è¾çç»ä»¶ç±»åTï¼è¿ä¸ªå®ç°ä¸ºComplex<T>æä¾äºç¸çæ¯è¾åè½ãå设æä»¬å¨æä¸ªå°æ¹ä¹ä¸ºComplexå®ç°äºstd::ops::Mulï¼ç°å¨å°±å¯ä»¥è¿æ ·åï¼
let x = Complex { re: 5, im: 2 };
let y = Complex { re: 2, im: 5 };
assert_eq!(x * y, Complex { re: 0, im: 29 });
2
3
PartialEqçå®ç°é叏齿¯åè¿æ ·çå½¢å¼ï¼å°å·¦æä½æ°çæ¯ä¸ªå段ä¸å³æä½æ°çç¸åºå段è¿è¡æ¯è¾ãç¼åè¿äºå®ç°ä¼å¾ç¹çï¼èç¸çæ¯è¾æ¯ä¸ä¸ªå¸¸ç¨çæä½ï¼æä»¥å¦æä½ æéæ±ï¼Rustä¼èªå¨ä¸ºä½ çæPartialEqçå®ç°ãåªéå¨ç±»åå®ä¹çderive屿§ä¸æ·»å PartialEqï¼å¦ä¸æç¤ºï¼
#[derive(Clone, Copy, Debug, PartialEq)]
struct Complex<T> {
...
}
2
3
4
Rustèªå¨çæçå®ç°ä¸æä»¬æåç代ç åºæ¬ç¸åï¼ä¾æ¬¡æ¯è¾ç±»åçæ¯ä¸ªåæ®µæå
ç´ ãRustä¹å¯ä»¥ä¸ºæä¸¾ç±»åæ´¾çPartialEqå®ç°ã
å½ç¶ï¼ç±»åæå
å«çå¼ï¼å¯¹äºæä¸¾ç±»åï¼æ¯å¯è½å
å«çå¼ï¼æ¬èº«é½å¿
é¡»å®ç°PartialEqã
ä¸ç®æ¯åä½è¿ç®ç¹æ§ä¸åï¼PartialEqéè¿å¼ç¨è·åæä½æ°ãè¿æå³çæ¯è¾åStringãVecæHashMapè¿æ ·çä¸å¯å¤å¶ï¼non-Copyï¼å¼æ¶ï¼ä¸ä¼å¯¼è´å®ä»¬è¢«ç§»å¨ï¼å¦åä¼å¸¦æ¥éº»ç¦ï¼
let s = "d\x6fv\x65t\x61i\x6c ".to_string();
let t = "\x64o\x76e\x74a\x69l".to_string();
assert!(s == t); // såtåªæ¯è¢«åç¨äº...
// ... æä»¥å®ä»¬å¨è¿éä»ç¶æå¼ã
assert_eq!(format!("{} {}", s, t), "dovetail dovetail");
2
3
4
5
è¿å°±å¼åºäºè¯¥ç¹æ§å¯¹Rhsç±»ååæ°ç约æï¼è¿æ¯æä»¬ä¹å没æè§è¿çä¸ç§çº¦æï¼
where
Rhs: ?Sized,
2
è¿æ¾å®½äºRustéå¸¸è¦æ±ç±»ååæ°å¿
é¡»æ¯ Sized ç±»åçéå¶ï¼ä½¿æä»¬è½å¤ç¼ååPartialEq<str>æPartialEq<[T]>è¿æ ·çç¹æ§ãeqåneæ¹æ³æ¥å&Rhsç±»åçåæ°ï¼å°æä¸ªå¼ä¸&stræ&[T]è¿è¡æ¯è¾æ¯å®å
¨åççãç±äºstrå®ç°äºPartialEq<str>ï¼ä»¥ä¸æè¨æ¯çæçï¼
assert!("ungula" != "ungulate");
assert!("ungula".ne("ungulate"));
2
è¿éï¼SelfåRhs齿¯æªç¡®å®å¤§å°çï¼unsizedï¼strç±»åï¼ä½¿å¾neçselfårhs忰齿¯&strå¼ã
æä»¬å°å¨ âSizedâ ä¸è¯¦ç»è®¨è®º Sized ç±»åãæªç¡®å®å¤§å°çç±»ååSizedç¹æ§ã
为ä»ä¹è¿ä¸ªç¹æ§è¢«ç§°ä¸ºPartialEqå¢ï¼ä¼ ç»æ°å¦ä¸å¯¹çä»·å
³ç³»ï¼ç¸çæ¯å
¶ä¸ä¸ç§æ
åµï¼çå®ä¹æä¸ä¸ªè¦æ±ã对äºä»»ä½å¼xåyï¼
- 妿
x == y为çï¼é£ä¹y == xä¹å¿ 须为çãæ¢å¥è¯è¯´ï¼äº¤æ¢ç¸çæ¯è¾ç两边ä¸ä¼å½±åç»æã - 妿
x == yä¸y == zï¼é£ä¹å¿ ç¶æx == zãç»å®ä»»ä½ä¸ä¸ªå¼é¾ï¼å ¶ä¸æ¯ä¸ªå¼é½çäºä¸ä¸ä¸ªå¼ï¼é£ä¹è¿ä¸ªé¾ä¸çæ¯ä¸ªå¼é½ç´æ¥çäºå ¶ä»ä»»ä½å¼ãç¸çå ³ç³»å ·æä¼ éæ§ã x == xå¿ é¡»å§ç»ä¸ºçã
æåä¸ä¸ªè¦æ±å¯è½çèµ·æ¥å¤ªææ¾ï¼é½ä¸å¼å¾ä¸æï¼ä½é®é¢æ°æ°åºå¨è¿éãRustçf32åf64æ¯IEEEæ åçæµ®ç¹å¼ãæ ¹æ®è¯¥æ åï¼å0.0/0.0è¿æ ·æ²¡æåéå¼ç表达å¼å¿
须产çç¹æ®çéæ°åå¼ï¼é常称为NaNå¼ã该æ åè¿ä¸æ¥è¦æ±ï¼NaNå¼å¿
须被è§ä¸ºä¸å
¶ä»ææå¼é½ä¸ç¸çï¼å
æ¬å®èªèº«ãä¾å¦ï¼è¯¥æ åè¦æ±ä»¥ä¸ææè¡ä¸ºï¼
assert!(f64::is_nan(0.0 / 0.0));
assert_eq!(0.0 / 0.0 == 0.0 / 0.0, false);
assert_eq!(0.0 / 0.0 != 0.0 / 0.0, true);
2
3
æ¤å¤ï¼ä»»ä½ä¸NaNå¼çæåºæ¯è¾é½å¿
é¡»è¿åfalseï¼
assert_eq!(0.0 / 0.0 < 0.0 / 0.0, false);
assert_eq!(0.0 / 0.0 > 0.0 / 0.0, false);
assert_eq!(0.0 / 0.0 <= 0.0 / 0.0, false);
assert_eq!(0.0 / 0.0 >= 0.0 / 0.0, false);
2
3
4
å æ¤ï¼è½ç¶Rustç==è¿ç®ç¬¦æ»¡è¶³çä»·å
³ç³»çåä¸¤ä¸ªè¦æ±ï¼ä½å¨ç¨äºIEEEæµ®ç¹å¼æ¶ï¼æ¾ç¶ä¸æ»¡è¶³ç¬¬ä¸ä¸ªè¦æ±ã
è¿è¢«ç§°ä¸ºé¨åçä»·å
³ç³»ï¼partial equivalence relationï¼ï¼æä»¥Rustå°==è¿ç®ç¬¦çå
ç½®ç¹æ§å½å为PartialEqãå¦æä½ ç¼åçæ³å代ç ä¸ï¼ç±»ååæ°åªå·²ç¥å®ç°äºPartialEqï¼é£ä¹ä½ å¯ä»¥å设åä¸¤ä¸ªè¦æ±æç«ï¼ä½ä¸åºåè®¾å¼æ»æ¯çäºå
¶èªèº«ã
è¿å¯è½æç¹è¿åç´è§ï¼å¦æä¸æ³¨æçè¯å¯è½ä¼å¯¼è´é误ãå¦æä½ å¸æä½ çæ³å代ç è¦æ±å®å
¨çä»·å
³ç³»ï¼å¯ä»¥ä½¿ç¨std::cmp::Eqç¹æ§ä½ä¸ºçº¦æï¼å®ä»£è¡¨å®å
¨çä»·å
³ç³»ï¼å¦æä¸ä¸ªç±»åå®ç°äºEqï¼é£ä¹å¯¹äºè¯¥ç±»åçæ¯ä¸ªå¼xï¼x == xé½å¿
须为çãå¨å®è·µä¸ï¼å 乿¯ä¸ªå®ç°äºPartialEqçç±»åä¹åºè¯¥å®ç°Eqï¼f32åf64æ¯æ ååºä¸ä»
æçå®ç°äºPartialEq使ªå®ç°Eqçç±»åã
æ ååºå°Eqå®ä¹ä¸ºPartialEqçæ©å±ï¼æ²¡ææ·»å æ°æ¹æ³ï¼
trait Eq : PartialEq<Self> {}
å¦æä½ çç±»åå®ç°äºPartialEqï¼å¹¶ä¸ä¹å¸æå®å®ç°Eqï¼é£ä¹å¿
é¡»æ¾å¼å®ç°Eqï¼å³ä½¿å®é
ä¸ä¸éè¦å®ä¹ä»»ä½æ°å½æ°æç±»åãæä»¥ä¸ºæä»¬çComplexç±»åå®ç°Eqå¾ç®åï¼
impl<T: Eq> Eq for Complex<T> {}
æä»¬è¿å¯ä»¥éè¿å¨Complexç±»åå®ä¹çderive屿§ä¸å
å«Eqï¼æ´ç®æ´å°å®ç°ï¼
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
struct Complex<T> {
...
}
2
3
4
对æ³åç±»åæ´¾ççå®ç°å¯è½ä¾èµäºç±»ååæ°ã使ç¨derive屿§æ¶ï¼Complex<i32>ä¼å®ç°Eqï¼å 为i32å®ç°äºEqï¼ä½Complex<f32>åªä¼å®ç°PartialEqï¼å 为f32没æå®ç°Eqã
å½ä½ èªå·±å®ç°std::cmp::PartialEqæ¶ï¼Rustæ æ³æ£æ¥ä½ 对eqåneæ¹æ³çå®ä¹æ¯å¦çæ£ç¬¦åé¨åæå®å
¨çä»·çè¦æ±ãå®ä»¬å¯ä»¥åä»»ä½ä½ æ³åçäºæ
ãRuståªæ¯ç¸ä¿¡ä½ 以符åè¯¥ç¹æ§ç¨æ·ææçæ¹å¼å®ç°äºç¸çæ¯è¾ã
è½ç¶PartialEqçå®ä¹ä¸ºneæä¾äºé»è®¤å®ç°ï¼ä½å¦æä½ æ¿æï¼ä¹å¯ä»¥æä¾èªå·±çå®ç°ãä¸è¿ï¼ä½ å¿
须确ä¿neåeqæ¯å®å
¨äºè¡¥çãPartialEqç¹æ§çç¨æ·ä¼è¿æ ·å设ã
# æåºæ¯è¾
Rustéè¿åä¸ç¹æ§std::cmp::PartialOrdæ¥å®ä¹æåºæ¯è¾è¿ç®ç¬¦<ã>ã<=å>=çè¡ä¸ºï¼
trait PartialOrd<Rhs = Self> : PartialEq<Rhs>
where
Rhs: ?Sized,
{
fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
fn lt(&self, other: &Rhs) -> bool { ... }
fn le(&self, other: &Rhs) -> bool { ... }
fn gt(&self, other: &Rhs) -> bool { ... }
fn ge(&self, other: &Rhs) -> bool { ... }
}
2
3
4
5
6
7
8
9
10
注æï¼PartialOrd<Rhs>æ©å±äºPartialEq<Rhs>ï¼åªæè½è¿è¡ç¸çæ¯è¾çç±»åï¼æè½è¿è¡æåºæ¯è¾ã
ä½ å¿
é¡»èªå·±å®ç°PartialOrdä¸å¯ä¸çæ¹æ³æ¯partial_cmpãå½partial_cmpè¿åSome(o)æ¶ï¼o表示selfä¸otherçå
³ç³»ï¼
enum Ordering {
Less, // self < other
Equal, // self == other
Greater, // self > other
}
2
3
4
5
ä½å¦æpartial_cmpè¿åNoneï¼è¿æå³çselfåotherä¹é´æ²¡æé¡ºåºå
³ç³»ï¼æ¢ä¸æ¯å¤§äºå
³ç³»ï¼ä¹ä¸ç¸çãå¨Rustçææåºæ¬ç±»åä¸ï¼åªææµ®ç¹å¼ä¹é´çæ¯è¾å¯è½ä¼è¿åNoneï¼å
·ä½æ¥è¯´ï¼å°NaNï¼éæ°åï¼å¼ä¸å
¶ä»ä»»ä½å¼è¿è¡æ¯è¾é½ä¼è¿åNoneã
æä»¬å¨âçä»·æ¯è¾âä¸å¯¹NaNå¼åäºæ´å¤ä»ç»ã
ä¸å
¶ä»äºå
è¿ç®ç¬¦ä¸æ ·ï¼è¦æ¯è¾LeftåRight两ç§ç±»åçå¼ï¼Leftå¿
é¡»å®ç°PartialOrd<Right>ãåx < yæx >= yè¿æ ·çè¡¨è¾¾å¼æ¯å¯¹PartialOrdæ¹æ³è°ç¨çç®åå½¢å¼ï¼å¦è¡¨12-5æç¤ºã
表12-5 æåºæ¯è¾è¿ç®ç¬¦åPartialOrdæ¹æ³
| è¡¨è¾¾å¼ | çææ¹æ³è°ç¨ | é»è®¤å®ä¹ |
|---|---|---|
x < y | x.lt(y) | x.partial_cmp(&y) == Some(Less) |
x > y | x.gt(y) | x.partial_cmp(&y) == Some(Greater) |
x <= y | x.le(y) | matches!(x.partial_cmp(&y), Some(Less) | Some(Equal)) |
x >= y | x.ge(y) | matches!(x.partial_cmp(&y), Some(Greater) | Some(Equal)) |
ä¸åé¢ç示ä¾ä¸æ ·ï¼è¿éå±ç¤ºççææ¹æ³è°ç¨ä»£ç å设std::cmp::PartialOrdåstd::cmp::Orderingå¨ä½ç¨åå
ã
å¦æä½ ç¥é两ç§ç±»åç弿»æ¯åå¨é¡ºåºå
³ç³»ï¼é£ä¹å¯ä»¥å®ç°æ´ä¸¥æ ¼çstd::cmp::Ordç¹æ§ï¼
trait Ord : Eq + PartialOrd<Self> {
fn cmp(&self, other: &Self) -> Ordering;
}
2
3
è¿éçcmpæ¹æ³åªè¿åä¸ä¸ªOrderingï¼èä¸åpartial_cmp飿 ·è¿åOption<Ordering>ï¼cmpæ»æ¯æç¡®è¡¨ç¤ºå
¶åæ°ç¸çï¼æè
æåºå®ä»¬çç¸å¯¹é¡ºåºãå 乿æå®ç°äºPartialOrdçç±»åä¹é½åºè¯¥å®ç°Ordã卿 ååºä¸ï¼f32åf64æ¯è¿æ¡è§åä»
æçä¾å¤ã
ç±äºå¤æ°ä¹é´æ²¡æèªç¶ç顺åºå
³ç³»ï¼æä»¥æä»¬ä¸è½ç¨åé¢ç« èä¸çComplexç±»åæ¥å±ç¤ºPartialOrdç示ä¾å®ç°ãåè®¾ä½ æ£å¨å¤ç以ä¸ç±»åï¼å®è¡¨ç¤ºè½å¨ç»å®åå¼åºé´å
çä¸ç»æ°åï¼
#[derive(Debug, PartialEq)]
struct Interval<T> {
lower: T, // å
å«ä¸é
upper: T, // ä¸å
å«ä¸é
}
2
3
4
5
ä½ å¸æè®©è¿ç§ç±»åçå¼å
·æé¨å顺åºå
³ç³»ï¼å¦æä¸ä¸ªåºé´å®å
¨å¨å¦ä¸ä¸ªåºé´ä¹åï¼ä¸æ²¡æéå ï¼é£ä¹è¿ä¸ªåºé´å°±å°äºå¦ä¸ä¸ªåºé´ãå¦æä¸¤ä¸ªä¸ç¸ççåºé´æéå ï¼é£ä¹å®ä»¬æ¯æ åºçï¼åæ¹é½åå¨ä¸äºå
ç´ å°äºå¯¹æ¹çä¸äºå
ç´ ãè两个ç¸ççåºé´å°±æ¯ç¸ççãä¸é¢å¯¹PartialOrdçå®ç°éµå¾ªäºè¿äºè§åï¼
use std::cmp::{Ordering, PartialOrd};
impl<T: PartialOrd> PartialOrd<Interval<T>> for Interval<T> {
fn partial_cmp(&self, other: &Interval<T>) -> Option<Ordering> {
if self == other {
Some(Ordering::Equal)
} else if self.lower >= other.upper {
Some(Ordering::Greater)
} else if self.upper <= other.lower {
Some(Ordering::Less)
} else {
None
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
æäºè¿ä¸ªå®ç°ï¼ä½ å°±å¯ä»¥ç¼å以ä¸ä»£ç ï¼
assert!(Interval { lower: 10, upper: 20 } < Interval { lower: 20, upper: 40 });
assert!(Interval { lower: 7, upper: 8 } >= Interval { lower: 0, upper: 8 });
assert!(Interval { lower: 7, upper: 8 } <= Interval { lower: 7, upper: 8 });
// éå çåºé´ä¹é´æ²¡æé¡ºåºå
³ç³»ã
let left = Interval { lower: 10, upper: 30 };
let right = Interval { lower: 20, upper: 40 };
assert!( !(left < right));
assert!( !(left >= right));
2
3
4
5
6
7
8
9
è½ç¶PartialOrdæ¯ä½ é常ä¼è§å°çï¼ä½å¨æäºæ
åµä¸ï¼æ¯å¦æ ååºä¸å®ç°çæåºæ¹æ³ï¼ä½¿ç¨Ordå®ä¹çå
¨åºå
³ç³»æ¯å¿
è¦çãä¾å¦ï¼ä»
é PartialOrdçå®ç°æ æ³å¯¹åºé´è¿è¡æåºãå¦æä½ ç¡®å®æ³å¯¹å®ä»¬è¿è¡æåºï¼å°±å¿
é¡»å¤çæ åºçæ
åµãæ¯å¦ï¼ä½ å¯è½æ³æä¸éè¿è¡æåºï¼ä½¿ç¨sort_by_keyå¾å®¹æåå°è¿ä¸ç¹ï¼
intervals.sort_by_key(|i| i.upper);
Reverseå
è£
ç±»åå©ç¨äºè¿ä¸ç¹ï¼å®éè¿ä¸ä¸ªæ¹æ³å®ç°äºOrdï¼è¯¥æ¹æ³åªæ¯å转任ä½é¡ºåºã对äºä»»ä½å®ç°äºOrdçç±»åTï¼std::cmp::Reverse<T>ä¹å®ç°äºOrdï¼ä½é¡ºåºæ¯ç¸åçãä¾å¦ï¼æä¸éä»é«å°ä½å¯¹æä»¬çåºé´è¿è¡æåºå¾ç®åï¼
use std::cmp::Reverse;
intervals.sort_by_key(|i| Reverse(i.lower));
2
# Index å IndexMut
ä½ å¯ä»¥éè¿å®ç°std::ops::Indexåstd::ops::IndexMutç¹æ§ï¼æ¥æå®åa[i]è¿æ ·çç´¢å¼è¡¨è¾¾å¼å¨ä½ çç±»åä¸çè¡ä¸ºãæ°ç»ç´æ¥æ¯æ[]è¿ç®ç¬¦ï¼ä½å¨å
¶ä»ä»»ä½ç±»åä¸ï¼è¡¨è¾¾å¼a[i]é常æ¯*a.index(i)çç®åå½¢å¼ï¼å
¶ä¸indexæ¯std::ops::Indexç¹æ§çä¸ä¸ªæ¹æ³ãä¸è¿ï¼å¦æè¯¥è¡¨è¾¾å¼ç¨äºèµå¼æå¯ååç¨ï¼é£ä¹å®æ¯*a.index_mut(i)çç®åå½¢å¼ï¼è¿æ¯å¯¹std::ops::IndexMutç¹æ§æ¹æ³çè°ç¨ã
以䏿¯è¿äºç¹æ§çå®ä¹ï¼
trait Index<Idx> {
type Output: ?Sized;
fn index(&self, index: Idx) -> &Self::Output;
}
trait IndexMut<Idx> : Index<Idx> {
fn index_mut(&mut self, index: Idx) -> &mut Self::Output;
}
2
3
4
5
6
7
8
注æï¼è¿äºç¹æ§å°ç´¢å¼è¡¨è¾¾å¼çç±»åä½ä¸ºåæ°ãä½ å¯ä»¥ç¨å个usize对åçè¿è¡ç´¢å¼ï¼ä»¥å¼ç¨å个å
ç´ ï¼å 为åçå®ç°äºIndex<usize>ãä½ä½ ä¹å¯ä»¥ç¨a[i..j]è¿æ ·ç表达å¼å¼ç¨ä¸ä¸ªååçï¼å 为å®ä»¬è¿å®ç°äºIndex<Range<usize>>ãè¿ä¸ªè¡¨è¾¾å¼æ¯ä¸é¢ä»£ç çç®åå½¢å¼ï¼
*a.index(std::ops::Range { start: i, end: j })
RustçHashMapåBTreeMapéåå
è®¸ä½ ä½¿ç¨ä»»ä½å¯å叿æåºç±»åä½ä¸ºç´¢å¼ã以ä¸ä»£ç è½å¤æ£å¸¸å·¥ä½ï¼æ¯å 为HashMap<&str, i32>å®ç°äºIndex<&str>ï¼
use std::collections::HashMap;
let mut m = HashMap::new();
m.insert("å", 10);
m.insert("ç¾", 100);
m.insert("å", 1000);
m.insert("ä¸", 10000);
m.insert("å", 100000000);
assert_eq!(m["å"], 10);
assert_eq!(m["å"], 1000);
2
3
4
5
6
7
8
9
10
11
è¿äºç´¢å¼è¡¨è¾¾å¼çæäºï¼
use std::ops::Index;
assert_eq!(*m.index("å"), 10);
assert_eq!(*m.index("å"), 1000);
2
3
4
Indexç¹æ§çå
³èç±»åOutputæå®äºç´¢å¼è¡¨è¾¾å¼äº§ççç±»åï¼å¯¹äºæä»¬çHashMapï¼Indexå®ç°çOutputç±»åæ¯i32ã
IndexMutç¹æ§éè¿index_mutæ¹æ³æ©å±äºIndexï¼è¯¥æ¹æ³æ¥å对selfçå¯åå¼ç¨ï¼å¹¶è¿å对Outputå¼çå¯åå¼ç¨ãå½ç´¢å¼è¡¨è¾¾å¼åºç°å¨éè¦å¯åå¼ç¨çä¸ä¸æä¸æ¶ï¼Rustä¼èªå¨éæ©index_mutãä¾å¦ï¼å设æä»¬ç¼å以ä¸ä»£ç ï¼
let mut desserts =
vec!["Howalon".to_string(), "Soan papdi".to_string()];
desserts[0].push_str(" (fictional)");
desserts[1].push_str(" (real)");
2
3
4
å 为push_stræ¹æ³ä½ç¨äº&mut selfï¼æä»¥æå两è¡ä»£ç çæäºï¼
use std::ops::IndexMut;
(*desserts.index_mut(0)).push_str(" (fictional)");
(*desserts.index_mut(1)).push_str(" (real)");
2
3
4
IndexMutçä¸ä¸ªè®¾è®¡éå¶æ¯ï¼å®å¿
é¡»è¿å对æä¸ªå¼çå¯åå¼ç¨ãè¿å°±æ¯ä¸ºä»ä¹ä½ ä¸è½ä½¿ç¨åm["å"] = 10;è¿æ ·ç表达å¼åHashMap m䏿å
¥å¼ï¼åå¸è¡¨éè¦å
为"å"å建ä¸ä¸ªæ¡ç®ï¼å¹¶èµäºæä¸ªé»è®¤å¼ï¼ç¶åè¿å对该å¼çå¯åå¼ç¨ãä½å¹¶éææç±»å齿å»ä»·çé»è®¤å¼ï¼æäºç±»åçé»è®¤å¼ä¸¢å¼æ¶å¯è½ä»£ä»·å¾é«ï¼ä»
ä»
为äºå¨èµå¼æ¶ç«å³ä¸¢å¼èåå»ºè¿æ ·ä¸ä¸ªå¼æ¯ä¸ç§æµªè´¹ãï¼å¨è¯è¨çåç»çæ¬ä¸ï¼æè®¡å对æ¤è¿è¡æ¹è¿ãï¼
ç´¢å¼æå¸¸è§çç¨éæ¯ç¨äºéåãä¾å¦ï¼å设æä»¬æ£å¨å¤çä½å¾å¾åï¼å°±å第2ç« ä¸ç»å¶æ¼å¾·å¸æ´ç¹éåæ¶å建çå¾å飿 ·ãåæ³ä¸ä¸ï¼æä»¬çç¨åºä¸æè¿æ ·ç代ç ï¼
pixels[row * bounds.0 + column] =...;
妿æä¸ä¸ªImage<u8>ç±»åï¼å®çè¡ä¸ºåäºç»´æ°ç»ï¼è®©æä»¬å¨è®¿é®åç´ æ¶æ éååºææçç®æ¯è¿ç®ï¼é£å°±æ´å¥½äºï¼
image[row][column] =...;
è¦å®ç°è¿ä¸ç¹ï¼æä»¬éè¦å£°æä¸ä¸ªç»æä½ï¼
struct Image<P> {
width: usize,
pixels: Vec<P>,
}
impl<P: Default + Copy> Image<P> {
/// å建ä¸ä¸ªç»å®å¤§å°çæ°å¾åã
fn new(width: usize, height: usize) -> Image<P> {
Image {
width,
pixels: vec![P::default(); width * height],
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
以䏿¯ç¬¦åè¦æ±çIndexåIndexMutå®ç°ï¼
impl<P> std::ops::Index<usize> for Image<P> {
type Output = [P];
fn index(&self, row: usize) -> &[P] {
let start = row * self.width;
&self.pixels[start..start + self.width]
}
}
impl<P> std::ops::IndexMut<usize> for Image<P> {
fn index_mut(&mut self, row: usize) -> &mut [P] {
let start = row * self.width;
&mut self.pixels[start..start + self.width]
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
å½ä½ 对Imageè¿è¡ç´¢å¼æ¶ï¼ä¼å¾å°ä¸ä¸ªåç´ åçï¼å¯¹åçåè¿è¡ç´¢å¼å°±è½å¾å°å个åç´ ã
注æï¼å½æä»¬ç¼åimage[row][column]æ¶ï¼å¦ærowè¶
åºèå´ï¼æä»¬ç.index()æ¹æ³ä¼å°è¯å¯¹self.pixelsè¿è¡è¶çç´¢å¼ï¼ä»è触åpanicãè¿æ¯IndexåIndexMutå®ç°åºæçè¡ä¸ºï¼è¶ç访é®ä¼è¢«æ£æµå°å¹¶å¯¼è´panicï¼è¿ä¸å¯¹æ°ç»ãåçæåéè¿è¡è¶çç´¢å¼çæ
åµç¸åã
# å ¶ä»è¿ç®ç¬¦
å¹¶éææè¿ç®ç¬¦å¨Rustä¸é½è½è¢«éè½½ãæªè³Rust 1.50ï¼éè¯¯æ£æ¥è¿ç®ç¬¦?ä»
éç¨äºResultåOptionå¼ï¼ä¸è¿ç®åä¹å¨åªåå°å
¶æ©å±å°ç¨æ·èªå®ä¹ç±»åãåæ ·ï¼é»è¾è¿ç®ç¬¦&&å||ä»
éç¨äºå¸å°å¼ã..å..=è¿ç®ç¬¦æ»æ¯å建ä¸ä¸ªè¡¨ç¤ºèå´è¾¹ççç»æä½ï¼&è¿ç®ç¬¦æ»æ¯åç¨å¼ç¨ï¼=è¿ç®ç¬¦æ»æ¯ç§»å¨æå¤å¶å¼ãå®ä»¬é½ä¸è½è¢«éè½½ã
è§£å¼ç¨è¿ç®ç¬¦*valï¼ä»¥åç¨äºè®¿é®å段åè°ç¨æ¹æ³çç¹è¿ç®ç¬¦ï¼å¦val.fieldåval.method()ï¼ï¼å¯ä»¥ä½¿ç¨DerefåDerefMutç¹æ§è¿è¡éè½½ï¼æä»¬å°å¨ä¸ä¸ç« ä»ç»è¿ä¸¤ä¸ªç¹æ§ãï¼æä»¬å¨è¿é没æä»ç»å®ä»¬ï¼æ¯å 为è¿äºç¹æ§çä½ç¨ä¸æ¢æ¯éè½½å 个è¿ç®ç¬¦ãï¼
Rust䏿¯æéè½½å½æ°è°ç¨è¿ç®ç¬¦f(x)ãç¸åï¼å½ä½ éè¦ä¸ä¸ªå¯è°ç¨ç弿¶ï¼é常åªéç¼åä¸ä¸ªéå
ãæä»¬å°å¨ç¬¬14ç« è§£éè¿æ¯å¦ä½å·¥ä½çï¼å¹¶ä»ç»FnãFnMutåFnOnceè¿äºç¹æ®ç¹æ§ã
Lispç¨åºåä¼å¾é«å ´ï¼è¡¨è¾¾å¼
<i32 as Add>::addæ¯i32ç±»åä¸ç+è¿ç®ç¬¦ï¼è¢«æè·ä¸ºä¸ä¸ªå½æ°å¼ã