我爲何學Rust?git
2019年6月18日,Facebook發佈了數字貨幣Libra的技術白皮書,我也第一時間體驗了一下它的智能合約編程語言MOVE,發現這個MOVE是用Rust編寫的,看來想準確理解MOVE的機制,還須要對Rust有深入的理解,因此又開始了Rust的快速入門學習。github
歐拉計劃
看了一下網上有關Rust的介紹,都說它的學習曲線至關陡峭,曾一度被其嚇着,後來發現Rust借鑑了Haskell等函數式編程語言的優勢,而我之前專門學習過Haskell,通過一段時間的入門學習,我如今已經喜歡上這門神奇的語言。算法
入門資料我用官方的《The Rust Programming Language》,很是權威,配合着《Rust by example》這本書一塊兒學習,效果很是不錯。編程
學習任何一項技能最怕沒有反饋,尤爲是學英語、學編程的時候,必定要「用」,學習編程時有一個很是有用的網站,它就是「歐拉計劃」,網址:https://projecteuler.net數組
若是你的英文不過關,有人已經將幾乎全部的題目翻譯成了中文,網址:http://pe-cn.github.io,本書中的許多題目的描述都照搬了該網站的翻譯。緩存
歐拉計劃提供了幾百道由易到難的數學問題,你能夠用任何辦法去解決它,固然主要還得靠編程,但編程語言不限,已經有Java、C#、Python、Lisp、Haskell等各類解法,固然直接用google搜索答案就沒什麼樂趣了。微信
學習Rust最好先把基本的語法和特性看過一遍,而後就能夠動手解題了,解題的過程就是學習、試錯、再學習、掌握和鞏固的過程,學習進度會大大加快。app
題型介紹
歐拉計劃中的各題都標出了難度係數,以百分數來表示,5%是其中難度最低的,難度最高的爲100%,截止到2019年10月10日,難題係數爲5%的題共有63道,能夠做爲Rust的入門練手題。編程語言
這些初級難度的題目,主要涉及整除性質、素數、因子、分數、迴文數、階乘、三角數、大整數、數字序列、路徑計算、日期、全排列、組合數、初級密碼學等方面,經過解這些題,能夠了解Rust中的基本數據類型,向量用法,理解Rust中特有的全部權體系,體會函數式編程的思惟等。函數式編程
在歐拉計劃的官網上註冊帳號後,若是得出了某題的正確答案,能夠在論壇裏參與相關的討論,看看其餘人的解題思路和源代碼,得到一些靈感。
下面我把63道題分爲幾大類,經過研究這些題的解法,我學會了Rust的一些語法知識點和編程算法。
第一部分 小試牛刀
這一部分題型相對簡單,能夠了解Rust的基本數據類型,整數運算、文件讀取和字符串操做。
第1題 篩選整數
第2題 偶斐波那契數
第3題 最大質因數
第4題 最大回文乘積
第5題 最小倍數
第6題 平方和與和的平方之差
第8題 連續數字最大乘積
第17題 表達數字的英文字母計數
第22題 姓名得分
主要的語法知識點:
Rust的安裝
cargo包管理器的使用
vscode中相關插件的安裝,程序的調試
println!宏的使用
循環語句for的寫法,注意與C語言的不一樣之處
mut關鍵字,體會什麼是可修改的變量
向量Vec的基本用法,vec!宏的使用
迭代器iter()和enumerate()的基本用法
延遲評價的設計理念
強類型特色,幾種數據類型
字符串的基本操做,字符串切片slice的理解
字符與整型的轉換
第二部分 序列
根據必定的規則,一個數字能夠變換爲另外一個數字,但最後會收斂到一個特定的值。
第14題 最長考拉茲序列
第92題 平方數字鏈
遞歸函數的寫法
chars()、map()、sum()和count()等函數的應用
如何優化程序的性能
if表達式
第三部分 因子
一個數有質因子,真因子等概念,而後引出了親和數、盈數等有趣的數字。
第12題 因子繁多的三角數
第21題 親和數
第23題 非盈數之和
第47題 不一樣的質因數
因子、質因子的求法
數組做爲函數參數的寫法:&[bool]
primes函數庫的使用
第四部分 素數
歐拉是一個數學家,因此歐拉計劃中題型以數學題爲主,而其中與素數有關的問題特別多。
第7題 第10001個素數
第10題 素數的和
第27題 二次多項式生成素數
第35題 旋轉素數
第37題 左截和右截素數
第50題 連續素數的和
第58題 螺旋素數
第97題 非梅森大素數
篩子求素數的算法
const常量定義的寫法
usize和isize的應用
字符串的push()、remove()和parse()函數的應用
filter()和take()的使用
第五部分 數字遊戲
勾股數、冪運算、階乘、迴文等一些數字遊戲。
第9題 特殊勾股數
第11題 方陣中的最大乘積
第28題 螺旋數陣對角線
第30題 各位數字的五次冪
第32題 全數字的乘積
第34題 各位數字的階乘
第36題 兩種進制的迴文數
第38題 全數字的倍數
第40題 錢珀瑙恩常數
第46題 哥德巴赫的另外一個猜測
第52題 重排的倍數
第206題 被遮擋的平方數
二維數組的寫法
步長大於1的迭代器用step_by()
chars()和map()的組合運用
數字的二進制轉換
第六部分 大整數
各類編程語言一般都提供64位的整數,表示的最大值爲18446744073709551615,也只有20位數字。對於超過這個範圍的整數,日常的數據類型就沒法進行運算,這時須要用到大整數函數庫num-bigint。
第13題 大整數求和
第16題 冪的數字和
第20題 階乘數字和
第25題 一千位斐波那契數
第29題 不一樣的冪
第48題 自冪
第53題 組合數選擇
第55題 利克瑞爾數
第56題 冪的數字和
第57題 平方根逼近
第63題 冪次與位數
字符串轉換成BigUInt
切片slice的使用
fold()函數的學習
第七部分 路徑
求不一樣的路徑或者最大路徑,學習遞歸算法和改進算法。
第15題 網格路徑
第18題 最大路徑和I
第67題 最大路徑和II
把一個可修改的向量看成函數參數的寫法,&mut Vec<u64>
遞歸中緩存一些運算結果
讀文件的操做
路徑中分層計算的算法優化
第八部分 日期
只有一道涉及日期的計算。
第19題 數星期日
chrono函數庫的使用
day()和weekday()的使用
表示時間跨度的time::Duration
第九部分 排列組合
學習全排列的幾種生成算法。
第24題 字典序排列
第31題 硬幣求和
第41題 全數字的素數
第49題 素數重排
第43題 子串的可整除性
學寫按字典生成全排列的算法
不從新發明輪子,使用別人的庫 permutohedron::heap_recursive
第十部分 分數
分數能夠表示爲無限循環小數,不斷試除和取餘來找循環節。
第26題 倒數的循環節
第33題 消去數字的分數
Option<T>、Some<T>和None的使用
match關鍵字如何匹配表達式
第十一部分 三角形數
根據一個函數能夠生成一系列的整數。
第39題 直角三角形
第42題 編碼三角形數
第44題 五邊形數
第45題 三角形數、五邊形數和六角形數
字符與ASCII碼的轉換
一元二次函數的求根公式
第十二部分 密碼學
這裏有兩道初級的黑客問題。
第59題 異或解密
第79題 密碼推斷
異或XOR
字符串的split()函數的使用
graphviz工具的運用
小結
一、刷題容易上癮
一開始解題是想快速掌握Rust的語法,前面進展較慢,由於語法不熟,須要邊看Rust編程書,邊google,邊試驗才能解決一道題。
在完成了30題左右以後,有點遊戲闖關上癮的感受,有些題即便5%難度係數,解決起來也並不容易,須要不斷找bug或優化算法的性能,當在projecteuler.net上輸入答案獲得正確反饋的一刻,有一種打怪升級的快感。
而後就想會把前50題,前70題所有攻克!
慢慢地就會忘了學Rust的初心,忘了作歐拉題的初心,我是想學MOVE編程語言,我是想學區塊鏈的智能合約編程技術,因此就放慢了刷題的節奏。
寫完這63道題的小結,也是將前面學習Rust的過程進行一次小結。後面可能會更新這本PDF書,也可能不會。
二、數學題並非所有
歐拉計劃以數學題爲主,對數學或算法感興趣的朋友,能夠拿它練習,若是你學習JAVA、C#、Python等編程語言,拿它練練手,絕對蠻有用,必定要先本身試着作一下,直接看別人的源碼什麼也學不到。
但它的侷限性也是顯然的,實際的軟件項目中幾乎很難遇到素數判斷、質因子、大整數以及全排列生成的這些算法。你更要學習模塊的劃分、單元測試的編寫、程序的調試的基本技巧,字符串操做、數組排序、字典、哈希表的運用可能更加頻繁。
三、函數式編程
現代的編程語言都結合了過程式編程和函數式編程的優勢,經過這些例子的練習,你既能夠掌握一般的過程式算法的寫法,也要理解函數式編程的優美和簡潔,但在實際項目中又不能爲了函數式編程減小几行代碼而去刻意地炫技,讓程序失去了可維護性。
須要在過程式編程和函數式編程之間達到一種平衡。
四、還得結合其它編程書籍
程序完成了,獲得了正確的答案,事情並無結束,Rust背後的一些原理,仍須要深刻地理解,字符串和切片的區別,iter()的背後機制,如何定義宏,全部權的借用關係,這些都尚未真正掌握。
內容太多,我直接把它寫成了一本電子書,下載地址:
https://pan.baidu.com/s/1Py8rp4pqAQ5EU7vz6uLYxQ
提取碼: 58zw
近期文章:
本文分享自微信公衆號 - Rust語言中文社區(rust-china)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。