1. rust性能到底有多好
這個和c++大同小異。 因為把大量的運行時放到了編譯時。 只不過編譯器優化不夠還達不到c++性能。
其實rust和c++的關系很想scala和java的關系。 rust和c++很多概念甚至庫都是通用的,抽象化方式,比如泛性,多態,可變性,拷貝構造,移動構造,都是一樣的。 你要是寫過c++再來寫rust,就會吐槽原來這個功能也有啊...
運行速度上rust c++ java都是大同小異,io處理上 java甚至比rust還要快。內存消耗rust和c++是一個級別的,都非常低。 另外很多人寫rust喜歡用arc cellref這些只能指針, 其實是給這些變數增加了動態性會導致額外開銷,所以這些特性用多了後,rust性能也不會太高:
2. 哪種高級編程語言的執行速度最快
回答時間2019年下半年
僅限高級語言
排名由前到後
性能 C Rust C++ Ada Java Pascal Chapel Lisp Ocaml Fortran Swift Haskell CSharp(C#) Go Dart F# Javascript Racket
時間 C Rust C++ Ada Java Chapel Go Pascal Ocaml C# Lisp Haskell Swift Fortran F# Javascript Dart Racket
內存佔用 Pascal Go C Fortran C++ Ada Rust Lisp Haskell PHP Swift Python Ocmal C# Hack Racket
性能 對CPU資源消耗程度 越少越好
時間 運行同樣代碼任務所需時間 越短越好
內存佔用 對內存的消耗 越少越好
C Rust C++ Ada 都是強類型的靜態語言,性能非常接近,java可以說的帶runtime的最快的語言。目前這四門頂級性能高級語言中最設計先進的是Rust,由於rust為了解決C系遺留安全問題,引入了ownership lifetime reference,因此最難入門的也是Rust。C C++ 入門較容易,但設計復雜的大型項目時C和C++將會變得困難,特別是C。建議學習路線 C>C++>Rust。
3. Rust語言的最新版本說明
Mozilla在2014年10月宣布發布Rust編譯器和工具的0.12版。
0.12版有1900多項變化和bug修正,其中主要包括:重寫了入門文檔(現在叫Rust Guide);繼續提高了包管理器Cargo等。
在2015年1月,發布了Rust-1.0.0-alpha版本。
2015年5月15日,Rust編程語言核心團隊正式宣布發布Rust 1.0版本。
2015年6月25日,Rust發布了1.1版本。同時發布1.2測試版本 編譯速度在1.1版本的基礎上再提升30% 並行編譯又能用了,默認未開啟,如果開啟,還能提升33%的編譯速度(數據來自4核編譯rustc) Cargo性能提升(編譯Servo時啟動速度提升10倍),可在多個package之間共享依賴包緩存 初步支持MSVC(Microsoft Visual C),以後Windows環境中不需要MinGW/MySYS/GCC了 Rust 1.2 穩定版 將在六周之後發布,屆時還將一並發布 1.3 測試版
4. 腐蝕RUST游戲指令和伺服器指令一覽
腐蝕 RUST游戲指令和伺服器指令一覽,在伺服器中,管理員也可以利用指令來管理游戲中不正當行為。下面就給大家帶來腐蝕RUST基本指令及伺服器指令大全,以供玩家們參考。
基本指令
(以下在聊天框內輸入)
/msg【message a specified player(私信一個玩家)】
/me【Puts your text into a purple color(你的 文字 將以紫色發出)】
(以下在控制台內輸入,按F1)
grass.on true/false 【Enables or disables grass; Improves FPS for some.(打開/關閉草地,可提高FPS)】
grass.displacement 【true/false Enables or disables grass displacements.(打開關閉草地 移動 )】
terrain.idleinterval 0-100 【Sets how often to draw unseen terrain; setting to 0 will disable.(遠景更新平率,0為不允許)】
gui.show 【Turns the UI on.(顯示用戶界面)】
gui.hide 【Turns the UI off.(關閉用戶界面)】
gui.show_branding 【Turns the branding UI in top-right corner on.(顯示右上角的標識)】
gui.hide_branding 【Turns the branding UI in top-right corner off.(隱藏右上角的標識)】
net.connect "Server IP" 【Connect to a direct server IP.(連接伺服器IP,Server IP出填寫伺服器的IP)】
net.disconnect 【Disconnects from a server.(斷開伺服器連接)】
net.reconnect 【Reconnect to the last server you were on.(重新連接上一個伺服器)】
censor.nudity false 【Disabled censorship.(關閉裸體)】
suicide 【Kills your character allowing for a respawn.(自殺)】
quit 【Quits the game.(退出遊戲)】
伺服器指令
rcon.login "password" 【Use your 'Password' to login into Rcon via ingame console (F1)。(使用控制台登錄伺服器)】
status 【See how many players are online on server.(查看在線玩家數量)】
notice.popupall "message" 【Pops up a message for all players.(發送伺服器公告,在每個玩家屏幕上彈出)】
find * 【Lists available console commands.(列出控制台指令)】
kick "player" 【Kicks player from the server.(踢出某個玩家)】
ban "player" or "steamid" 【Bans player. Doesn't kick him though.(封掉一個玩家)】
banid "steamid" "reason" 【Bans a steamid from the server.(封掉一個玩家的steamID,reason處可寫理由,掛狗和無(B)素(I)質(U)狗去死吧)】
unbanall 【Unbans all players.(解封所有玩家)】
truth.enforce true/false 【Server kicks people automatically when they are doing "weird" things.(伺服器自動踢出做奇怪事情的人,如卡BUG)】
save.all 【Saves world map and player inventory(伺服器保存當前地圖和玩家信息)。】
say [message] 【Sends a message to the person/s in-game globally.(以伺服器身份說話)】
inv.giveplayer "player" "item" "amount" 【Gives 'Player' the 'Item'. Full name and Item name required. List of Items.(給玩家東西,“玩家”“物品”“數量”)】
inv.giveall "item" "amount" 【Gives all players 'Item'. Full Item name required. List of Items.(給所有人東西,“玩家”“物品”“數量”,比如節日的時候,可以作為驚喜,沒人給一把槍什麼的)】
dmg.godmode true/false 【Gives all logged in admins godmode.(開啟/關閉所有人 創造 模式)】
crafting.cancel 【Cancels every single crafting job in progress for everyone.(取消製作任何東西)】
crafting.instant true/false 【Sets crafting to be instant for everyone.(開啟/關閉瞬間製作)】
crafting.instant_admins true/false 【Sets crafting to be instant for logged in admins only.(開啟/關閉管理員瞬間製作)】
crafting.timescale "amount" 【Sets the timescale of crafting to 'amount' (1 = default, 0.5 = half time)。(設置製作物品時間的速度,1為默認,0.5為一半時間)】
airdrop.drop 【Starts an airdrop.(進行一次物品空降)】
airdrop.min_players "amount" 【Starts airdrops only when minimum X players are online.(開始物品空降,當在線人數至少“X”人的時候)】
vehicle.spawn 【Spawns a car at your current position.( 放置 一輛車,在你當前位置,管理裝B專用)】
server.hostname 【Sets a hostname.(設置伺服器名稱)】
server.clienttimeout "time"【Sets the time until someone times out. Good to fight item glitchers. (Default 2 minutes)(設置超時時長,默認為2分鍾)】
server.pvp true/false 【Sets PVP on or off.(開啟PVP)】
server.maxplayers "amount" 【Sets maximum amount of server slots.(設置最大玩家數量)】
sleepers.on true/false 【Sets sleepers on or off.(是否允許睡眠模式)】
env.time "amount" 【Sets the time of day to a specified value.(設置天的時間)】
falldamage.enabled true/false 【Turns fall damage on or off.(開啟/關閉掉落傷害)】
RUST++ MOD
(以下在聊天框內輸入)
基本命令
/share playername 【shares your doors with a player(共享你的門給一個玩家)】
/unshare playername 【unshares your doors with a player(解除對一個玩家的門共享)】
/help 【Shows commands(顯示所有指令)】
/pm "playername" "message" 【private messages a player.(私聊一個玩家,名字必須寫全)】
/r message here 【quick reply to last PM(快速回復上一個私聊你的玩家)】
/history 【Shows chat history, last 6 messages by default(顯示前6個聊天內容)】
/players 【Shows online players(顯示當前在線玩家)】
/location 【Shows the coordinates of the player(顯示玩家的當前坐標)】
/ping 【shows latency between client and server(顯示伺服器的延遲)】
/starter 【gives a configurable starter kit(給予初始裝備)】
/friends 【shows your friends list(顯示朋友列表)】
/addfriend playername 【adds a player to your friends list(添加一個玩家為好友)】
/unfriend playername 【removes a friend(移除一個好友)】
/about 【shows server mod version(顯示伺服器版本)】
管理員命令
/announce message here 【ADMIN ONLY - announces a message to the server(發送伺服器公告)】
/loadout 【ADMIN ONLY - spawns you an admin loadout set in the config file(生成一個管理操作記錄在設置文件夾下)
RustEssentials MOD
(以下在聊天框內輸入)
/access {on} 【(Gives the sender access to all doors,給予你打開所有門的許可權)】
/access {off} 【(Revokes access to all doors from the sender,移除你打開所有門的許可權)】
/airdrop 【(Spawns an airdrop with a random drop location,設置一次隨地地點的空降)】
/airdrop【(Spawns an airdrop with a drop location at the specified player,設置一次空降給某個玩家)】
/ban【(Bans player with reason: "Banned by a(n)",封掉一個玩家)】
/ban[reason] 【(Bans player with reason,封掉一個玩家和願意)】
/chan {g} 【(Joins the global chat,加入全球聊天屏道)】
/chan {global} 【(Joins the global chat,同上)】
/chan {d} 【(Joins the direct chat,加入一個特定聊天屏道)】
/chan {direct} 【(Joins the direct chat,同上)】
/give【(Gives the item to that player,給一個玩家指定物品)】
/give[amount] 【(Gives the amount of the item to that player,給一個玩家指定物品和數量)】
/give[item id] 【(Gives 1 of the item with the corresponding id to that player,給一個玩家指定的物品,這里用的是物品ID)】
/give[item id] [amount] 【(Gives the amount of the item with the corresponding id to that player,給一個玩家指定的物品和數量,這里用的是物品ID)】
/god【(Gives the specified player god mode,給指定玩家上帝模式)】
/heal *player name* 【(Heals the designated player,恢復指定玩家的血)】
/help 【(Returns available commands for your current rank,顯示指令)】
/help [command without /] 【(Returns the documentation and syntax for the specified command,顯示已經排除外的指令,without/後面填上你不想顯示的指令)】
/history {1-50} 【(Returns the the last # lines of the chat history,查看聊天記錄,1-50裡面填你想查看前面多少條記錄)】
/i【(Gives the item to you,給自己指定物品)】
/i[amount] 【(Gives the amount of the item to you,給自己指定物品和數量)】
/i [item id] 【(Gives 1 of the item with the corresponding id to you,給自己指定物品,這里用的是物品ID)】
/i [item id] [amount] 【(Gives the amount of the item with the corresponding id to you,給自己指定物品和數量,這里用的是物品ID)
/join 【(Emulates the joining of yourself, 模擬 自己加入游戲)】
/join【(Emulates the joining of a fake player,加入一個機器人到游戲中)】
/kick【(Kick player with reason: "Kicked by a(n)",踢出一個玩家)】
/kick[reason] 【(Kick player with reason,踢出一個玩家和願意)】
/kickall 【(Kicks all users, except for the command executor, out of the server踢出所有玩家,除了輸入這條指令者)】
/kill【(Kills the specified player,殺死一個指定玩家)】
/kit [kit name] 【(Gives the user the specified kit if the user has the correct authority level,給一個用戶指定套裝,當這個玩家有指定的許可權的時候)
/kits 【(Lists the kits available to you,列出自己所有能用的套裝)】
/leave 【(Emulates the leaving of yourself,模擬自己離開游戲)】
/leave【(Emulates the leaving of a fake player,模擬一個機器人離開游戲)】
/mute【(Mutes the player on global chat,禁言一個玩家)】
/online 【(Returns the amount of players currently connected,顯示所有伺服器在線玩家)】
/pm*message* 【(Sends a private message to that player,私聊某個玩家)】
/pos 【(Returns the player's position,顯示玩家所在的坐標)
/reload {config/whitelist/ranks/commands/kits/motd/bans/all} 【(Reloads the specified file,重新載入指定的文件)】
/save 【(Saves all world data,保存世界數據)】
/say *message* 【(Says a message through the plugin,以伺服器身份說話,在公屏上)】
/saypop *message* 【(Says a (!) dropdown message to all clients,彈出一段話,在玩家屏幕上)】
/saypop [icon] *message* 【(Says a dropdown message to all clients with designated icon),以icon的什麼彈出一段話,在玩家屏幕上】
/share *player name* 【(Shares ownership of your doors with the designated user,共享門給指定玩家)】
/stop 【(Saves, deactivates, and effectively stops the server,停止伺服器並保存)】
/time 【(Returns current time of day,顯示當前世界時間)】
/time {0-24} 【(Sets time to a number between 0 and 24,設置當前世界時間)】
/time {day} 【(Sets time to day,設置為白天)】
/time {freeze} 【(Freezes time,凍住當前時間)】
/time {night} 【(Sets time to night,設置為晚上)】
/time {unfreeze} 【(Unfreezes time,解凍當前時間)】
/timescale 【(Returns the speed at which time passes,顯示當前時間流逝速度)】
/timescale [#] 【(Sets the speed at which time passes. Recommended between 0 and 1. WARNING: THIS AFFECTS AIRDROPS,設置時間流逝速度,在0和1之間,警告!這個將影響到空降時間)】
/uid 【(Returns your steam UID,顯示你的steamID)】
/uid *player name* 【(Returns that user's steam UID,顯示指定玩家的steamID)】
/unban【(Unbans the specified player,解封指定玩家)】
/ungod【(Revokes god mode from the specified player,解除指定玩家的上帝模式)】
/unmute【(Unmutes the player on global chat,解除指定玩家的禁言)】
/unshare {all} 【(Revokes ownership of your doors from everyone,解除對所有玩家的門共享)
/unshare *player name*【(Revokes ownership of your doors from the designated user,解除對指定玩家的門共享)
/version 【(Returns the current running version of Rust Essentials,重置Rust Essentials模組的版本)
/whitelist {add} [UID] 【(Adds the specified Steam UID to the whitelist,把指定steamID添加至白名單)】
/whitelist {check} 【(Checks if you're currently on the whitelist,查詢白名單)】
/whitelist {kick} 【(Kicks all players that are not whitelisted. This only work if whitelist is enabled,踢出所有在白名單的人,如果白名單已經啟動)】
/whitelist {off} 【(Turns whitelist off,關掉白名單)】
/whitelist {on} 【(Turns whitelist on,打開白名單)】
/whitelist {rem} [UID] 【(Removes the specified Steam UID to the whitelist,移除指定steamID從白名單)】
5. Java和Rust在實現多線程編程時的異同
Java的實現
打開Follower.java里的這個函數
這里的Follower.this.invitations就是我們的消息隊列,定義是:private LinkedList<Invitation> invitations;LinkedList不是線性安全的集合,需要我們加同步。具體的同步方法就是函數里寫的,通過Java常見的用wait,notify和notifyall給對象加鎖。
處理並發有wait、notify和notiyall,有興趣的朋友可以去這里了解一下:http://www.importnew.com/16453.html。Follower就是一個等待leader發送invitation,處理並返回結果的過程。
Leader.java
這么一段代碼:
裡面就是Leader發送邀請inv,並等待follower返回結果的大概邏輯,通過對消息體加鎖,是Java傳統的實現多線程並發的方式。還有消費者的消息隊列也會加鎖,在Java里,有個對象叫LinkedBlockingQueue,是不用加鎖就可以put和take的,但在例子里,我們選用了更簡單的LinkedList,也是為了表現一下加鎖的邏輯。
Rust的實現
Leader的結構為:
Follower的結構為:
對於其他語言轉過來的同學,這里的Vec,i32,bool都很好理解,不過裡面出現的Arc和Mutex,Sender,Receiver就是新東西了,上面這4個都是Rust標准庫的東西,也是這次分享要介紹的重點對象,是這4個東西共同實現了消息的生產,傳遞和消費。
下面簡單介紹一下分別是做什麼用的:
Arc<T>實現了sync介面。Sync介面是做什麼呢?權威資料是這么說的:當一個類型T實現了Sync,它向編譯器表明這個類型在多線程並發時沒有導致內存不安全的可能性。
如果看不懂不要緊,我們先看看實際中是怎麼用的:
在這個例子里,我們關注這幾句:
let data = Arc::new(Mutex::new(vec![1u32, 2, 3]));
let data = data.clone();
let mut data = data.lock().unwrap();
下面分別解釋一下是做什麼的:
簡單的說Arc::new表明了這是通過clone()方法來使用的,每clone,都會給該對象原子計數+1,通過引用計數的方法來保證對象只要還被其中任何一個線程引用就不會被釋放掉,從而保證了前面說的:這個類型在多線程並發時沒有導致內存不安全的可能性。
如果我們不定義為Arc<>就傳到其他線程使用,編譯器會報:
error: capture of moved value: `data`
data[i] += 1;
我們可以記住clone()就是Arc的用法。
接下來我們看Mutex:
Mutex實現了send介面。同樣,在權威資料里是這么描述的:這個類型的所有權可以在線程間安全的轉移
那我們又是怎麼用Mutex的呢?就是用lock().unwrap()。lock()的作用是獲取對象,如果當前有其他線程正在使用Mutex<T>裡面的T對象時,本線程就會阻塞,從而保證同時只有一個線程來訪問對象,mutex也另外提供了try_lock()的方法,是不阻塞的,只要其他線程被佔用,就返回err,通常Arc和Mutex都是一起使用的。
回到我最原始的題目,Mutex和Arc實現了對象本身的線程共享,但是在線程間如何傳遞這個對象呢?就是靠channel,channel通常是這么定義的let (tx, rx) = mpsc::channel();它會返回兩個對象tx和rx,就是之前我提到的sender和receiver。
在我的Rust實現里,關鍵的語句是以下幾個:
let leaders = (0..leader_cnt).map(|i|
Arc::new(Mutex::new(Leader::new(i,dance_types.len() as i32)))
).collect::<Vec<_>>();
這一句是new一堆leader出來,Arc和Mutex表明leader是可以多線程共享和訪問的。
同樣Follower也是:
let followers = (0..follower_cnt).map(|i|
Arc::new(Mutex::new(Follower::new(i,dance_types.len() as i32,leader_cnt)))
).collect::<Vec<_>>();
接下來這幾句就有點不好理解了。
這里定義了一堆的sender和receiver,其中把他們都作為leader和follower的成員變數存起來。大概意思就是每一個leader都通過sender列表可以發送invitation給所有follower,同時又有單個receiver來接受所有follower發給自己的處理結果inviresult。
同樣follower也是這么做。這樣在之後每一個follower和leader作為一個線程跑起來之後,都能在相互之間建立了一條通信的通道。
這個是和Java實現多線程並發最大的不同之處!Java是通過給對象加鎖,Rust是通過channel轉移對象的所有權,在代碼里,leader發送inv給folloer是下面這一句
match self.senders[*follower_id as usize].lock().unwrap().send(inv){,其中的lock().unwrap()是獲得該leader對該follower的發送通道的所有權,send(inv)就是轉移具體的發送對象invitation所有權了。
這個轉移按照我的理解,應該是內存拷貝。就是在follower接收的時候,let inv = match self.receiver.recv() { ,原來leader裡面的inv在send之後已經是不可訪問了,如果你之後再次訪問了inv,會報use of moved value錯誤,而follower裡面的inv則是在follower的棧里新生成的對象,所以,在Java裡面我只定義了invitation對象,但是在Rust裡面,我要再定義一個InviResult,因為我即使在follower線程裡面填了result欄位,leader線程也不能繼續訪問inv了。所以需要依靠follower再次發送一個invresult給leader,所以整個Rust程序大概就是這么一個思路。
實踐總結
之前我測試比較Java和Rust實現的性能時,由於沒有把調試信息去掉,導致Java比Rust慢很多,特別是那些調試信息都是調用String.format,這是比幾個string相加慢上10倍的方法,兩者都去掉調試信息後,leader和follower都會2000的時候,在我低端外星人筆記本里,性能差別大概是2倍吧,沒我想像中大,Rust的程序整個寫下來比較費力,一方面是對ownership機制不熟,思維沒有轉變過來,另一方面Rust的確需要開發者分部分精力到語法細節上。
編者註:馮總也有一些其它的實踐體會,請參見CSDN對馮耀明的專訪,請戳這里。也可以查看他的個人博客里的總結。
下面摘錄采訪中關於Rust的內容過來:
首先Rust裡面的ownership和lifetime概念真的很酷,就因為這個概念實現無內存泄露,野指針和安全並發。
其次,Rust的語法不簡單,也是有不少坑的,據說Rust的潛在用戶應該是現在的C和C++程序員,他們可能會覺得比較習慣,說不定還 覺得更簡單。由於ownership機制,一些在其他語言能夠跑通的程序在Rust下就要調整實現了,它會改變你寫程序的思維方式。據說一些寫Rust超 過半年的程序員已經愛上它了!
我對Rust感受較深的是下面幾點:
初學者不熟悉ownership機制,會無數次編譯失敗。但一旦編譯成功,那麼程序只剩下邏輯錯誤了。同樣,由於ownership機制,將來在項目里修改Rust代碼將可能是痛苦的過程,因為原來編譯通過的代碼可能加入新功能就編譯不過了,這是我的猜測。
Rust編譯速度慢,不過據說最近每一個Rust新發布的版本編譯速度都比之前的版本提高了30%。
Rust沒有類,有的是結構體加方法,我喜歡這種簡單的概念。
Rust沒有類繼承,只有介面,雖然介面可以提供默認的實現。這樣一來,在大型項目里原來類繼承來重用代碼的效果是否就要用成員變數實例來完成呢?
Rust沒有null,取而代之的是None和Option<T>,也因此,結構體在初始化的時候必須初始化所有欄位。
Rust有我一直很想要的錯誤值返回機制,而不必通過拋異常或者需要每每定義包含結果和錯誤體實現。
Rust用send和sync兩個介面來處理多線程並發,其中Arc<T>和Mutex<T>分別實現了這兩個介面,簡單易用。
Rust目前沒有一個強大的IDE,支持斷點調試,變數監控等。
它跟現在動態語言是兩個截然不同的方向,它適合一些資深的程序員,我倒是覺得有必要有這么一本書,叫《從C++到Rust,你需要改善的20個編程 習慣》,能從實踐上告訴開發者Rust里我們應該遵從什麼樣的編程習慣。Rust未來是否像C那樣流行開來成為新一代的主流語言沒有人能夠知道,但它絕對 是值得你去了解和關注的語言。
進一步的思考:反轉鏈表 - Java和Rust的不同實現
Rust的list應該怎麼定義,譬如反轉列表又是怎麼做呢?
由於ownership的機制和不存在空指針的情況,很多在其他帶GC的語言能夠跑起來的程序在Rust下面就要換一種做法。最近試用Rust的基礎數據結構時,更加加強了我的看法。下面以最原始的鏈表list為例。
在Java中,考慮最基本的鏈表定義
class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[");
sb.append(val);
ListNode pNext = this.next;
while (pNext != null) {
sb.append(",");
sb.append(pNext.val);
pNext = pNext.next;
}
sb.append("]");
return String.format("%s", sb.toString());
}
}
如果我們要反轉鏈表,可以這么做:
public ListNode reverseList(ListNode head) {
if (head == null) {
return null;
}
ListNode pNext = head.next;
ListNode pPrevious = null;
while (head != null) {
pNext = head.next;
head.next = pPrevious;
pPrevious = head;
head = pNext;
}
return pPrevious;
}
那如果我們按照一般思維,在Rust里對應的實現就是這樣子的:
struct ListNode{
id :i32,
next :Option<Box<ListNode>>
}
反轉鏈表:
fn reverseList2(head :&mut Option<Box<ListNode>>) -> Option<Box<ListNode>> {
match *head{
None => None,
Some(head) => {
let mut head = Some(head);
let mut pNext = head.unwrap().next;
let mut pPrevious:Option<Box<ListNode>> = None;
while true {
match head {
None =>{break;}
_ =>{}
}
pNext = head.unwrap().next;
head.unwrap().next = pPrevious;
pPrevious = head;
head = pNext;
}
pPrevious
}
}
}
然後編譯,報了以下錯誤:
=》match *head{
ERROR:cannot move out of borrowed content
=》 pNext = head.unwrap().next;
ERROR:cuse of moved value: `head`
這些錯誤就是因為Rust的ownership機制,讓我們無法像Java或者C++里保存臨時變數,特別是在循環里。反復試過各種寫法,都行不通。
最後,換成這么來做
鏈表定義:
use List::*;
enum List {
Cons1(i32, Box<List>),
Nil,
}
// Methods can be attached to an enum
impl List {
#[inline]
fn new() -> List {
Nil
}
#[inline]
fn prepend(self, elem: i32) -> List {
Cons1(elem, Box::new(self))
}
fn len(&self) -> i32 {
match *self {
Cons1(_, ref tail) => 1 + tail.len(),
Nil => 0
}
}
fn stringify(&self) -> String {
match *self {
Cons1(head, ref tail) => {
format!("{}, {}", head, tail.stringify())
},
Nil => {
format!("Nil")
},
}
}
}
fn reverseList(list:List, acc:List ) -> List{
match list{
Cons1(val,tail) => {
reverseList(*tail,acc.prepend(val))
}
Nil => acc
}
}
fn main() {
let mut head = List::new();
let mut i=0;
while i < 10 {
i+=1;
head = head.prepend(i);
}
println!("{:30}",head.stringify());
let result = List::new();
let result = reverseList(head,result);
<span style="white-space:pre"> </span>println!("{:30}",result.stringify());
}
從結果可以看到,鏈表已經實現反轉了。所以在Rust下面,很多做法都要換一下。有人說這就是Rust函數式編程的思維。我但願這種遞歸式的做法不會有溢出。