第11ç« ç¹æ§ä¸æ³å
# 第11ç« ç¹æ§ä¸æ³å
è®¡ç®æºç§å¦å®¶å¾å¾è½å¤å¤çéç»ä¸çç»æââæ åµ1ãæ åµ2ãæ åµ3çï¼èæ°å¦å®¶åå¾åäºå¯»æ¾ä¸ä¸ªç»ä¸çå ¬çæ¥æ¯é æ´ä¸ªç³»ç»ã ââå纳德·å åªç¹ï¼Donald Knuthï¼
ç¼ç¨é¢åçä¸ä¸ªé大åç°æ¯ï¼ç¼åè½å¤å¤çå¤ç§ä¸åç±»åå¼çä»£ç æ¯å¯è¡çï¼çè³è¿äºç±»åå¨ç¼åä»£ç æ¶è¿æªè¢«åæåºæ¥ã以䏿¯ä¸¤ä¸ªä¾åï¼
Vec<T>æ¯æ³åçï¼ä½ å¯ä»¥å建任ä½ç±»åå¼çåéï¼å æ¬å¨ä½ çç¨åºä¸å®ä¹çãVecçä½è 仿ªé¢æå°çç±»åã- 许å¤ç±»å齿
.write()æ¹æ³ï¼å æ¬FileåTcpStreamãä½ ç代ç å¯ä»¥éè¿å¼ç¨è·åä»»ä½å®ç°äºåå ¥åè½çç±»åï¼å¹¶åå ¶åéæ°æ®ï¼èæ éå ³å¿å®å ·ä½æ¯åªç§ç±»åã以åï¼å¦ææäººæ·»å äºä¸ç§æ°çå¯åå ¥ç±»åï¼ä½ ç代ç ä¹è½æ¯æã
å½ç¶ï¼è¿ç§è½å对äºRustæ¥è¯´å¹¶éé¦åãå®è¢«ç§°ä¸ºå¤ææ§ï¼polymorphismï¼ï¼æ¯20ä¸çºª70年代çé¨çç¼ç¨è¯è¨æ°ææ¯ï¼å¦ä»å·²å¹¿æ³åºç¨ãRustéè¿ä¸¤ä¸ªç¸å ³ç¹æ§æ¥æ¯æå¤ææ§ï¼ç¹æ§ï¼traitsï¼åæ³åï¼genericsï¼ã许å¤ç¨åºå对è¿äºæ¦å¿µå¹¶ä¸éçï¼ä½Rustä»Haskellçç±»åç±»ï¼typeclassesï¼ä¸æ±²åçµæï¼éç¨äºå ¨æ°çå®ç°æ¹å¼ã
ç¹æ§æ¯Rust对æ¥å£ï¼interfacesï¼ææ½è±¡åºç±»ï¼abstract base classesï¼çå®ç°ãä¹ä¸çï¼å®ä»¬ä¸JavaæC#ä¸çæ¥å£å¾ç¸ä¼¼ãç¨äºåèåå
¥çç¹æ§å为std::io::Writeï¼å
¶å¨æ ååºä¸çå®ä¹å¦ä¸ï¼
trait Write {
fn write(&mut self, buf: &[u8]) -> Result<usize>;
fn flush(&mut self) -> Result<()>;
fn write_all(&mut self, buf: &[u8]) -> Result<()> { ... }
...
}
2
3
4
5
6
è¿ä¸ªç¹æ§æä¾äºå¤ä¸ªæ¹æ³ï¼æä»¬è¿éåªå±ç¤ºäºåä¸ä¸ªã
æ åç±»åFileåTcpStreamé½å®ç°äºstd::io::Writeï¼Vec<u8>乿¯å¦æ¤ãè¿ä¸ç§ç±»å齿ä¾äºå为.write()ã.flush()ççæ¹æ³ãä¸å
³å¿åå
¥ç±»åç代ç å¯ä»¥è¿æ ·ç¼åï¼
use std::io::Write;
fn say_hello(out: &mut dyn Write) -> std::io::Result<()> {
out.write_all(b"hello world\n")?;
out.flush()
}
2
3
4
5
6
outçç±»åæ¯&mut dyn Writeï¼æææ¯ â对任ä½å®ç°äºWriteç¹æ§çå¼çå¯åå¼ç¨âãæä»¬å¯ä»¥å°ä»»ä½è¿æ ·çå¼çå¯åå¼ç¨ä¼ éç»say_helloï¼
use std::fs::File;
let mut local_file = File::create("hello.txt")?;
say_hello(&mut local_file)?; // å¯è¡
let mut bytes = vec![];
say_hello(&mut bytes)?; // åæ ·å¯è¡
assert_eq!(bytes, b"hello world\n");
2
3
4
5
6
7
æ¬ç« å°é¦å
ä»ç»ç¹æ§çä½¿ç¨æ¹æ³ãå·¥ä½åç以åå¦ä½å®ä¹èªå·±çç¹æ§ãä½ç¹æ§çåè½è¿ä¸æ¢æä»¬ç®åæå°çè¿äºãæä»¬å°ç¨å®ä»¬ä¸ºç°æç±»åï¼çè³æ¯åstråboolè¿æ ·çå
ç½®ç±»åæ·»å æ©å±æ¹æ³ãæä»¬å°è§£é为ä»ä¹ä¸ºç±»åæ·»å ç¹æ§ä¸ä¼å¢å é¢å¤çå
åå¼éï¼ä»¥åå¦ä½å¨ä¸äº§çèæ¹æ³è°ç¨å¼éçæ
åµä¸ä½¿ç¨ç¹æ§ãæä»¬è¿ä¼äºè§£å°ï¼å
ç½®ç¹æ§æ¯Rust为è¿ç®ç¬¦éè½½åå
¶ä»åè½æä¾çè¯è¨é©åãæ¤å¤ï¼æä»¬å°ä»ç»Selfç±»åãå
³è彿°åå
³èç±»åï¼è¿ä¸ä¸ªä»Haskellåé´çç¹æ§ï¼ä¼é
å°è§£å³äºå
¶ä»è¯è¨éè¦éè¿åéæ¹æ³æè½è§£å³çé®é¢ã
æ³åæ¯Rustä¸å¦ä¸ç§å¤ææ§çå®ç°æ¹å¼ãä¸C++模æ¿ç±»ä¼¼ï¼æ³å彿°æç±»åå¯ä»¥ç¨äºå¤ç§ä¸åç±»åçå¼ï¼
/// ç»å®ä¸¤ä¸ªå¼ï¼éæ©è¾å°çé£ä¸ªã
fn min<T: Ord>(value1: T, value2: T) -> T {
if value1 <= value2 {
value1
} else {
value2
}
}
2
3
4
5
6
7
8
彿°ä¸ç<T: Ord>表示minå¯ä»¥ç¨äºä»»ä½å®ç°äºOrdç¹æ§çç±»åTçåæ°ï¼å³ä»»ä½æåºç±»åãè¿æ ·çè¦æ±è¢«ç§°ä¸ºçº¦æï¼boundï¼ï¼å 为å®éå¶äºTå¯è½çç±»åãç¼è¯å¨ä¼ä¸ºä½ å®é
使ç¨çæ¯ä¸ªç±»åTçæå®å¶çæºå¨ä»£ç ã
æ³ååç¹æ§å¯åç¸å
³ï¼æ³å彿°ä½¿ç¨çº¦æä¸çç¹æ§æ¥æç¡®å®ä»¬å¯ä»¥åºç¨äºåªäºç±»åçåæ°ãå æ¤ï¼æä»¬è¿å°è®¨è®º&mut dyn Writeå<T: Write>çå¼åï¼ä»¥åå¦ä½å¨è¿ä¸¤ç§ä½¿ç¨ç¹æ§çæ¹å¼ä¸ååºéæ©ã
# 使ç¨ç¹æ§
ç¹æ§æ¯ä¸ç§ä»»ä½ç»å®ç±»åå¯è½æ¯æä¹å¯è½ä¸æ¯æçåè½ãé常æ åµä¸ï¼ç¹æ§ä»£è¡¨ä¸ç§è½åï¼å³æä¸ªç±»åè½åçäºæ ã
- å®ç°äº
std::io::Writeçç±»åçå¼å¯ä»¥è¾åºåèã - å®ç°äº
std::iter::Iteratorçç±»åçå¼å¯ä»¥çæä¸ç³»åå¼ã - å®ç°äº
std::clone::Cloneçç±»åçå¼å¯ä»¥å¨å åä¸å建èªèº«çå éã - å®ç°äº
std::fmt::Debugçç±»åçå¼å¯ä»¥ä½¿ç¨println!()å{:?}æ ¼å¼å说æç¬¦è¿è¡æå°ã
è¿åä¸ªç¹æ§é½æ¯Rustæ ååºçä¸é¨åï¼è®¸å¤æ åç±»åé½å®ç°äºå®ä»¬ãä¾å¦ï¼
std::fs::Fileå®ç°äºWriteç¹æ§ï¼å®å°åèåå ¥æ¬å°æä»¶ï¼std::net::TcpStreamå®ç°äºè¯¥ç¹æ§ï¼ç¨äºåç½ç»è¿æ¥åå ¥æ°æ®ï¼Vec<u8>åæ ·å®ç°äºWriteç¹æ§ï¼æ¯æ¬¡å¯¹åèåéè°ç¨.write()é½ä¼å¨åéæ«å°¾è¿½å ä¸äºæ°æ®ãRange<i32>ï¼0..10çç±»åï¼å®ç°äºIteratorç¹æ§ï¼ä¸äºä¸åçãåå¸è¡¨çç¸å ³çè¿ä»£å¨ç±»åä¹å®ç°äºè¯¥ç¹æ§ã- 大夿°æ ååºç±»åé½å®ç°äº
Cloneç¹æ§ã主è¦çä¾å¤æ¯åTcpStreamè¿æ ·çç±»åï¼å®ä»¬ä¸ä» ä» ä»£è¡¨å åä¸çæ°æ®ã - åæ ·ï¼å¤§å¤æ°æ ååºç±»å齿¯æ
Debugç¹æ§ã
å ³äºç¹æ§æ¹æ³æä¸ä¸ªä¸å¯»å¸¸çè§åï¼ç¹æ§æ¬èº«å¿ é¡»å¨ä½ç¨åå ï¼å¦åå ¶æææ¹æ³é½ä¸å¯è§ï¼
let mut buf: Vec<u8> = vec![];
buf.write_all(b"hello")?; // éè¯¯ï¼æ²¡æå为`write_all`çæ¹æ³
2
å¨è¿ç§æ
åµä¸ï¼ç¼è¯å¨ä¼ç»åºä¸æ¡å好çéè¯¯æ¶æ¯ï¼å»ºè®®æ·»å use std::io::Write;ï¼è¿æ ·ç¡®å®å¯ä»¥è§£å³é®é¢ï¼
use std::io::Write;
let mut buf: Vec<u8> = vec![];
buf.write_all(b"hello")?; // æ£å¸¸
2
3
4
Rustæè¿ä¸ªè§åæ¯å ä¸ºï¼æ£å¦æä»¬å°å¨æ¬ç« åé¢çå°çï¼ä½ å¯ä»¥ä½¿ç¨ç¹æ§ä¸ºä»»ä½ç±»åæ·»å æ°æ¹æ³ï¼çè³æ¯åu32åstrè¿æ ·çæ ååºç±»åãç¬¬ä¸æ¹åºä¹å¯ä»¥è¿æ ·åãæ¾ç¶ï¼è¿å¯è½ä¼å¯¼è´å½åå²çªï¼ä½ç±äºRustè¦æ±ä½ 导å
¥è®¡å使ç¨çç¹æ§ï¼åºå°±å¯ä»¥èªç±å©ç¨è¿ä¸ªå¼ºå¤§çåè½ãè¦åçå²çªï¼ä½ å¿
须导å
¥ä¸¤ä¸ªä¸ºåä¸ç±»åæ·»å ååæ¹æ³çç¹æ§ï¼å¨å®è·µä¸è¿ç§æ
åµå¾å°è§ãï¼å¦æä½ ç¡®å®éå°äºå²çªï¼å¯ä»¥ä½¿ç¨æ¬ç« åé¢ä»ç»çå®å
¨é宿¹æ³è¯æ³æ¥æç¡®æå®ä½ æ³è¦çå
容ãï¼
CloneåIteratoræ¹æ³ä¸éè¦ä»»ä½ç¹æ®å¯¼å
¥å°±è½ä½¿ç¨ï¼æ¯å 为å®ä»¬é»è®¤å§ç»å¨ä½ç¨åå
ï¼å®ä»¬æ¯æ åå置模åï¼standard preludeï¼çä¸é¨åï¼Rustä¼èªå¨å°è¿äºå称导å
¥å°æ¯ä¸ªæ¨¡åä¸ãå®é
ä¸ï¼å置模åä¸»è¦æ¯ç²¾å¿æéçä¸äºç¹æ§ãæä»¬å°å¨ç¬¬13ç« ä»ç»å
¶ä¸ç许å¤ç¹æ§ã
C++åC#ç¨åºåå¯è½å·²ç»æ³¨æå°ï¼ç¹æ§æ¹æ³ç±»ä¼¼äºèæ¹æ³ï¼virtual methodsï¼ãä¸è¿ï¼ä¸é¢è¿æ ·çè°ç¨é度å¾å¿«ï¼åå
¶ä»ä»»ä½æ¹æ³è°ç¨ä¸æ ·å¿«ãç®åæ¥è¯´ï¼è¿éä¸åå¨å¤ææ§ãæ¾ç¶bufæ¯ä¸ä¸ªåéï¼ä¸æ¯æä»¶æç½ç»è¿æ¥ãç¼è¯å¨å¯ä»¥ç´æ¥ååºå¯¹Vec<u8>::write()çç®åè°ç¨ï¼çè³å¯ä»¥å°è¯¥æ¹æ³å
èãï¼C++åC#é常ä¹ä¼è¿æ ·åï¼å°½ç®¡ææ¶ç±äºåå¨åç±»åçå¯è½æ§èæ æ³å
èãï¼åªæéè¿&mut dyn Writeè¿è¡çè°ç¨æä¼äº§ç卿è°åº¦ï¼ä¹ç§°ä¸ºèæ¹æ³è°ç¨ï¼çå¼éï¼dynå
³é®åå¨ç±»åä¸è¡¨æäºè¿ä¸ç¹ãdyn Writeè¢«ç§°ä¸ºç¹æ§å¯¹è±¡ï¼trait objectï¼ï¼å¨æ¥ä¸æ¥çé¨åï¼æä»¬å°ç ç©¶ç¹æ§å¯¹è±¡çææ¯ç»èï¼ä»¥åå®ä»¬ä¸æ³å彿°çæ¯è¾ã
# ç¹æ§å¯¹è±¡
å¨Rustä¸ï¼ä½¿ç¨ç¹æ§ç¼åå¤æä»£ç æä¸¤ç§æ¹å¼ï¼ç¹æ§å¯¹è±¡åæ³åãæä»¬å ä»ç»ç¹æ§å¯¹è±¡ï¼ä¸ä¸èå讨论æ³åã
Rustä¸å
许å®ä¹ç±»å为dyn Writeçåéï¼
use std::io::Write;
let mut buf: Vec<u8> = vec![];
let writer: dyn Write = buf; // é误ï¼`Write`ç大å°ä¸åºå®
2
3
4
åéç大å°å¿
é¡»å¨ç¼è¯æ¶ç¡®å®ï¼èå®ç°Writeç¹æ§çç±»å大å°å¯è½åä¸ç¸åã
å¦æä½ æ¥èªC#æJavaï¼è¿å¯è½ä¼è®©ä½ æå°æè®¶ï¼ä½åå å¾ç®åãå¨Javaä¸ï¼ç±»å为OutputStreamï¼ç±»ä¼¼äºRustä¸std::io::WriteçJavaæ 忥å£ï¼çå鿝坹任ä½å®ç°äºOutputStreamç对象çå¼ç¨ãå¨Javaä¸ï¼å®æ¯ä¸ä¸ªå¼ç¨è¿ä¸ç¹ä¸è¨èå»ãC#å大夿°å
¶ä»è¯è¨ä¸çæ¥å£ä¹æ¯å¦æ¤ã
å¨Rust䏿们æ³è¦çæ¯åæ ·çææï¼ä½å¨Rustä¸ï¼å¼ç¨æ¯æ¾å¼çï¼
let mut buf: Vec<u8> = vec![];
let writer: &mut dyn Write = &mut buf; // æ£å¸¸
2
å¯¹ç¹æ§ç±»åçå¼ç¨ï¼å¦writerï¼è¢«ç§°ä¸ºç¹æ§å¯¹è±¡ãä¸å
¶ä»ä»»ä½å¼ç¨ä¸æ ·ï¼ç¹æ§å¯¹è±¡æåæä¸ªå¼ï¼æèªå·±ççå½å¨æï¼å¹¶ä¸å¯ä»¥æ¯å¯åçæå
±äº«çã
ç¹æ§å¯¹è±¡çä¸åä¹å¤å¨äºï¼Rusté常å¨ç¼è¯æ¶ä¸ç¥é被å¼ç¨å¼çå
·ä½ç±»åãå æ¤ï¼ç¹æ§å¯¹è±¡å
å«ä¸äºå
³äºè¢«å¼ç¨å¼ç±»åçé¢å¤ä¿¡æ¯ãè¿å®å
¨æ¯Rustå¨å
é¨ä½¿ç¨çï¼å½ä½ è°ç¨writer.write(data)æ¶ï¼Rustéè¦è¿äºç±»åä¿¡æ¯ï¼ä»¥ä¾¿æ ¹æ®*writerçå®é
ç±»å卿è°ç¨æ£ç¡®çwriteæ¹æ³ãä½ ä¸è½ç´æ¥æ¥è¯¢è¿äºç±»åä¿¡æ¯ï¼å¹¶ä¸Rust䏿¯æä»ç¹æ§å¯¹è±¡&mut dyn Writeåä¸è½¬å为åVec<u8>è¿æ ·çå
·ä½ç±»åã
# ç¹æ§å¯¹è±¡çå¸å±
å¨å
åä¸ï¼ç¹æ§å¯¹è±¡æ¯ä¸ä¸ªèæéï¼fat pointerï¼ï¼ç±ä¸ä¸ªæåå¼çæéåä¸ä¸ªæå表示该å¼ç±»åç表çæéç»æãå æ¤ï¼æ¯ä¸ªç¹æ§å¯¹è±¡å ç¨ä¸¤ä¸ªæºå¨åé¿ï¼å¦å¾11-1æç¤ºã
å¾11-1 å
åä¸çç¹æ§å¯¹è±¡
C++乿è¿ç§è¿è¡æ¶ç±»åä¿¡æ¯ï¼ç§°ä¸ºè表ï¼virtual tableï¼ævtableãå¨Rustä¸ï¼åC++䏿 ·ï¼vtableå¨ç¼è¯æ¶çæä¸æ¬¡ï¼å¹¶ç±ç¸åç±»åçææå¯¹è±¡å ±äº«ãå¾11-1ä¸é¢è²è¾æ·±çé¨åï¼å æ¬vtableï¼é½æ¯Rustçç§æå®ç°ç»èãåæ ·ï¼è¿äºä¸æ¯ä½ å¯ä»¥ç´æ¥è®¿é®çåæ®µåæ°æ®ç»æãç¸åï¼å½ä½ è°ç¨ç¹æ§å¯¹è±¡çæ¹æ³æ¶ï¼è¯è¨ä¼èªå¨ä½¿ç¨vtableæ¥ç¡®å®è°ç¨åªä¸ªå®ç°ã
ç»éªä¸°å¯çC++ç¨åºå伿³¨æå°ï¼RuståC++å¨å å使ç¨ä¸ç¥æä¸åãå¨C++ä¸ï¼vtableæéï¼vptrï¼ä½ä¸ºç»æä½çä¸é¨ååå¨ãèRust使ç¨èæéãç»æä½æ¬èº«åªå å«å ¶å段ã
éè¿è¿ç§æ¹å¼ï¼ä¸ä¸ªç»æä½å¯ä»¥å®ç°å åä¸ªç¹æ§ï¼èæ éå
å«å å个vptrãå³ä½¿åi32è¿æ ·å°å°æ æ³å®¹çº³vptrçç±»åï¼ä¹å¯ä»¥å®ç°ç¹æ§ã
Rustå¨éè¦æ¶ä¼èªå¨å°æ®éå¼ç¨è½¬æ¢ä¸ºç¹æ§å¯¹è±¡ãè¿å°±æ¯ä¸ºä»ä¹å¨è¿ä¸ªä¾å䏿们è½å¤å°&mut local_fileä¼ éç»say_helloï¼
let mut local_file = File::create("hello.txt")?;
say_hello(&mut local_file)?;
2
&mut local_fileçç±»åæ¯&mut Fileï¼èsay_helloçåæ°ç±»åæ¯&mut dyn Writeãç±äºFileæ¯ä¸ç§å¯åå
¥ç±»åï¼Rustå
è®¸è¿æ ·åï¼èªå¨å°æ®éå¼ç¨è½¬æ¢ä¸ºç¹æ§å¯¹è±¡ã
åæ ·ï¼Rustä¼å¾èªç¶å°å°Box<File>转æ¢ä¸ºBox<dyn Write>ï¼è¿æ¯ä¸ä¸ªå¨å 䏿¥æå¯åå
¥å¯¹è±¡çç±»åï¼
let w: Box<dyn Write> = Box::new(local_file);
Box<dyn Write>å&mut dyn Write䏿 ·ï¼æ¯ä¸ä¸ªèæéï¼å®å
å«åå
¥å¯¹è±¡æ¬èº«çå°ååvtableçå°åãå
¶ä»æéç±»åï¼å¦Rc<dyn Write>ï¼ä¹æ¯å¦æ¤ã
è¿ç§è½¬æ¢æ¯åå»ºç¹æ§å¯¹è±¡çå¯ä¸æ¹å¼ãç¼è¯å¨å®é
åçäºæ
é常ç®åãå¨è¿è¡è½¬æ¢æ¶ï¼Rustç¥é被å¼ç¨å¼ççå®ç±»åï¼å¨è¿ä¸ªä¾å䏿¯Fileï¼ï¼æä»¥å®åªæ¯æ·»å éå½çvtableå°åï¼å°æ®éæé转æ¢ä¸ºèæéã
# æ³å彿°åç±»ååæ°
卿¬ç« å¼å¤´ï¼æä»¬å±ç¤ºäºä¸ä¸ªsay_hello()彿°ï¼å®æ¥åä¸ä¸ªç¹å¾å¯¹è±¡ä½ä¸ºåæ°ãç°å¨ï¼è®©æä»¬å°è¿ä¸ªå½æ°éå为ä¸ä¸ªæ³å彿°ï¼
fn say_hello<W: Write>(out: &mut W) -> std::io::Result<()> {
out.write_all(b"hello world\n")?;
out.flush()
}
2
3
4
åªæç±»åç¾ååçäºååï¼
fn say_hello(out: &mut dyn Write) // æ®é彿°
fn say_hello<W: Write>(out: &mut W) // æ³å彿°
2
<W: Write>è¿é¨åè®©å½æ°æä¸ºäºæ³å彿°ãè¿æ¯ä¸ä¸ªç±»ååæ°ï¼æå³çå¨è¿ä¸ªå½æ°ä½ä¸ï¼W代表æç§å®ç°äºWriteç¹å¾çç±»åãæç
§æ¯ä¾ï¼ç±»ååæ°é常ç¨å个大ååæ¯è¡¨ç¤ºã
W代表åªç§ç±»ååå³äºæ³å彿°çä½¿ç¨æ¹å¼ï¼
say_hello(&mut local_file)?; | // è°ç¨say_hello::<File> |
|---|---|
say_hello(&mut bytes)?; | // è°ç¨say_hello::<Vec<u8>> |
å½ä½ å°&mut local_fileä¼ éç»æ³åçsay_hello()彿°æ¶ï¼ä½ å®é
ä¸è°ç¨çæ¯say_hello::<File>()ãRustä¼ä¸ºè¿ä¸ªå½æ°çææºå¨ç ï¼è°ç¨File::write_all()åFile::flush()ãå½ä½ ä¼ é&mut bytesæ¶ï¼ä½ è°ç¨çæ¯say_hello::<Vec<u8>>()ãRustä¼ä¸ºè¿ä¸ªçæ¬ç彿°çæåç¬çæºå¨ç ï¼è°ç¨ç¸åºçVec<u8>æ¹æ³ãå¨è¿ä¸¤ç§æ
åµä¸ï¼Rusté½ä¼æ ¹æ®åæ°çç±»åæ¨æåºç±»åWãè¿ä¸ªè¿ç¨è¢«ç§°ä¸ºåæåï¼ç¼è¯å¨ä¼èªå¨å¤çè¿ä¸åã
ä½ ä¹å¯ä»¥æç¡®ååºç±»ååæ°ï¼say_hello::<File>(&mut local_file)?;ã
è¿ç§æ
åµå¾å°æå¿
è¦ï¼å 为Rusté常å¯ä»¥éè¿æ¥çåæ°æ¥æ¨æç±»ååæ°ãè¿éï¼say_helloæ³å彿°ææä¸ä¸ª&mut Wç±»åçåæ°ï¼èæä»¬ä¼ éç»å®çæ¯ä¸ä¸ª&mut Fileï¼æä»¥Rustæ¨æåºW = Fileã
å¦æä½ è°ç¨çæ³å彿°æ²¡æä»»ä½åæ°è½æä¾æç¨ç线索ï¼ä½ å¯è½å°±å¾æç¡®ååºç±»ååæ°ï¼
// è°ç¨ä¸ä¸ªä¸å¸¦åæ°çæ³åæ¹æ³collect<C>()
let v1 = (0..1000).collect(); // éè¯¯ï¼æ æ³æ¨æç±»å
let v2 = (0..1000).collect::<Vec<i32>>(); // æ£ç¡®
2
3
ææ¶ï¼æä»¬éè¦ç±»ååæ°å ·å¤å¤ç§è½åãä¾å¦ï¼å¦ææä»¬æ³æå°åºåéä¸åºç°é¢çæé«çåå个å¼ï¼é£ä¹è¿äºå¼å¿ é¡»æ¯å¯æå°çï¼
use std::fmt::Debug;
fn top_ten<T: Debug>(values: &Vec<T>) { ... }
2
ä½è¿è¿ä¸å¤ãæä»¬è¦å¦ä½ç¡®å®åªäºå¼æ¯åºç°é¢çæé«çå¢ï¼é常çåæ³æ¯å°è¿äºå¼ä½ä¸ºåå¸è¡¨ä¸çé®ãè¿æå³çè¿äºå¼éè¦æ¯æHashåEqæä½ãTç约æå¿
须忶å
å«è¿äºä»¥åDebugãè¿éçè¯æ³ä½¿ç¨+符å·ï¼
use std::hash::Hash;
use std::fmt::Debug;
fn top_ten<T: Debug + Hash + Eq>(values: &Vec<T>) { ... }
2
3
æäºç±»åå®ç°äºDebugï¼æäºå®ç°äºHashï¼æäºæ¯æEqï¼è¿æå°æ°ç±»åï¼æ¯å¦u32åStringï¼å®ç°äºè¿ä¸ç§ï¼å¦å¾11 - 2æç¤ºã
å¾11 - 2. ç¹å¾ä½ä¸ºç±»åéå
ç±»ååæ°ä¹å¯è½å®å
¨æ²¡æçº¦æï¼ä½å¦æä½ 没æä¸ºå®æå®ä»»ä½çº¦æï¼ä½ 对è¿ä¸ªå¼è½åçäºæ
就徿éãä½ å¯ä»¥ç§»å¨å®ï¼å¯ä»¥å°å®æ¾å
¥ä¸ä¸ªBoxæåéä¸ãå·®ä¸å¤å°±è¿äºäºã
æ³å彿°å¯ä»¥æå¤ä¸ªç±»ååæ°ï¼
/// 对ä¸ä¸ªå¤§åçååºæ°æ®éè¿è¡æ¥è¯¢ã
/// 请åé
<http://research.google.com/archive/mapreduce.html>ã
fn run_query<M: Mapper + Serialize, R: Reducer + Serialize>(
data: &DataSet, map: M, reduce: R
) -> Results {
...
}
2
3
4
5
6
7
æ£å¦è¿ä¸ªä¾åæç¤ºï¼çº¦æå¯è½ä¼åå¾å¾é¿ï¼è®©äººççå¾è´¹å²ãRustæä¾äºä¸ç§æ¿ä»£è¯æ³ï¼ä½¿ç¨whereå
³é®åï¼
fn run_query<M, R>(data: &DataSet, map: M, reduce: R) -> Results
where
M: Mapper + Serialize,
R: Reducer + Serialize
{
...
}
2
3
4
5
6
7
ç±»ååæ°MåRä»ç¶å¨åé¢å£°æï¼ä½çº¦æè¢«ç§»å°äºåç¬çè¡ä¸ãè¿ç§whereåå¥ä¹å
许ç¨äºæ³åç»æä½ãæä¸¾ãç±»åå«ååæ¹æ³ââå¨ä»»ä½å
许约æçå°æ¹é½å¯ä»¥ä½¿ç¨ã
å½ç¶ï¼é¤äºä½¿ç¨whereåå¥ï¼è¿æä¸ç§éæ©æ¯ä¿æç®åï¼æ¾å°ä¸ç§æ¹æ³ï¼å¨ç¼åç¨åºæ¶ä¸è¿åº¦ä½¿ç¨æ³åã
â彿°åæ°æ¥æ¶å¼ç¨âä»ç»äºçå½å¨æåæ°çè¯æ³ãä¸ä¸ªæ³å彿°å¯ä»¥åæ¶æçå½å¨æåæ°åç±»ååæ°ã
çå½å¨æåæ°æå¨åé¢ï¼
/// è¿å`candidates`ä¸ç¦»`target`ç¹æè¿çç¹çå¼ç¨ã
fn nearest<'t, 'c, P>(target: &'t P, candidates: &'c [P]) -> &'c P
where
P: MeasureDistance
{
...
}
2
3
4
5
6
7
è¿ä¸ªå½æ°æ¥åä¸¤ä¸ªåæ°ï¼targetåcandidatesãå®ä»¬é½æ¯å¼ç¨ï¼æä»¬ç»å®ä»¬ä¸åççå½å¨æ'tå'cï¼å¦âä¸åççå½å¨æåæ°âä¸æè®¨è®ºçï¼ãæ¤å¤ï¼è¿ä¸ªå½æ°å¯ä»¥å¤çä»»ä½å®ç°äºMeasureDistanceç¹å¾çç±»åPï¼æä»¥æä»¬å¯è½å¨ä¸ä¸ªç¨åºä¸å¯¹Point2då¼ä½¿ç¨å®ï¼å¨å¦ä¸ä¸ªç¨åºä¸å¯¹Point3då¼ä½¿ç¨å®ã
çå½å¨æå¯¹æºå¨ç 没æä»»ä½å½±åã使ç¨ç¸åç±»åPä½ä¸åçå½å¨æç两次对nearest()çè°ç¨ï¼ä¼è°ç¨ç¸åçå·²ç¼è¯å½æ°ãåªæä¸åçç±»åæä¼å¯¼è´Rustç¼è¯æ³å彿°çå¤ä¸ªå¯æ¬ã
å½ç¶ï¼å½æ°å¹¶ä¸æ¯Rustä¸å¯ä¸çæ³å代ç ï¼
- æä»¬å·²ç»å¨âæ³åç»æä½âåâæ³åæä¸¾âä¸ä»ç»è¿æ³åç±»åã
- å³ä½¿å®ä¹æ¹æ³çç±»å䏿¯æ³åçï¼åä¸ªæ¹æ³ä¹å¯ä»¥æ¯æ³åçï¼
impl PancakeStack {
fn push<T: Topping>(&mut self, goop: T) -> PancakeResult<()> {
goop.pour(&self);
self.absorb_topping(goop)
}
}
2
3
4
5
6
- ç±»åå«åä¹å¯ä»¥æ¯æ³åçï¼
type PancakeResult<T> = Result<T, PancakeError>;
- æä»¬å°å¨æ¬ç« åé¢ä»ç»æ³åç¹å¾ã
æ¬èä»ç»çææç¹æ§ââ约æãwhereåå¥ãçå½å¨æåæ°ççââé½å¯ä»¥ç¨äºæææ³å项ï¼èä¸ä»
ä»
æ¯å½æ°ã
# 该å¦ä½éæ©
使ç¨ç¹å¾å¯¹è±¡è¿æ¯æ³å代ç ï¼è¿ä¸ªéæ©æ¯è¾å¾®å¦ãç±äºè¿ä¸¤ä¸ªç¹æ§é½åºäºç¹å¾ï¼å®ä»¬æå¾å¤å ±åä¹å¤ã
æ¯å½ä½ éè¦å°ä¸åç±»åç弿¶éå¨ä¸èµ·æ¶ï¼ç¹å¾å¯¹è±¡å°±æ¯æ£ç¡®çéæ©ã仿æ¯ä¸è®²ï¼ä¹å¯ä»¥å建æ³åâæ²æâï¼
trait Vegetable {
...
}
struct Salad<V: Vegetable> {
veggies: Vec<V>
}
2
3
4
5
6
ç¶èï¼è¿æ¯ä¸ç§ç¸å½ä¸¥æ ¼çè®¾è®¡ãæ¯ä¸ä»½è¿æ ·çâæ²æâå®å
¨ç±åä¸ç±»åçè¬èç»æã䏿¯æ¯ä¸ªäººé½å欢è¿ç§ä¸è¥¿ãæ¬ä¹¦çä¸ä½ä½è
æ¾ç»è±14ç¾å
ä¹°äºä¸ä»½Salad<IcebergLettuce>ï¼è³ä»é½è¿æ²¡ç¼è¿æ¥ã
æä»¬ææ ·æè½ååºæ´å¥½çâæ²æâå¢ï¼ç±äºVegetableå¼ç大å°å¯è½åä¸ç¸åï¼æä»¬ä¸è½è®©Rustå建ä¸ä¸ªVec<dyn Vegetable>ï¼
struct Salad {
veggies: Vec<dyn Vegetable> // é误ï¼`dyn Vegetable`没æåºå®å¤§å°
}
2
3
ç¹å¾å¯¹è±¡å°±æ¯è§£å³æ¹æ¡ï¼
struct Salad {
veggies: Vec<Box<dyn Vegetable>>
}
2
3
æ¯ä¸ªBox<dyn Vegetable>å¯ä»¥åæ¾ä»»ä½ç±»åçè¬èï¼ä½Boxæ¬èº«æåºå®å¤§å°ââ两个æéââéååå¨å¨åéä¸ãé¤äºå¨é£ç©ä¸åºç°âçåâè¿ä¸ªä¸å¤ªæ°å½çæ¯å»ä¹å¤ï¼è¿æ£æ¯æä»¬æéè¦çï¼èä¸å®å¯¹äºç»å¾åºç¨ç¨åºä¸çå½¢ç¶ã游æä¸çæªç©ãç½ç»è·¯ç±å¨ä¸å¯ææçè·¯ç±ç®æ³ççåæ ·éç¨ã
使ç¨ç¹å¾å¯¹è±¡çå¦ä¸ä¸ªå¯è½åå æ¯åå°ç¼è¯åçä»£ç æ»éãRustå¯è½éè¦ä¸ºæ³å彿°ä½¿ç¨çæ¯ç§ç±»åé½ç¼è¯ä¸æ¬¡ãè¿å¯è½ä¼ä½¿äºè¿å¶æä»¶å大ï¼å¨C++é¢åï¼è¿ç§ç°è±¡è¢«ç§°ä¸ºä»£ç è¨èãå¦ä»ï¼å åå¾å è¶³ï¼æä»¬å¤§å¤æ°äººé½å¯ä»¥å¿½ç¥ä»£ç 大å°ï¼ä½ç¡®å®åå¨èµæºåéçç¯å¢ã
é¤äºæ¶åâæ²æâæä½èµæºç¯å¢çæ åµå¤ï¼æ³åç¸å¯¹äºç¹å¾å¯¹è±¡æä¸ä¸ªéè¦ä¼å¿ï¼å æ¤å¨Rustä¸ï¼æ³åæ¯æ´å¸¸ç¨çéæ©ã
第ä¸ä¸ªä¼å¿æ¯éåº¦ãæ³¨ææ³å彿°ç¾å䏿²¡ædynå
³é®åãå ä¸ºä½ å¨ç¼è¯æ¶æå®ç±»åï¼æ è®ºæ¯æ¾å¼æå®è¿æ¯éè¿ç±»åæ¨æï¼ç¼è¯å¨é½ç¡®åç¥éè¦è°ç¨åªä¸ªwriteæ¹æ³ãä¸ä½¿ç¨dynå
³é®åæ¯å 为没æç¹å¾å¯¹è±¡ââä¹å°±æ²¡æå¨æååââæ¶åå
¶ä¸ã
å¼è¨ä¸å±ç¤ºçæ³åmin()彿°åæä»¬åå«ç¼åmin_u8ãmin_i64ãmin_stringç彿°çéåº¦ä¸æ ·å¿«ãç¼è¯å¨å¯ä»¥å对å¾
ä»»ä½å
¶ä»å½æ°ä¸æ ·å
èå®ï¼æä»¥å¨åå¸çæ¬çæå»ºä¸ï¼å¯¹min::<i32>çè°ç¨å¯è½åªéè¦ä¸¤ä¸æ¡æä»¤ã使ç¨å¸¸éåæ°çè°ç¨ï¼æ¯å¦min(5, 3)ï¼ä¼æ´å¿«ï¼Rustå¯ä»¥å¨ç¼è¯æ¶è®¡ç®å®ï¼æä»¥è¿è¡æ¶å®å
¨æ²¡æå¼éã
åçè¿ä¸ªæ³å彿°è°ç¨ï¼
let mut sink = std::io::sink();
say_hello(&mut sink)?;
2
std::io::sink()è¿åä¸ä¸ªSinkç±»åçåå
¥å¨ï¼å®ä¼ææå°ä¸¢å¼åå
¥çææåèã
å½Rustä¸ºè¿æ®µä»£ç çææºå¨ç æ¶ï¼å®å¯ä»¥çæè°ç¨Sink::write_allãæ£æ¥é误ï¼ç¶åè°ç¨Sink::flushç代ç ãè¿æ¯æ³å彿°ä½ä¸è¦æ±åçäºæ
ã
æè ï¼Rustå¯ä»¥æ¥çè¿äºæ¹æ³ï¼å¹¶æè¯å°ä»¥ä¸å ç¹ï¼
Sink::write_all()ä»ä¹é½ä¸åãSink::flush()ä»ä¹é½ä¸åã- è¿ä¸¤ä¸ªæ¹æ³é½ä¸ä¼è¿åé误ã
ç®èè¨ä¹ï¼Rustæ¥æå®å ¨ä¼åæè¿ä¸ªå½æ°è°ç¨æéçææä¿¡æ¯ã
å°å
¶ä¸ä½¿ç¨ç¹å¾å¯¹è±¡çè¡ä¸ºè¿è¡æ¯è¾ãRustç´å°è¿è¡æ¶æç¥éç¹å¾å¯¹è±¡æåä»ä¹ç±»åçå¼ãæä»¥å³ä½¿ä½ ä¼ éä¸ä¸ªSinkï¼è°ç¨èæ¹æ³åæ£æ¥é误çå¼éä»ç¶åå¨ã
æ³åç第äºä¸ªä¼å¿æ¯ï¼å¹¶éæ¯ä¸ªç¹å¾é½æ¯æç¹å¾å¯¹è±¡ãç¹å¾æ¯æä¸äºåè½ï¼æ¯å¦å ³è彿°ï¼è¿äºåè½åªéç¨äºæ³åï¼å®ä»¬å®å ¨æé¤äºç¹å¾å¯¹è±¡ç使ç¨ãæä»¬å¨ä»ç»è¿äºåè½æ¶ä¼æåºã
æ³åç第ä¸ä¸ªä¼å¿æ¯ï¼å¾å®¹æåæ¶ç¨å¤ä¸ªç¹å¾æ¥çº¦ææ³åç±»ååæ°ï¼å°±åæä»¬çtop_ten彿°è¦æ±å
¶Tåæ°å®ç°Debug + Hash + Eq䏿 ·ãç¹å¾å¯¹è±¡åä¸å°è¿ä¸ç¹ï¼Rust䏿¯æå&mut (dyn Debug + Hash + Eq)è¿æ ·çç±»åãï¼ä½ å¯ä»¥ä½¿ç¨æ¬ç« åé¢å®ä¹çåç¹å¾æ¥è§£å³è¿ä¸ªé®é¢ï¼ä½è¿æç¹å¤æãï¼
# å®ä¹åå®ç°ç¹å¾
å®ä¹ä¸ä¸ªç¹å¾å¾ç®åãç»å®å个ååï¼å¹¶ååºç¹å¾æ¹æ³çç±»åç¾åã妿æä»¬æ£å¨ç¼åä¸ä¸ªæ¸¸æï¼å¯è½ä¼æè¿æ ·ä¸ä¸ªç¹å¾ï¼
/// ç¨äºè¡¨ç¤ºè§è²ãç©åååºæ¯çç¹å¾ââ
/// 游æä¸çä¸ä»»ä½å¨å±å¹ä¸å¯è§çä¸è¥¿ã
trait Visible {
/// å¨ç»å®çç»å¸ä¸æ¸²æè¿ä¸ªå¯¹è±¡ã
fn draw(&self, canvas: &mut Canvas);
/// 妿ç¹å»åæ (x, y)åºè¯¥éä¸è¿ä¸ªå¯¹è±¡ï¼åè¿åtrueã
fn hit_test(&self, x: i32, y: i32) -> bool;
}
2
3
4
5
6
7
8
è¦å®ç°ä¸ä¸ªç¹å¾ï¼ä½¿ç¨impl TraitName for Typeçè¯æ³ï¼
impl Visible for Broom {
fn draw(&self, canvas: &mut Canvas) {
for y in self.y - self.height - 1..self.y {
canvas.write_at(self.x, y, '|');
}
canvas.write_at(self.x, self.y, 'M');
}
fn hit_test(&self, x: i32, y: i32) -> bool {
self.x == x && self.y - self.height - 1 <= y && y <= self.y
}
}
2
3
4
5
6
7
8
9
10
11
注æï¼è¿ä¸ªimplå
å«äºVisibleç¹å¾ä¸æ¯ä¸ªæ¹æ³çå®ç°ï¼æ²¡æå
¶ä»å
容ãå¨ç¹å¾implä¸å®ä¹çææå
容é½å¿
é¡»æ¯è¯¥ç¹å¾çå®é
åè½ï¼å¦ææä»¬æ³æ·»å ä¸ä¸ªè¾
婿¹æ³æ¥æ¯æBroom::draw()ï¼å°±å¿
é¡»å¨ä¸ä¸ªåç¬çimplåä¸å®ä¹ï¼
impl Broom {
/// ä¸é¢`Broom::draw()`使ç¨çè¾
å©å½æ°ã
fn broomstick_range(&self) -> Range<i32> {
self.y - self.height - 1..self.y
}
}
2
3
4
5
6
è¿äºè¾
å©å½æ°å¯ä»¥å¨ç¹å¾implåä¸ä½¿ç¨ï¼
impl Visible for Broom {
fn draw(&self, canvas: &mut Canvas) {
for y in self.broomstick_range() {
...
}
...
}
...
}
2
3
4
5
6
7
8
9
# é»è®¤æ¹æ³
æä»¬ä¹å讨论çSinkåå
¥å¨ç±»åå¯ä»¥ç¨å è¡ä»£ç å®ç°ãé¦å
ï¼å®ä¹ç±»åï¼
/// ä¸ä¸ªå¿½ç¥ä½ åå
¥ç任使°æ®çåå
¥å¨ã
pub struct Sink;
2
Sinkæ¯ä¸ä¸ªç©ºç»æä½ï¼å 为æä»¬ä¸éè¦å¨å
¶ä¸åå¨ä»»ä½æ°æ®ãæ¥ä¸æ¥ï¼ä¸ºSinkæä¾Writeç¹æ§çå®ç°ï¼
use std::io::{Write, Result};
impl Write for Sink {
fn write(&mut self, buf: &[u8]) -> Result<usize> {
// 声称æååå
¥äºæ´ä¸ªç¼å²åºã
Ok(buf.len())
}
fn flush(&mut self) -> Result<()> {
Ok(())
}
}
2
3
4
5
6
7
8
9
10
11
12
å°ç®å为æ¢ï¼è¿ä¸Visibleç¹æ§é常ç¸ä¼¼ã使¯æä»¬ä¹çå°Writeç¹æ§æä¸ä¸ªwrite_allæ¹æ³ï¼
let mut out = Sink;
out.write_all(b"hello world\n")?;
2
为ä»ä¹Rustå
许æä»¬å¨æ²¡æå®ä¹è¿ä¸ªæ¹æ³çæ
åµä¸ä¸ºSinkå®ç°Writeå¢ï¼çæ¡æ¯æ ååºä¸Writeç¹æ§çå®ä¹å
å«äºwrite_allçé»è®¤å®ç°ï¼
trait Write {
fn write(&mut self, buf: &[u8]) -> Result<usize>;
fn flush(&mut self) -> Result<()>;
fn write_all(&mut self, buf: &[u8]) -> Result<()> {
let mut bytes_written = 0;
while bytes_written < buf.len() {
bytes_written += self.write(&buf[bytes_written..])?;
}
Ok(())
}
...
}
2
3
4
5
6
7
8
9
10
11
12
13
14
writeåflushæ¹æ³æ¯æ¯ä¸ªåå
¥å¨é½å¿
é¡»å®ç°çåºæ¬æ¹æ³ãåå
¥å¨ä¹å¯ä»¥å®ç°write_allï¼ä½å¦ææ²¡æå®ç°ï¼å°±ä¼ä½¿ç¨åé¢å±ç¤ºçé»è®¤å®ç°ã
ä½ èªå·±å®ä¹çç¹æ§ä¹å¯ä»¥ä½¿ç¨ç¸åçè¯æ³å å«é»è®¤å®ç°ã
æ ååºä¸å¯¹é»è®¤æ¹æ³ææ¾èçåºç¨æ¯Iteratorç¹æ§ï¼å®æä¸ä¸ªå¿
éçæ¹æ³ï¼.next()ï¼åå å个é»è®¤æ¹æ³ã第15ç« ä¼è§£éåå ã
# ç¹æ§ä¸ä»äººå®ä¹çç±»å
Rustå è®¸ä½ å¨ä»»ä½ç±»åä¸å®ç°ä»»ä½ç¹æ§ï¼åªè¦è¯¥ç¹æ§æç±»åæ¯å¨å½åå ä¸å¼å ¥çã
è¿æå³çï¼ä»»ä½æ¶åä½ æ³ä¸ºæä¸ªç±»åæ·»å æ¹æ³ï¼é½å¯ä»¥ä½¿ç¨ç¹æ§æ¥å®ç°ï¼
trait IsEmoji {
fn is_emoji(&self) -> bool;
}
/// 为å
ç½®å符类åå®ç°IsEmojiç¹æ§ã
impl IsEmoji for char {
fn is_emoji(&self) -> bool {
...
}
}
assert_eq!('$'.is_emoji(), false);
2
3
4
5
6
7
8
9
10
11
12
åå
¶ä»ä»»ä½ç¹æ§æ¹æ³ä¸æ ·ï¼åªæå½IsEmojiå¨ä½ç¨åå
æ¶ï¼è¿ä¸ªæ°çis_emojiæ¹æ³æå¯è§ã
è¿ä¸ªç¹å®ç¹æ§çå¯ä¸ç®çæ¯ä¸ºç°æçcharç±»åæ·»å ä¸ä¸ªæ¹æ³ãè¿è¢«ç§°ä¸ºæ©å±ç¹æ§ï¼extension traitï¼ãå½ç¶ï¼ä½ ä¹å¯ä»¥éè¿ç¼åimpl IsEmoji for str { ... }çæ¹å¼ï¼å°è¿ä¸ªç¹æ§æ·»å å°å
¶ä»ç±»åä¸ã
ä½ çè³å¯ä»¥ä½¿ç¨æ³åimplåï¼ä¸æ¬¡æ§ä¸ºä¸æ´ç±»ç±»åæ·»å æ©å±ç¹æ§ãè¿ä¸ªç¹æ§å¯ä»¥å¨ä»»ä½ç±»åä¸å®ç°ï¼
use std::io::{self, Write};
/// å¯ä»¥åå
¶åéHTMLçç±»åçç¹æ§ã
trait WriteHtml {
fn write_html(&mut self, html: &HtmlDocument) -> io::Result<()>;
}
2
3
4
5
6
为ææå®ç°Writeçç±»åå®ç°è¿ä¸ªç¹æ§ï¼å°±ä½¿å
¶æä¸ºäºä¸ä¸ªæ©å±ç¹æ§ï¼ä¸ºææRuståå
¥å¨æ·»å äºä¸ä¸ªæ¹æ³ï¼
/// ä½ å¯ä»¥å°HTMLåå
¥ä»»ä½std::ioåå
¥å¨ã
impl<W: Write> WriteHtml for W {
fn write_html(&mut self, html: &HtmlDocument) -> io::Result<()> {
...
}
}
2
3
4
5
6
impl<W: Write> WriteHtml for Wè¿è¡ä»£ç çæææ¯ âå¯¹äºæ¯ä¸ä¸ªå®ç°äºWriteçç±»åWï¼è¿éæ¯WriteHtmlç¹æ§é对Wçå®ç°âã
serdeåºå¾å¥½å°å±ç¤ºäºå¨æ åç±»åä¸å®ç°ç¨æ·èªå®ä¹ç¹æ§çå®ç¨æ§ãserdeæ¯ä¸ä¸ªåºåååºï¼ä¹å°±æ¯è¯´ï¼ä½ å¯ä»¥ç¨å®å°Rustæ°æ®ç»æåå
¥ç£çï¼ä¹ååéæ°å è½½ã该åºå®ä¹äºä¸ä¸ªSerializeç¹æ§ï¼ä¸ºå
¶æ¯æçæ¯ç§æ°æ®ç±»åé½å®ç°äºè¿ä¸ªç¹æ§ãæä»¥å¨serdeçæºä»£ç ä¸ï¼æé对boolãi8ãi16ãi32ãæ°ç»åå
ç»ç±»åççSerializeå®ç°ï¼æ¶µçäºææåVecåHashMapè¿æ ·çæ åæ°æ®ç»æã
è¿ä¸åçç»ææ¯ï¼serde为ææè¿äºç±»åæ·»å äºä¸ä¸ª.serialize()æ¹æ³ãå¯ä»¥åè¿æ ·ä½¿ç¨ï¼
use serde::Serialize;
use serde_json;
pub fn save_configuration(config: &HashMap<String, String>) -> std::io::Result<()> {
// å建ä¸ä¸ªJSONåºååå¨ï¼å°æ°æ®åå
¥æä»¶ã
let writer = File::create(config_filename())?;
let mut serializer = serde_json::Serializer::new(writer);
// serdeç`.serialize()`æ¹æ³å®æå
¶ä½å·¥ä½ã
config.serialize(&mut serializer)?;
Ok(())
}
2
3
4
5
6
7
8
9
10
11
æä»¬ä¹å说è¿ï¼å½ä½ å®ç°ä¸ä¸ªç¹æ§æ¶ï¼è¯¥ç¹æ§æç±»åå¿
é¡»æ¯å¨å½åå
䏿°å»ºçãè¿è¢«ç§°ä¸ºå¤å¿è§åï¼orphan ruleï¼ã宿å©äºRustç¡®ä¿ç¹æ§å®ç°çå¯ä¸æ§ãä½ ç代ç ä¸è½ä¸ºu8å®ç°Writeï¼å 为Writeåu8é½å¨æ ååºä¸å®ä¹ã妿Rustå
许å个å
è¿æ ·åï¼é£ä¹å¯è½ä¼å¨ä¸åçå
ä¸åå¨å¤ä¸ªé对u8çWriteå®ç°ï¼èRustå°æ æ³åçå°å³å®å¨ç»å®çæ¹æ³è°ç¨ä¸ä½¿ç¨åªä¸ªå®ç°ã
ï¼C++ä¹æç±»ä¼¼çå¯ä¸æ§éå¶ï¼åä¸å®ä¹è§åï¼One Definition Ruleï¼ãä»¥å ¸åçC++飿 ¼ï¼é¤äºæç®åçæ åµï¼ç¼è¯å¨ä¸ä¼å¼ºå¶æ§è¡è¯¥è§åï¼å¦æä½ è¿åäºå®ï¼ä¼å¾å°æªå®ä¹è¡ä¸ºãï¼
# ç¹æ§ä¸çSelf
ç¹æ§å¯ä»¥ä½¿ç¨Selfå
³é®åä½ä¸ºä¸ç§ç±»åãä¾å¦ï¼æ åçCloneç¹æ§ï¼ç¨å¾®ç®ååï¼çèµ·æ¥æ¯è¿æ ·çï¼
pub trait Clone {
fn clone(&self) -> Self;
...
}
2
3
4
å¨è¿é使ç¨Selfä½ä¸ºè¿åç±»åæå³çx.clone()çç±»åä¸xçç±»åç¸åï¼æ 论xæ¯ä»ä¹ç±»åã妿xæ¯Stringï¼é£ä¹x.clone()çç±»åå°±æ¯Stringï¼è䏿¯dyn Cloneæå
¶ä»ä»»ä½å¯å
éçç±»åã
åæ ·ï¼å¦ææä»¬å®ä¹è¿ä¸ªç¹æ§ï¼
pub trait Spliceable {
fn splice(&self, other: &Self) -> Self;
}
2
3
å¹¶ä¸ºå ¶æä¾ä¸¤ä¸ªå®ç°ï¼
impl Spliceable for CherryTree {
fn splice(&self, other: &Self) -> Self {
...
}
}
impl Spliceable for Mammoth {
fn splice(&self, other: &Self) -> Self {
...
}
}
2
3
4
5
6
7
8
9
10
11
é£ä¹å¨ç¬¬ä¸ä¸ªimplåä¸ï¼Selfåªæ¯CherryTreeçå«åï¼å¨ç¬¬äºä¸ªimplåä¸ï¼å®æ¯Mammothçå«åã
è¿æå³çæä»¬å¯ä»¥æ¼æ¥ä¸¤æ£µæ¨±æ¡æ æä¸¤åªçç¸è±¡ï¼è䏿¯å建ä¸ä¸ªçç¸è±¡ - æ¨±æ¡æ çæäº¤ä½ãselfçç±»ååotherçç±»åå¿
é¡»å¹é
ã
使ç¨Selfç±»åçç¹æ§ä¸ç¹æ§å¯¹è±¡ä¸å
¼å®¹ï¼
// é误ï¼ç¹æ§`Spliceable`ä¸è½ç¨äºåå»ºç¹æ§å¯¹è±¡
fn splice_anything(left: &dyn Spliceable, right: &dyn Spliceable) {
let combo = left.splice(right);
// ...
}
2
3
4
5
卿·±å
¥ç ç©¶ç¹æ§çé«çº§åè½æ¶ï¼æä»¬ä¼å¤æ¬¡éå°è¿ä¸ªåå ãRustæç»è¿æ®µä»£ç æ¯å ä¸ºå®æ æ³å¯¹left.splice(right)è°ç¨è¿è¡ç±»åæ£æ¥ãç¹æ§å¯¹è±¡çå
³é®å¨äºï¼å
¶ç±»åç´å°è¿è¡æ¶æç¥éãRustå¨ç¼è¯æ¶æ æ³ç¥éleftårightæ¯å¦ä¼æ¯æéçç¸åç±»åã
ç¹æ§å¯¹è±¡å®é ä¸éç¨äºæç®åçç¹æ§ï¼å³é£äºå¨Javaä¸å¯ä»¥ç¨æ¥å£æå¨C++ä¸å¯ä»¥ç¨æ½è±¡åºç±»å®ç°çç¹æ§ãç¹æ§çæ´é«çº§åè½å¾æç¨ï¼ä½å®ä»¬ä¸è½ä¸ç¹æ§å¯¹è±¡å ±åï¼å 为使ç¨ç¹æ§å¯¹è±¡æ¶ï¼Rustè¿è¡ç¨åºç±»åæ£æ¥æéçç±»åä¿¡æ¯ä¼ä¸¢å¤±ã
ç°å¨ï¼å¦ææä»¬æ³è¦å®ç°åºå ä¸ä¸å¤ªå¯è½çæ¼æ¥ï¼å¯ä»¥è®¾è®¡ä¸ä¸ªå¯¹ç¹æ§å¯¹è±¡å好çç¹æ§ï¼
pub trait MegaSpliceable {
fn splice(&self, other: &dyn MegaSpliceable) -> Box<dyn MegaSpliceable>;
}
2
3
è¿ä¸ªç¹æ§ä¸ç¹æ§å¯¹è±¡å
¼å®¹ã对è¿ä¸ª.splice()æ¹æ³çè°ç¨è¿è¡ç±»åæ£æ¥æ²¡æé®é¢ï¼å 为åªè¦otheråselfçç±»å齿¯MegaSpliceableï¼å°±ä¸è¦æ±otherçç±»åä¸selfçç±»åå¹é
ã
# åç¹æ§
æä»¬å¯ä»¥å£°æä¸ä¸ªç¹æ§æ¯å¦ä¸ä¸ªç¹æ§çæ©å±ï¼
/// 游æä¸çä¸çæä¸ªè§è²ï¼å¯è½æ¯ç©å®¶ï¼ä¹å¯è½æ¯å
¶ä»å°ç²¾çµãç³åé¬¼ãæ¾é¼ ãé£äººéççã
trait Creature: Visible {
fn position(&self) -> (i32, i32);
fn facing(&self) -> Direction;
...
}
2
3
4
5
6
"trait Creature: Visible"è¿å¥è¯çæææ¯ææçç©é½æ¯å¯è§çãæ¯ä¸ªå®ç°Creatureç¹æ§çç±»åä¹å¿
é¡»å®ç°Visibleç¹æ§ï¼
impl Visible for Broom {
...
}
impl Creature for Broom {
...
}
2
3
4
5
6
7
æä»¬å¯ä»¥æä»»æé¡ºåºå®ç°è¿ä¸¤ä¸ªç¹æ§ï¼ä½æ¯ä¸ºä¸ä¸ªç±»åå®ç°Creatureç¹æ§èä¸å®ç°Visibleç¹æ§æ¯é误çãå¨è¿éï¼æä»¬è¯´Creatureæ¯Visibleçåç¹æ§ï¼èCreatureæ¯Visibleçè¶
ç¹æ§ã
åç¹æ§ç±»ä¼¼äºJavaæC#ä¸ç忥å£ï¼ç¨æ·å¯ä»¥å设任ä½å®ç°åç¹æ§çå¼ä¹å®ç°äºå®çè¶ ç¹æ§ãä½å¨Rustä¸ï¼åç¹æ§ä¸ä¼ç»§æ¿å ¶è¶ ç¹æ§çå ³è项ï¼å¦æä½ æ³è°ç¨æä¸ªç¹æ§çæ¹æ³ï¼æ¯ä¸ªç¹æ§é½å¿ é¡»å¨ä½ç¨åå ã
å®é
ä¸ï¼Rustä¸çåç¹æ§åªæ¯å¯¹Selfç约æçä¸ç§ç®åå½¢å¼ãåè¿æ ·å®ä¹Creatureä¸åé¢å±ç¤ºçå®ä¹å®å
¨çæï¼
trait Creature where Self: Visible {
...
}
2
3
# ç±»åå ³è彿°
å¨å¤§å¤æ°é¢å对象è¯è¨ä¸ï¼æ¥å£ä¸è½å å«éææ¹æ³ææé 彿°ï¼ä½ç¹æ§å¯ä»¥å å«ç±»åå ³è彿°ï¼è¿ç±»ä¼¼äºRustä¸çéææ¹æ³ï¼
trait StringSet {
/// è¿åä¸ä¸ªæ°ç空éåã
fn new() -> Self;
/// è¿åä¸ä¸ªå
å«`strings`䏿æå符串çéåã
fn from_slice(strings: &[&str]) -> Self;
/// æ£æ¥è¿ä¸ªé忝å¦å
å«ç¹å®ç`value`ã
fn contains(&self, string: &str) -> bool;
/// åè¿ä¸ªéå䏿·»å ä¸ä¸ªå符串ã
fn add(&mut self, string: &str);
}
2
3
4
5
6
7
8
9
10
æ¯ä¸ªå®ç°StringSetç¹æ§çç±»åé½å¿
é¡»å®ç°è¿å个å
³è彿°ãå两个ï¼new()åfrom_slice()ï¼ä¸æ¥åselfåæ°ï¼å®ä»¬ç¨ä½æé 彿°ãå¨éæ³å代ç ä¸ï¼å¯ä»¥ä½¿ç¨::è¯æ³è°ç¨è¿äºå½æ°ï¼å°±åè°ç¨å
¶ä»ä»»ä½ç±»åå
³è彿°ä¸æ ·ï¼
// å建两个å设å®ç°äºStringSetç¹æ§çç±»åçéåï¼
let set1 = SortedStringSet::new();
let set2 = HashedStringSet::new();
2
3
卿³å代ç ä¸ä¹æ¯å¦æ¤ï¼åªæ¯ç±»åé常æ¯ä¸ä¸ªç±»ååéï¼å¦ä¸æç¤ºç对S::new()çè°ç¨ï¼
/// è¿å`document`ä¸ä¸å¨`wordlist`ä¸çåè¯éåã
fn unknown_words<S: StringSet>(document: &[String], wordlist: &S) -> S {
let mut unknowns = S::new();
for word in document {
if!wordlist.contains(word) {
unknowns.add(word);
}
}
unknowns
}
2
3
4
5
6
7
8
9
10
ä¸JavaåC#æ¥å£ä¸æ ·ï¼ç¹æ§å¯¹è±¡ä¸æ¯æç±»åå
³è彿°ãå¦æä½ æ³ä½¿ç¨&dyn StringSetç¹æ§å¯¹è±¡ï¼å¿
é¡»æ´æ¹ç¹æ§ï¼ä¸ºæ¯ä¸ªä¸éè¿å¼ç¨æ¥åselfåæ°çå
³è彿°æ·»å where Self: Sized约æï¼
trait StringSet {
fn new() -> Self
where Self: Sized;
fn from_slice(strings: &[&str]) -> Self
where Self: Sized;
fn contains(&self, string: &str) -> bool;
fn add(&mut self, string: &str);
}
2
3
4
5
6
7
8
è¿ä¸ªçº¦æåè¯Rustï¼ç¹å¾å¯¹è±¡æ 鿝æè¿ä¸ªç¹å®çå
³è彿°ãæäºè¿äºæ·»å å
容åï¼StringSetç¹å¾å¯¹è±¡æ¯è¢«å
许çï¼å®ä»¬ä»ç¶ä¸æ¯ænewæfrom_sliceï¼ä½ä½ å¯ä»¥å建å®ä»¬ï¼å¹¶ä½¿ç¨å®ä»¬æ¥è°ç¨.contains()å.add()ãåæ ·çæå·§éç¨äºä»»ä½å
¶ä»ä¸ç¹å¾å¯¹è±¡ä¸å
¼å®¹çæ¹æ³ãï¼æä»¬ä¸ä¼å¨è¿éè¿è¡å
³äºå
¶å·¥ä½åççç¹çææ¯è§£éï¼Sizedç¹å¾å°å¨ç¬¬13ç« ä»ç»ãï¼
# å®å ¨é宿¹æ³è°ç¨
ç®å为æ¢ï¼æä»¬è§è¿çè°ç¨ç¹å¾æ¹æ³çæææ¹å¼ï¼é½ä¾èµRustå¸®ä½ è¡¥å ä¸äºç¼ºå¤±çé¨åãä¾å¦ï¼åè®¾ä½ åä¸å¦ä¸ä»£ç ï¼
"hello".to_string()
è¿éçto_stringæçæ¯ToStringç¹å¾çto_stringæ¹æ³ï¼æä»¬è°ç¨çæ¯strç±»åå¯¹è¯¥æ¹æ³çå®ç°ãæä»¥è¿éæ¶åå个è¦ç´ ï¼ç¹å¾ãç¹å¾çæ¹æ³ãæ¹æ³çå®ç°ï¼ä»¥ååºç¨è¯¥å®ç°çå¼ãæ¯æ¬¡è°ç¨æ¹æ³æ¶ï¼ä¸å¿
æè¿äºé½è¯¦ç»ååºæ¥ï¼è¿ç¡®å®å¾æ¹ä¾¿ãä½å¨æäºæ
åµä¸ï¼ä½ éè¦ä¸ç§è½ç²¾å表达èªå·±æå¾çæ¹å¼ãå®å
¨é宿¹æ³è°ç¨å°±å¾åéã
é¦å ï¼è¦ç¥éæ¹æ³å ¶å®å°±æ¯ä¸ç§ç¹æ®ç彿°ãä¸é¢è¿ä¸¤ç§è°ç¨æ¹å¼æ¯çä»·çï¼
"hello".to_string()
str::to_string("hello")
2
第äºç§å½¢å¼çèµ·æ¥å®å
¨å°±æ¯è°ç¨å
³è彿°ãå³ä¾¿to_stringæ¹æ³éè¦selfåæ°ï¼è¿ç§è°ç¨æ¹å¼ä¹æ²¡é®é¢ãåªéæselfä½ä¸ºå½æ°ç第ä¸ä¸ªåæ°ä¼ è¿å»å°±è¡ã
ç±äºto_stringæ¯æ åToStringç¹å¾çæ¹æ³ï¼ä½ è¿å¯ä»¥ä½¿ç¨å¦å¤ä¸¤ç§å½¢å¼ï¼
ToString::to_string("hello")
<str as ToString>::to_string("hello")
2
è¿åç§æ¹æ³è°ç¨çææå®å ¨ä¸æ ·ã
大夿°æ¶åï¼ä½ ç´æ¥åvalue.method()å°±è¡ãå
¶ä»å½¢å¼å±äºé宿¹æ³è°ç¨ï¼å®ä»¬æå®äºæ¹æ³æå
³èçç±»åæç¹å¾ãæåä¸ç§å¸¦å°æ¬å·çå½¢å¼ï¼ä¸¤ç§é½æå®äºï¼è¿å°±æ¯å®å
¨é宿¹æ³è°ç¨ã
å½ä½ ç¨.è¿ç®ç¬¦å"hello".to_string()æ¶ï¼å¹¶æ²¡ææç¡®æåºè°ç¨çæ¯åªä¸ªto_stringæ¹æ³ãRustæä¸å¥æ¹æ³æ¥æ¾ç®æ³ï¼ä¼æ ¹æ®ç±»åãè§£å¼ç¨å¼ºå¶è½¬æ¢çå ç´ æ¥ç¡®å®å
·ä½è°ç¨çæ¹æ³ã使ç¨å®å
¨éå®è°ç¨ï¼ä½ å°±è½ç²¾åæå®è¦è°ç¨çæ¹æ³ï¼å¨ä¸äºç¹æ®æ
åµä¸ï¼è¿å¾æå¸®å©ï¼
- å½ä¸¤ä¸ªæ¹æ³ååæ¶ãç»å
¸çä¾åæ¯
Outlawç»æä½ï¼å®ä»ä¸¤ä¸ªä¸åçç¹å¾éç»§æ¿äºä¸¤ä¸ª.draw()æ¹æ³ï¼ä¸ä¸ªç¨äºå¨å±å¹ä¸ç»å¶ï¼å¦ä¸ä¸ªç¨äºä¸æ³å¾ç¸å ³ç交äºï¼
outlaw.draw(); // æ¥éï¼æ¯å¨å±å¹ä¸ç»å¶ï¼è¿æ¯æåºææªï¼
Visible::draw(&outlaw); // 没é®é¢ï¼å¨å±å¹ä¸ç»å¶
HasPistol::draw(&outlaw); // 没é®é¢ï¼æ§æ³ç¸å
³æä½
2
3
é常æ¥è¯´ï¼æå¥½æå ¶ä¸ä¸ä¸ªæ¹æ³éå½åï¼ä½æäºæ¶åæ²¡åæ³è¿ä¹åã
- å½
selfåæ°çç±»åæ æ³æ¨ææ¶ï¼
let zero = 0; // æªæå®ç±»åï¼å¯è½æ¯`i8`ã`u8`çç
zero.abs(); // æ¥éï¼æ æ³å¨ç±»åä¸æç¡®çæ°å¼ä¸è°ç¨`abs`æ¹æ³
i64::abs(zero); // 没é®é¢
2
3
- 彿彿°æ¬èº«å½ä½å½æ°å¼ä½¿ç¨æ¶ï¼
let words: Vec<String> =
line.split_whitespace() // è¿ä»£å¨çæ`&str`å¼
.map(ToString::to_string) // 没é®é¢
.collect();
2
3
4
- å½å¨å®éè°ç¨ç¹å¾æ¹æ³æ¶ãæä»¬ä¼å¨ç¬¬21ç« è§£éã
å®å
¨éå®è¯æ³ä¹éç¨äºå
³è彿°ãä¸ä¸èéï¼æä»¬å¨æ³å彿°éç¨S::new()å建æ°éåãæä»¬ä¹å¯ä»¥åæStringSet::new()ï¼æè
<S as StringSet>::new()ã
# å®ä¹ç±»åé´å ³ç³»çç¹å¾
å°ç®å为æ¢ï¼æä»¬çå°çæ¯ä¸ªç¹å¾é½æ¯ç¬ç«çï¼ä¸ä¸ªç¹å¾å°±æ¯ä¸ç»ç±»åå¯ä»¥å®ç°çæ¹æ³ãç¹å¾è¿è½ç¨äºå¤ä¸ªç±»åéè¦ååå·¥ä½çåºæ¯ï¼å®ä»¬å¯ä»¥æè¿°ç±»åä¹é´çå ³ç³»ã
std::iter::Iteratorç¹å¾å°æ¯ç§è¿ä»£å¨ç±»ååå®çæçå¼çç±»åå ³èèµ·æ¥ãstd::ops::Mulç¹å¾å ³èäºå¯ä»¥è¿è¡ä¹æ³è¿ç®çç±»åãå¨è¡¨è¾¾å¼a * béï¼aåbçå¼å¯ä»¥æ¯ç¸åç±»åï¼ä¹å¯ä»¥æ¯ä¸åç±»åãrandåºå å«ä¸ä¸ªç¨äºéæºæ°çæå¨çç¹å¾ï¼rand::Rngï¼ï¼è¿æä¸ä¸ªç¨äºå¯éæºçæç±»åçç¹å¾ï¼rand::Distributionï¼ãè¿äºç¹å¾æç¡®è§å®äºè¿äºç±»åå¦ä½ååå·¥ä½ã
ä½ ä¸ç¨æ¯å¤©é½å建è¿ç±»ç¹å¾ï¼ä½å¨æ ååºåç¬¬ä¸æ¹åºä¸ï¼ä½ ä¼ç»å¸¸éå°å®ä»¬ã卿¬èä¸ï¼æä»¬ä¼å±ç¤ºè¿äºç¤ºä¾æ¯å¦ä½å®ç°çï¼å¨éè¦çæ¶åä»ç»ç¸å ³çRustè¯è¨ç¹æ§ãè¿éçå ³é®æè½æ¯è¯»æç¹å¾åæ¹æ³ç¾åï¼çè§£å®ä»¬å¯¹ç¸å ³ç±»åçæè¿°ã
# å ³èç±»åï¼æè¿ä»£å¨çå·¥ä½åçï¼
æä»¬ä»è¿ä»£å¨å¼å§è®²èµ·ãå¦ä»ï¼æ¯ç§é¢å对象è¯è¨é½å¯¹è¿ä»£å¨æä¾äºæç§å ç½®æ¯æï¼è¿ä»£å¨æ¯ç¨æ¥éåæäºå¼åºåç对象ã
Rustæä¸ä¸ªæ åçIteratorç¹å¾ï¼å®ä¹å¦ä¸ï¼
pub trait Iterator {
type Item;
fn next(&mut self) -> Option<Self::Item>;
...
}
2
3
4
5
è¿ä¸ªç¹å¾ç第ä¸ä¸ªç¹æ§type Item;æ¯ä¸ä¸ªå
³èç±»åãæ¯ä¸ªå®ç°Iteratorçç±»åé½å¿
é¡»æå®å®çæç项æ¯ä»ä¹ç±»åã
第äºä¸ªç¹æ§next()æ¹æ³ï¼å¨è¿åå¼éç¨å°äºè¿ä¸ªå
³èç±»åãnext()è¿åä¸ä¸ªOption<Self::Item>ï¼è¦ä¹æ¯Some(item)ï¼å³åºåéçä¸ä¸ä¸ªå¼ï¼è¦ä¹æ¯Noneï¼è¡¨ç¤ºæ²¡ææ´å¤å¼å¯è®¿é®äºãç±»ååæSelf::Itemï¼è䏿¯ç®åçItemï¼å 为Itemæ¯æ¯ç§è¿ä»£å¨ç±»åçç¹æ§ï¼ä¸æ¯ä¸ä¸ªç¬ç«çç±»åãåå¾å¸¸ä¸æ ·ï¼åªè¦ä½¿ç¨selfåSelfç±»åçåæ®µãæ¹æ³çï¼å®ä»¬å°±ä¼å¨ä»£ç éæ¾å¼åºç°ã
ä¸é¢æ¯ä¸ºä¸ä¸ªç±»åå®ç°Iteratorç¹å¾ç示ä¾ï¼
// ï¼ä»£ç æ¥èª`std::env`æ ååºæ¨¡åï¼
impl Iterator for Args {
type Item = String;
fn next(&mut self) -> Option<String> {
...
}
...
}
2
3
4
5
6
7
8
std::env::Argsæ¯æ ååºå½æ°std::env::args()è¿åçè¿ä»£å¨ç±»åï¼æä»¬å¨ç¬¬2ç« ç¨è¿ä¸ªå½æ°æ¥è®¿é®å½ä»¤è¡åæ°ãå®çæStringå¼ï¼æä»¥å¨å®ç°é¨å声ætype Item = String;ã
æ³å代ç å¯ä»¥ä½¿ç¨å ³èç±»åï¼
/// éåä¸ä¸ªè¿ä»£å¨ï¼æå¼åå°ä¸ä¸ªæ°çåééã
fn collect_into_vector<I: Iterator>(iter: I) -> Vec<I::Item> {
let mut results = Vec::new();
for value in iter {
results.push(value);
}
results
}
2
3
4
5
6
7
8
å¨è¿ä¸ªå½æ°ä½éï¼Rustä¼å¸®æä»¬æ¨ævalueçç±»åï¼è¿å¾æ¹ä¾¿ï¼ä½æä»¬å¿
é¡»æç¡®ååºcollect_into_vectorçè¿åç±»åï¼èå
³èç±»åItemæ¯å®ç°è¿ä¸ç¹çå¯ä¸æ¹å¼ãï¼Vec<I>æ¯å®å
¨é误çï¼è¿æå³çæä»¬è¿åçæ¯ä¸ä¸ªè¿ä»£å¨åéï¼ï¼
åé¢è¿ä¸ªç¤ºä¾ä»£ç ï¼ä½ ä¸è¬ä¸ä¼èªå·±å»åï¼å 为读å®ç¬¬15ç« åï¼ä½ å°±ä¼ç¥éè¿ä»£å¨å·²ç»æä¸ä¸ªæ åæ¹æ³è½å®ç°åæ ·çåè½ï¼iter.collect()ãæä»¥å¨ç»§ç»å¾ä¸è®²ä¹åï¼æä»¬åçä¸ä¸ªç¤ºä¾ï¼
/// æå°è¿ä»£å¨çæçææå¼
fn dump<I>(iter: I)
where
I: Iterator
{
for (index, value) in iter.enumerate() {
println!("{}: {:?}", index, value); // æ¥é
}
}
2
3
4
5
6
7
8
9
è¿æ®µä»£ç åºæ¬æ²¡é®é¢ï¼ä½æä¸ä¸ªé®é¢ï¼valueå¯è½ä¸æ¯å¯æå°çç±»åã
error: `<I as Iterator>::Item` doesn't implement `Debug`
|
8 | println!("{}: {:?}", index, value); // error
| ^^^^^
| `<I as Iterator>::Item` cannot be
formatted
| using `{:?}` because it doesn't
implement `Debug`
|
= help: the trait `Debug` is not implemented for `<I as
Iterator>::Item`
= note: required by `std::fmt::Debug::fmt`
help: consider further restricting the associated type
|
5 | where I: Iterator, <I as Iterator>::Item: Debug
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
æ¥éä¿¡æ¯éç¨äº<I as Iterator>::Itemè¿ç§è¯æ³ï¼è¿æ¯ä¸ç§æç¡®ä½å¾åé¿ç表示I::Itemçæ¹å¼ï¼è®©æ¥éä¿¡æ¯æç¹é¾æãè¿æ¯ææçRustè¯æ³ï¼ä½å®é
ä¸ä½ å¾å°éè¦è¿ä¹åç±»åã
æ¥éä¿¡æ¯çæ ¸å¿æææ¯ï¼è¦è®©è¿ä¸ªæ³å彿°è½ç¼è¯éè¿ï¼æä»¬å¿
须确ä¿I::Itemå®ç°äºDebugç¹å¾ï¼Debugç¹å¾ç¨äºç¨{:?}æ ¼å¼åå¼ã就忥éä¿¡æ¯é建议çï¼æä»¬å¯ä»¥éè¿å¯¹I::Itemè®¾ç½®çº¦ææ¥å®ç°ï¼
use std::fmt::Debug;
fn dump<I>(iter: I)
where
I: Iterator,
I::Item: Debug
{
...
}
2
3
4
5
6
7
8
æè
ï¼æä»¬å¯ä»¥åæ âIå¿
é¡»æ¯ä¸ä¸ªçæStringå¼çè¿ä»£å¨âï¼
fn dump<I>(iter: I)
where
I: Iterator<Item = String>
{
...
}
2
3
4
5
6
Iterator<Item = String>æ¬èº«ä¹æ¯ä¸ä¸ªç¹å¾ãå¦æä½ æIteratorç使¯ææè¿ä»£å¨ç±»åçéåï¼é£ä¹Iterator<Item = String>å°±æ¯Iteratorçä¸ä¸ªåéï¼å³çæStringçè¿ä»£å¨ç±»åçéåãè¿ç§è¯æ³å¯ä»¥ç¨å¨ä»»ä½è½ä½¿ç¨ç¹å¾åç§°çå°æ¹ï¼å
æ¬ç¹å¾å¯¹è±¡ç±»åï¼
fn dump(iter: &mut dyn Iterator<Item = String>) {
for (index, s) in iter.enumerate() {
println!("{}: {:?}", index, s);
}
}
2
3
4
5
åIteratorè¿æ ·æå
³èç±»åçç¹å¾ï¼åªæå¨ææå
³èç±»åé½æç¡®æå®çæ
åµä¸ï¼æåç¹å¾æ¹æ³å
¼å®¹ï¼å°±åè¿éå±ç¤ºç䏿 ·ãå¦åï¼sçç±»åå¯è½æ¯ä»»æçï¼Rustä¹å°±æ²¡åæ³å¯¹è¿æ®µä»£ç è¿è¡ç±»åæ£æ¥ã
æä»¬å±ç¤ºäºå¾å¤åè¿ä»£å¨æå ³ç示ä¾ãè¿å¾é¾é¿å ï¼å 为è¿ä»£å¨æ¯å ³èç±»åæå ¸åçåºç¨åºæ¯ãä½ä¸è¬æ¥è¯´ï¼åªè¦ä¸ä¸ªç¹å¾éè¦æ¶µççä¸åªæ¯æ¹æ³ï¼å ³èç±»å就徿ç¨ï¼
- å¨çº¿ç¨æ± åºä¸ï¼ä»£è¡¨ä¸ä¸ªå·¥ä½åå
ç
Taskç¹å¾ï¼å¯ä»¥æä¸ä¸ªå ³èçOutputç±»åã - 代表å符串æç´¢æ¹å¼ç
Patternç¹å¾ï¼å¯ä»¥æä¸ä¸ªå ³èçMatchç±»åï¼ç¨æ¥è¡¨ç¤ºå°æ¨¡å¼åå符串å¹é æ¶æ¶éå°çææä¿¡æ¯ï¼
trait Pattern {
type Match;
fn search(&self, string: &str) -> Option<Self::Match>;
}
/// ä½ å¯ä»¥å¨å符串éæç´¢ç¹å®å符ã
impl Pattern for char {
/// âå¹é
ç»æâ åªæ¯å符被æ¾å°çä½ç½®ã
type Match = usize;
fn search(&self, string: &str) -> Option<usize> {
...
}
}
2
3
4
5
6
7
8
9
10
11
12
å¦æä½ çææ£å表达å¼ï¼å°±å¾å®¹æç解为RegExpå®ç°Patternç¹å¾æ¶ï¼Matchç±»åä¼å¤æå¾å¤ï¼å¯è½æ¯ä¸ä¸ªç»æä½ï¼å
å«å¹é
çèµ·å§ä½ç½®åé¿åº¦ãæ¬å·åç»çå¹é
ä½ç½®ççã
- ç¨äºæä½å
³ç³»åæ°æ®åºçåºï¼å¯è½æä¸ä¸ª
DatabaseConnectionç¹å¾ï¼å ¶å ³èç±»å代表äºå¡ã游æ ãé¢å¤çè¯å¥ççã
å
³èç±»åé常é忝ç§å®ç°é½æä¸ç§ç¹å®ç¸å
³ç±»åçæ
åµï¼æ¯ç§ç±»åçTaské½ä¼äº§çç¹å®ç±»åçOutputï¼æ¯ç§ç±»åçPatterné½ä¼æ¥æ¾ç¹å®ç±»åçMatchãä¸è¿ï¼æ£å¦æä»¬æ¥ä¸æ¥ä¼çå°çï¼æäºç±»åä¹é´çå
³ç³»å¹¶é妿¤ã
# æ³åç¹å¾ï¼æè¿ç®ç¬¦éè½½çå·¥ä½åçï¼
Rustä¸ç乿³è¿ç®ä½¿ç¨è¿ä¸ªç¹å¾ï¼
/// std::ops::Mulï¼æ¯æ`*`è¿ç®ç¬¦çç±»åçç¹å¾ã
pub trait Mul<RHS> {
/// åºç¨`*`è¿ç®ç¬¦åçç»æç±»å
type Output;
/// `*`è¿ç®ç¬¦çæ¹æ³
fn mul(self, rhs: RHS) -> Self::Output;
}
2
3
4
5
6
7
8
Mulæ¯ä¸ä¸ªæ³åç¹å¾ãç±»ååæ°RHSæ¯âright-hand sideï¼å³ä¾§ï¼âç缩åã
è¿éçç±»ååæ°åå¨ç»æä½æå½æ°ä¸çå«ä¹ç¸åï¼Mulæ¯ä¸ä¸ªæ³åç¹å¾ï¼å®çå®ä¾Mul<f64>ãMul<String>ãMul<Size>ç齿¯ä¸åçç¹å¾ï¼å°±åmin::<i32>åmin::<String>æ¯ä¸åç彿°ï¼Vec<i32>åVec<String>æ¯ä¸åçç±»å䏿 ·ã
ä¸ä¸ªç±»åï¼æ¯å¦WindowSizeï¼å¯ä»¥åæ¶å®ç°Mul<f64>åMul<i32>ï¼çè³æ´å¤ãè¿æ ·ä½ å°±å¯ä»¥ç¨å¤ç§å
¶ä»ç±»åä¸WindowSizeè¿è¡ä¹æ³è¿ç®ã
æ¯ä¸ªå®ç°é½ä¼æèªå·±å
³èçOutputç±»åã
å¨å¤çå¤å¿è§åï¼orphan ruleï¼æ¶ï¼æ³åç¹å¾æç¹æ®çè±å
æ
åµï¼åªè¦ç¹å¾çå
¶ä¸ä¸ä¸ªç±»ååæ°æ¯å¨å½åå
ï¼crateï¼ä¸å®ä¹çç±»åï¼ä½ å°±å¯ä»¥ä¸ºå¤é¨ç±»åå®ç°å¤é¨ç¹å¾ãæä»¥ï¼å¦æä½ èªå·±å®ä¹äºWindowSizeï¼å³ä½¿ä½ 没æå®ä¹Mulåf64ï¼ä¹å¯ä»¥ä¸ºf64å®ç°Mul<WindowSize>ã
è¿äºå®ç°çè³å¯ä»¥æ¯æ³åçï¼æ¯å¦impl<T> Mul<WindowSize> for Vec<T>ãè¿æ¯å¯è¡çï¼å 为å
¶ä»ä»»ä½å
é½ä¸å¯è½ä¸ºå
¶ä»ç±»åå®ä¹Mul<WindowSize>ï¼å æ¤ä¹å°±ä¸ä¼åºç°å®ç°å²çªçæ
åµãï¼æä»¬å¨âç¹å¾ä¸ä»äººçç±»åâä¸ä»ç»è¿å¤å¿è§åãï¼
nalgebraè¿æ ·çå
å°±æ¯éè¿è¿ç§æ¹å¼ä¸ºåéå®ä¹ç®æ¯è¿ç®çã
åé¢å±ç¤ºçç¹å¾å°äºä¸ä¸ªå°ç»èãçæ£çMulç¹å¾æ¯è¿æ ·çï¼
pub trait Mul<RHS = Self> {
...
}
2
3
è¯æ³RHS = Self表示RHSçé»è®¤å¼æ¯Selfã妿æåimpl Mul for Complexï¼æ²¡ææå®Mulçç±»ååæ°ï¼é£å°±æå³çimpl Mul<Complex> for Complexãå¨çº¦æä¸ï¼å¦ææåwhere T: Mulï¼é£å°±æå³çwhere T: Mul<T>ã
å¨Rustä¸ï¼è¡¨è¾¾å¼lhs * rhsæ¯Mul::mul(lhs, rhs)çç®åãæä»¥å¨Rustä¸éè½½*è¿ç®ç¬¦ï¼åªéè¦å®ç°Mulç¹å¾å³å¯ãæä»¬å°å¨ä¸ä¸ç« å±ç¤ºç¤ºä¾ã
# impl Trait
å¯ä»¥æ³è±¡ï¼å¤ç§æ³åç±»åç»åå¨ä¸èµ·å¯è½ä¼åå¾å¾æ··ä¹±ãä¾å¦ï¼ä» ä½¿ç¨æ ååºä¸çç»åå¨ï¼combinatorsï¼ç»åå 个è¿ä»£å¨ï¼å°±ä¼è®©è¿åç±»åå¾å¿«åå¾å¾é¾çï¼
use std::iter;
use std::vec::IntoIter;
fn cyclical_zip(v: Vec<u8>, u: Vec<u8>) -> iter::Cycle<iter::Chain<IntoIter<u8>, IntoIter<u8>>> {
v.into_iter().chain(u.into_iter()).cycle()
}
2
3
4
5
æä»¬å¯ä»¥å¾å®¹æå°ç¨ç¹å¾å¯¹è±¡æ¥æ¿æ¢è¿ä¸ªå¤æçè¿åç±»åï¼
fn cyclical_zip(v: Vec<u8>, u: Vec<u8>) -> Box<dyn Iterator<Item = u8>> {
Box::new(v.into_iter().chain(u.into_iter()).cycle())
}
2
3
ç¶èï¼å¨å¤§å¤æ°æ åµä¸ï¼ä¸ºäºé¿å é¾ççç±»åç¾åï¼æ¯æ¬¡è°ç¨è¿ä¸ªå½æ°é½è¦æ¿æ 卿ååçå¼éåä¸å¯é¿å çå åé ï¼è¿ä¼¼ä¹ä¸æ¯ä¸ä¸ªåç®çåæ³ã
Rustæä¸ä¸ªå为impl Traitçç¹æ§ï¼æ£æ¯ä¸ºè¿ç§æ
åµè®¾è®¡çãimpl Traitå
许æä»¬âæ¦é¤âè¿åå¼çç±»åï¼åªæå®å®å®ç°çä¸ä¸ªæå¤ä¸ªç¹å¾ï¼èæ éè¿è¡å¨æååæå åé
ï¼
fn cyclical_zip(v: Vec<u8>, u: Vec<u8>) -> impl Iterator<Item = u8> {
v.into_iter().chain(u.into_iter()).cycle()
}
2
3
ç°å¨ï¼cyclical_zipçç¾åä¸åæå®ç¹å®çåµå¥è¿ä»£å¨ç»åå¨ç»æä½ç±»åï¼èåªæ¯è¡¨æå®è¿åæç§u8ç±»åçè¿ä»£å¨ãè¿åç±»å表达äºå½æ°çæå¾ï¼è䏿¯å®ç°ç»èã
è¿ç¡®å®æ¸
çäºä»£ç ï¼ä½¿å
¶æ´å
·å¯è¯»æ§ï¼ä½impl Traitä¸ä»
ä»
æ¯ä¸ç§æ¹ä¾¿çç®åã使ç¨impl Traitæå³çï¼åªè¦è¿åçå®é
ç±»åä»ç¶å®ç°äºIterator<Item = u8>ï¼ä½ å°æ¥å°±å¯ä»¥æ´æ¹å®ï¼å¹¶ä¸è°ç¨è¯¥å½æ°çä»»ä½ä»£ç é½å°ç»§ç»ç¼è¯ï¼ä¸ä¼åºç°é®é¢ãè¿ä¸ºåºä½è
æä¾äºå¾å¤§ççµæ´»æ§ï¼å 为类åç¾åä¸åªç¼ç äºç¸å
³çåè½ã
ä¾å¦ï¼å¦æåºç第ä¸ä¸ªçæ¬ä½¿ç¨äºåé¢é£æ ·çè¿ä»£å¨ç»åå¨ï¼ä½åæ¥åç°äºå®ç°ç¸åè¿ç¨çæ´å¥½ç®æ³ï¼åºä½è
å¯ä»¥ä½¿ç¨ä¸åçç»åå¨ï¼çè³å建ä¸ä¸ªå®ç°Iteratorçèªå®ä¹ç±»åï¼èåºçç¨æ·å¯ä»¥å¨å®å
¨ä¸æ´æ¹ä»£ç çæ
åµä¸è·å¾æ§è½æåã
ä½ å¯è½ä¼æ³ç¨impl Traitæ¥è¿ä¼¼å®ç°é¢å对象è¯è¨ä¸å¸¸ç¨ç工忍¡å¼çéæååçæ¬ãä¾å¦ï¼ä½ å¯è½ä¼å®ä¹è¿æ ·ä¸ä¸ªç¹å¾ï¼
trait Shape {
fn new() -> Self;
fn area(&self) -> f64;
}
2
3
4
å¨ä¸ºå ç§ç±»åå®ç°è¯¥ç¹å¾åï¼ä½ å¯è½å¸ææ ¹æ®è¿è¡æ¶çå¼ï¼æ¯å¦ç¨æ·è¾å
¥çå符串ï¼ä½¿ç¨ä¸åçShapeãä½å°impl Shapeä½ä¸ºè¿åç±»åæ¯è¡ä¸éçï¼
fn make_shape(shape: &str) -> impl Shape {
match shape {
"circle" => Circle::new(),
"triangle" => Triangle::new(), // é误ï¼ç±»åä¸å
¼å®¹
"shape" => Rectangle::new(),
}
}
2
3
4
5
6
7
ä»è°ç¨è
çè§åº¦æ¥çï¼è¿æ ·ç彿°æ²¡æä»ä¹æä¹ãimpl Traitæ¯ä¸ç§éæååå½¢å¼ï¼å æ¤ç¼è¯å¨å¿
é¡»å¨ç¼è¯æ¶ç¥é彿°è¿åçç±»åï¼ä»¥ä¾¿å¨æ ä¸åé
æ£ç¡®æ°éç空é´ï¼å¹¶æ£ç¡®è®¿é®è¯¥ç±»åçåæ®µåæ¹æ³ãå¨è¿éï¼è¿åç±»åå¯è½æ¯CircleãTriangleæRectangleï¼å®ä»¬å ç¨ç空é´å¯è½ä¸åï¼å¹¶ä¸area()æ¹æ³çå®ç°ä¹ä¸åã
éè¦æ³¨æçæ¯ï¼Rustä¸å
许ç¹å¾æ¹æ³ä½¿ç¨impl Traitä½ä¸ºè¿åå¼ãè¦æ¯æè¿ä¸ç¹ï¼éè¦å¯¹è¯è¨çç±»åç³»ç»è¿è¡ä¸äºæ¹è¿ãå¨å®æè¿é¡¹å·¥ä½ä¹åï¼åªæèªç±å½æ°åä¸ç¹å®ç±»åç¸å
³èç彿°å¯ä»¥ä½¿ç¨impl Traitä½ä¸ºè¿åå¼ã
impl Traitä¹å¯ä»¥ç¨äºæ¥åæ³ååæ°ç彿°ãä¾å¦ï¼èèè¿ä¸ªç®åçæ³å彿°ï¼
fn print<T: Display>(val: T) {
println!("{}", val);
}
2
3
å®å使ç¨impl Traitççæ¬æ¯ä¸æ ·çï¼
fn print(val: impl Display) {
println!("{}", val);
}
2
3
æä¸ä¸ªéè¦çä¾å¤æ
åµãä½¿ç¨æ³åå
è®¸å½æ°çè°ç¨è
æå®æ³ååæ°çç±»åï¼æ¯å¦print::<i32>(42)ï¼è使ç¨impl Traitåä¸è¡ã
æ¯ä¸ªimpl Traitåæ°é½ä¼è¢«åé
ä¸ä¸ªå¿åç±»ååæ°ï¼æä»¥impl Traitç¨äºåæ°çæ
åµä»
éäºæç®åçæ³å彿°ï¼ä¸åæ°ç±»åä¹é´æ²¡æå
³ç³»ã
# å ³è常é
åç»æä½ãæä¸¾ä¸æ ·ï¼ç¹å¾ä¹å¯ä»¥æå ³è常éãä½ å¯ä»¥ä½¿ç¨ä¸ç»æä½ææä¸¾ç¸åçè¯æ³ï¼å£°æä¸ä¸ªå¸¦æå ³è常éçç¹å¾ï¼
trait Greet {
const GREETING: &'static str = "Hello";
fn greet(&self) -> String;
}
2
3
4
ä¸è¿ï¼ç¹å¾ä¸çå ³è常éæç¹æ®çè½åã
åå ³èç±»åãå ³è彿°ä¸æ ·ï¼ä½ å¯ä»¥å£°æå ³è常éï¼ä½ä¸èµäºå ¶å¼ï¼
trait Float {
const ZERO: Self;
const ONE: Self;
}
2
3
4
ç¶åï¼ç¹å¾çå®ç°è å¯ä»¥å®ä¹è¿äºå¼ï¼
impl Float for f32 {
const ZERO: f32 = 0.0;
const ONE: f32 = 1.0;
}
impl Float for f64 {
const ZERO: f64 = 0.0;
const ONE: f64 = 1.0;
}
2
3
4
5
6
7
8
è¿å è®¸ä½ ç¼å使ç¨è¿äºå¼çæ³å代ç ï¼
fn add_one<T: Float + Add<Output = T>>(value: T) -> T {
value + T::ONE
}
2
3
注æï¼å ³è常éä¸è½ç¨äºç¹å¾å¯¹è±¡ï¼å 为ç¼è¯å¨ä¾èµäºå®ç°çç±»åä¿¡æ¯ï¼ä»¥ä¾¿å¨ç¼è¯æ¶éæ©æ£ç¡®çå¼ã
å³ä½¿æ¯åFloatè¿æ ·æ²¡æä»»ä½è¡ä¸ºçç®åç¹å¾ï¼ç»åä¸äºè¿ç®ç¬¦ï¼ä¹å¯ä»¥æä¾å
³äºä¸ä¸ªç±»åè¶³å¤çä¿¡æ¯ï¼æ¥å®ç°å¸¸è§çæ°å¦å½æ°ï¼æ¯å¦ææ³¢é£å¥å½æ°ï¼
fn fib<T: Float + Add<Output = T>>(n: usize) -> T {
match n {
0 => T::ZERO,
1 => T::ONE,
n => fib::<T>(n - 1) + fib::<T>(n - 2),
}
}
2
3
4
5
6
7
卿å两èä¸ï¼æä»¬å±ç¤ºäºç¹å¾æè¿°ç±»åä¹é´å ³ç³»çä¸åæ¹å¼ãææè¿äºä¹å¯ä»¥ç使¯é¿å èæ¹æ³å¼éååä¸è½¬åçæ¹æ³ï¼å 为å®ä»¬ä½¿Rustå¨ç¼è¯æ¶è½å¤äºè§£æ´å¤å ·ä½ç±»åã
# éåæ¨å¯¼çº¦ææ¡ä»¶
彿²¡æä¸ä¸ªåä¸çç¹å¾è½æ»¡è¶³ä½ ææéæ±æ¶ï¼ç¼åæ³å代ç å¯è½ä¼é常å°é¾ãå设æä»¬ç¼åäºè¿ä¸ªéæ³å彿°æ¥è¿è¡ä¸äºè®¡ç®ï¼
fn dot(v1: &[i64], v2: &[i64]) -> i64 {
let mut total = 0;
for i in 0..v1.len() {
total = total + v1[i] * v2[i];
}
total
}
2
3
4
5
6
7
ç°å¨æä»¬æ³ç¨ç¸åç代ç å¤çæµ®ç¹åæ°å¼ãæä»¬å¯è½ä¼å°è¯è¿æ ·åï¼
fn dot<N>(v1: &[N], v2: &[N]) -> N {
let mut total: N = 0;
for i in 0..v1.len() {
total = total + v1[i] * v2[i];
}
total
}
2
3
4
5
6
7
ä½å¹¶ä¸é¡ºå©ï¼Rustæ±æ¨*è¿ç®ç¬¦ç使ç¨å0çç±»åé®é¢ãæä»¬å¯ä»¥éè¿AddåMulç¹å¾ï¼è¦æ±Næ¯æ¯æ+å*è¿ç®çç±»åãä¸è¿ï¼æä»¬å¯¹0ç使ç¨éè¦æ¹åï¼å 为å¨Rustä¸0å§ç»æ¯æ´æ°ï¼å¯¹åºçæµ®ç¹åæ°å¼æ¯0.0ã幸è¿çæ¯ï¼å¯¹äºæé»è®¤å¼çç±»åï¼Rustæä¸ä¸ªæ åçDefaultç¹å¾ãå¯¹äºæ°å¼ç±»åï¼é»è®¤å¼æ»æ¯0ã代ç å¦ä¸ï¼
use std::ops::{Add, Mul};
fn dot<N: Add + Mul + Default>(v1: &[N], v2: &[N]) -> N {
let mut total = N::default();
for i in 0..v1.len() {
total = total + v1[i] * v2[i];
}
total
}
2
3
4
5
6
7
8
è¿æ ·æ´æ¥è¿æ£ç¡®çæ¡äºï¼ä½ä»ç¶æ æ³æ£å¸¸å·¥ä½ï¼
error: mismatched types
|
5 | fn dot<N: Add + Mul + Default>(v1: &[N], v2: &[N]) -> N {
| - this type parameter
...
8 | total = total + v1[i] * v2[i];
| ^^^^^^^^^^^^^ expected type parameter
`N`,
| found associated type
|
= note: expected type parameter `N`
found associated type `<N as Mul>::Output`
help: consider further restricting this bound
|
5 | fn dot<N: Add + Mul + Default + Mul<Output = N>>(v1: &[N],
v2: &[N]) -> N {
| ^^^^^^^^^^^^^^^^^
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
æä»¬çæ°ä»£ç å设两个Nç±»åçå¼ç¸ä¹ä¼äº§çå¦ä¸ä¸ªNç±»åçå¼ï¼ä½æ
åµå¹¶éä¸å®å¦æ¤ãä½ å¯ä»¥éè½½ä¹æ³è¿ç®ç¬¦ï¼ä½¿å
¶è¿åä»»ä½ä½ æ³è¦çç±»åãæä»¬éè¦ä»¥æç§æ¹å¼åè¯Rustï¼è¿ä¸ªæ³å彿°åªéç¨äºå
·æå¸¸è§ä¹æ³ç¹æ§çç±»åï¼å³N * Nçç»ææ¯Nç±»åãé误信æ¯ä¸çå»ºè®®åºæ¬æ£ç¡®ï¼æä»¬å¯ä»¥å°Mulæ¿æ¢ä¸ºMul<Output = N>ï¼Addä¹ååæ ·çæ¿æ¢ï¼
fn dot<N: Add<Output = N> + Mul<Output = N> + Default>(v1: &[N], v2: &[N]) -> N {
...
}
2
3
æ¤æ¶ï¼çº¦ææ¡ä»¶å¼å§å¢å¤ï¼ä»£ç åå¾é¾ä»¥é
读ãæä»¬æçº¦ææ¡ä»¶ç§»å°whereåå¥ä¸ï¼
fn dot<N>(v1: &[N], v2: &[N]) -> N
where
N: Add<Output = N> + Mul<Output = N> + Default {
...
}
2
3
4
5
å¾å¥½ãä½Rustä»ç¶å¯¹è¿è¡ä»£ç æ¥éï¼
error: cannot move out of type `[N]`, a non-copy slice
|
8 | total = total + v1[i] * v2[i];
| ^^^^^
| |
| cannot move out of here
| move occurs because `v1[_]` has type
`N`,
| which does not implement the `Copy` trait
2
3
4
5
6
7
8
9
ç±äºæä»¬æ²¡æè¦æ±Næ¯å¯å¤å¶ç±»åï¼Rustå°v1[i]è§£é为è¯å¾ä»åçä¸ç§»åºä¸ä¸ªå¼ï¼è¿æ¯ä¸å
许çãä½æä»¬æ ¹æ¬ä¸æ³ä¿®æ¹åçï¼åªæ¯æ³æå¼å¤å¶åºæ¥è¿è¡æä½ã幸è¿çæ¯ï¼Rustææçå
ç½®æ°å¼ç±»åé½å®ç°äºCopyï¼æä»¥æä»¬å¯ä»¥ç®åå°å°å
¶æ·»å å°å¯¹Nç约æä¸ï¼
where
N: Add<Output = N> + Mul<Output = N> + Default + Copy
2
è¿æ ·ï¼ä»£ç å°±å¯ä»¥ç¼è¯å¹¶è¿è¡äºãæç»ä»£ç å¦ä¸ï¼
use std::ops::{Add, Mul};
fn dot<N>(v1: &[N], v2: &[N]) -> N
where
N: Add<Output = N> + Mul<Output = N> + Default + Copy {
let mut total = N::default();
for i in 0..v1.len() {
total = total + v1[i] * v2[i];
}
total
}
#[test]
fn test_dot() {
assert_eq!(dot(&[1, 2, 3, 4], &[1, 1, 1, 1]), 10);
assert_eq!(dot(&[53.0, 7.0], &[1.0, 5.0]), 88.0);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
å¨Rustä¸ï¼è¿ç§æ 嵿¶æåçï¼å¨ä¸ç¼è¯å¨è¿è¡ä¸çªæ¿çâäºè®ºâåï¼ä»£ç çèµ·æ¥ç¸å½ä¸éï¼å°±å¥½åç¼åè¿ç¨ä¸å¸é£é¡ºï¼èä¸è¿è¡ææä¹å¾å¥½ã
æä»¬å¨è¿éæåçï¼æ¯é忍坼Nççº¦ææ¡ä»¶ï¼å©ç¨ç¼è¯å¨æ¥æå¯¼åæ£æ¥æä»¬çå·¥ä½ã乿以æç¹éº»ç¦ï¼æ¯å 为æ ååºä¸æ²¡æä¸ä¸ªNumberç¹å¾ï¼è½å
嫿们æ³è¦ä½¿ç¨çææè¿ç®ç¬¦åæ¹æ³ãå®é
ä¸ï¼æä¸ä¸ªå¾å欢è¿ç弿ºåºnumå®ä¹äºè¿æ ·ä¸ä¸ªç¹å¾ï¼å¦ææä»¬æ©ç¥éï¼å°±å¯ä»¥å¨Cargo.toml䏿·»å numï¼ç¶åè¿æ ·ç¼å代ç ï¼
use num::Num;
fn dot<N: Num + Copy>(v1: &[N], v2: &[N]) -> N {
let mut total = N::zero();
for i in 0..v1.len() {
total = total + v1[i] * v2[i];
}
total
}
2
3
4
5
6
7
8
å°±åå¨é¢å对象ç¼ç¨ä¸ï¼åéçæ¥å£è½è®©ä¸ååå¾ç¾å¥½ä¸æ ·ï¼å¨æ³åç¼ç¨ä¸ï¼åéçç¹å¾ä¹è½è®©ä¸ååå¾ç¾å¥½ã
ä¸è¿ï¼ä¸ºä»ä¹è¦è¿ä¹éº»ç¦å¢ï¼ä¸ºä»ä¹Rustçè®¾è®¡è æ²¡æè®©æ³åæ´åC++模æ¿é£æ ·ï¼å°çº¦ææ¡ä»¶éå«å¨ä»£ç ä¸ï¼ç±»ä¼¼äºâé¸åç±»åâå¢ï¼
Rustè¿ç§æ¹å¼çä¸ä¸ªä¼ç¹æ¯æ³å代ç çååå ¼å®¹æ§ãä½ å¯ä»¥æ´æ¹ä¸ä¸ªå ¬å ±æ³å彿°ææ¹æ³çå®ç°ï¼å¦æä¸æ´æ¹å ¶ç¾åï¼å°±ä¸ä¼ç ´åä»»ä½ä½¿ç¨å®ç代ç ã
çº¦ææ¡ä»¶çå¦ä¸ä¸ªä¼ç¹æ¯ï¼å½ä½ éå°ç¼è¯å¨é误æ¶ï¼è³å°ç¼è¯å¨è½åè¯ä½ é®é¢åºå¨åªéãæ¶åæ¨¡æ¿çC++ç¼è¯å¨é误信æ¯å¯è½æ¯Rustçé¿å¾å¤ï¼ä¼æå许å¤ä¸åç代ç è¡ï¼å 为ç¼è¯å¨æ æ³å¤æé®é¢åºå¨æ¨¡æ¿æ¬èº«ï¼è¿æ¯è°ç¨å®ç代ç ï¼è°ç¨ä»£ç ä¹å¯è½æ¯æ¨¡æ¿ï¼ï¼äº¦ææ¯é£ä¸ªæ¨¡æ¿çè°ç¨è â¦â¦
ä¹è®¸æ¾å¼ååºçº¦ææ¡ä»¶æéè¦çä¼ç¹ï¼å°±æ¯å®ä»¬å¨ä»£ç åææ¡£ä¸æ¸ æ°å¯è§ãä½ æ¥çRust䏿³å彿°çç¾åæ¶ï¼å°±è½æ¸ æ¥å°ç¥é宿¥åä»ä¹æ ·çåæ°ãèæ¨¡æ¿å°±åä¸å°è¿ä¸ç¹ãå¨åBoostè¿æ ·çC++åºä¸ï¼å®æ´è®°å½åæ°ç±»åçå·¥ä½ï¼æ¯æä»¬è¿éæç»åçè¿è¦è°å·¨ï¼å 为Boostçå¼åè æ²¡æç¼è¯å¨æ¥æ£æ¥ä»ä»¬çå·¥ä½ã
# ç¹å¾ä½ä¸ºåºç¡
ç¹å¾æ¯Rustä¸ç主è¦ç»ç»ç¹æ§ä¹ä¸ï¼è¿æ¯æå åçç±çãå´ç»ä¸ä¸ªå¥½çæ¥å£æ¥è®¾è®¡ç¨åºæåºï¼ååéä¸è¿äºã
æ¬ç« å æ¥çåç§è¯æ³ãè§ååè§£éãç°å¨æä»¬å·²ç»æä¸äºåºç¡ï¼å°±å¯ä»¥å¼å§æ¢è®¨å¨Rust代ç ä¸ä½¿ç¨ç¹å¾åæ³åçå¤ç§æ¹å¼ãäºå®ä¸ï¼æä»¬æåå触åç®æ¯ãæ¥ä¸æ¥çä¸¤ç« å°ä»ç»æ ååºæä¾ç常è§ç¹å¾ãåç»ç« èè¿ä¼æ¶åéå ãè¿ä»£å¨ãè¾å ¥/è¾åºåå¹¶åçå 容ãç¹å¾åæ³å卿æè¿äºä¸»é¢ä¸é½èµ·çæ ¸å¿ä½ç¨ã