成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Golang和Rust語言常見功能/庫

開發 后端
本文我們介紹了Golang和Rust中常用的功能包括命令行參數解析、錯誤處理、日志、Json處理和Web庫

時下最流行、最具發展前途的的兩門語言是Golang和Rust。Golang語言簡潔、高效、并發、并且有個強大的囊括了常見功能標準庫。與之相對比,Rust語言則主要是安全、高性能。雖然Rust沒有golang那種"內置電池(Batteries included)"的標準庫,但是Rust的第三方庫(crate,板條箱)極大補充了Rust精煉基本庫的功能。本文我們就介紹一下Golang和Rust常用的庫功能。

Golang和Rust語言常見功能/庫

參數處理

Golang標準庫中提供了功能。flag庫是非常基礎的功能,在實踐上也非常有用,在做命令行交互程序時候必不可少。

  1. package main 
  2. import "flag" 
  3. var ( 
  4. program = flag.String("p", "", "h program to compile/run") 
  5. outFname = flag.String("o", "", "if specified, write the webassembly binary created by -p here") 
  6. watFname = flag.String("o-wat", "", "if specified, write the uncompiled webassembly created by -p here") 
  7. port = flag.String("port", "", "HTTP port to listen on") 
  8. writeTao = flag.Bool("koan", false, "if true, print the h koan and then exit") 
  9. writeVersion = flag.Bool("v", false, "if true, print the version of h and then exit") 

上述代碼會生成一些程序包全局變量,其中將包含命令行參數的值。

在Rust中,常用的命令行解析包是structopt。但是,其工作方式與Golang flag程序包有所不同。structopt會選項加載到結構中,而非全局可變變量。主要因為Rust語言編程實踐中,基本上都會避免全局可變的變量。在大多數情況下,帶有包的全局變量flag是可以的,但前提是必須在程序真正開始執行其需要做的工作之前將它們寫入到程序中。

一個簡單示例源自于pahi庫源碼:

  1. #[derive(Debug, StructOpt)] 
  2. #[structopt( 
  3. name = "pa'i"
  4. about = "A WebAssembly runtime in Rust meeting the Olin ABI." 
  5. )] 
  6. struct Opt { 
  7. #[structopt(short, long, default_value = "cranelift")] 
  8. backend: String, 
  9. #[structopt(short, long)] 
  10. function_log: bool, 
  11. #[structopt(short, long)] 
  12. no_cache: bool, 
  13. #[structopt()] 
  14. fname: String, 
  15. #[structopt(short, long, default_value = "_start")] 
  16. entrypoint: String, 
  17. #[structopt()] 
  18. args: Vec<String>

Rust編譯器會生成所需的參數解析代碼,然后可以使用:

  1. fn main() { 
  2. let opt = Opt::from_args(); 
  3. debug!("args: {:?}", opt.args); 
  4. if opt.backend != "cranelift" { 
  5.         return Err(format!( 
  6.             "wanted backend to be cranelift, got: {}", 
  7.             opt.backend 
  8.         )); 

錯誤處理

Golang的標準庫具有error接口,可以創建一個描述類型的函數,函數描述為什么功能無法按預期執行,Golang程序必須先做好錯誤處理。比如:

  1. func Write(w io.Writer, buf []byte) error { 
  2. _, err :w.Write(buf) 
  3. if err != nil { 
  4. log.Println("unable to write:", err) 
  5. return err 
  6. return nil 

Rust也具有Error 特性,它使還可以創建一個描述函數為何無法實現其預期功能的類型。這兒我們介紹更加易用的thiserror板條箱構建自定義錯誤類型:

  1. [dependencies] 
  2. thiserror = "1" 

然后,在程序中使用:

  1. use std::fmt; 
  2. use thiserror::Error; 
  3. #[derive(Debug, Error)] 
  4. struct Divide0​; 
  5. impl fmt::Display for Divide0​ { 
  6. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 
  7. write!(f, "不能被零整除!") 

日志記錄

Go標準庫中也自帶了log庫。該庫是一個非常有爭議的記錄器,它的日志記錄缺乏日志記錄級別和上下文感知值之類的功能。

  1. package main 
  2. import ( 
  3. "log" 
  4. func init() { 
  5. log.SetPrefix("TRACE: ") 
  6. log.SetFlags(log.Ldate | log.Lmicroseconds | log.Llongfile) 
  1. func main() { 
  2. log.Println("message") 
  3. log.Fatalln("fatal message") 
  4. log.Panicln("panic message") 
  1. ------------------------------- 
  2. TRACE: 2020/09/09 14:24:32.868375 TestLog.go:15: message 
  3. TRACE: 2020/09/09 14:24:32.962329 TestLog.go:18: fatal message 
  4. Process finished with exit code 1 

在Rust中,有一個板條箱,這是一個非常簡單的包,它使用error!,warn!,info!,debug!和trace!宏分別關聯到最高和最低日志打印水平。同樣要使用log板條箱,先要增加的項目中,即添加到Cargo.toml的依賴部分。

  1. [dependencies] 
  2. log = "0.4" 

然后,就可以使用了:

  1. use log::{error, warn, info, debug, trace}; 
  2. fn main() { 
  3. trace!("starting main"); 
  4. debug!("debug message"); 
  5. info!("this is some information"); 
  6. warn!("oh no something bad is about to happen"); 
  7. error!("oh no it's an error"); 

注意,默認該庫日志記錄是不會記錄到本地文件中的。要記錄日志還需要其他庫。

pretty_env_logger是和log買一送一,最常搭配使用的板條箱。同樣,先添加項目依賴:

  1. [dependencies] 
  2. log = "0.4" 
  3. pretty_env_logger = "0.4" 

然后,在代碼中使用:

  1. use log::{error, warn, info, debug, trace}; 
  2. fn main() { 
  3. pretty_env_logger::init(); 
  4. trace!("這是一個示例程序。"); 
  5. debug!("調試信息xxx。"); 
  6. info!("程序正在運行中。"); 
  7. warn!("[WARN]程序有些參數配置有問題。"); 
  8. error!("[ERROR]程序發生嚴重錯誤!"); 

然后在啟動時候增加,日志級別參數RUST_LOG=trace 運行:

  1. env RUST_LOG=trace cargo run 
  2.   
  3. Compiling errex v0.1.0 (/home/lz/test/rust/commoncrate/errex) 
  4.     Finished dev [unoptimized + debuginfo] target(s) in 1.32s 
  5.      Running `target/debug/errex` 
  6.  TRACE errex > 這是一個示例程序。 
  7.  DEBUG errex > 調試信息xxx。 
  8.  INFO  errex > 程序正在運行中。 
  9.  WARN  errex > [WARN]程序有些參數配置有問題。 
  10.  ERROR errex > [ERROR]程序發生嚴重錯誤! 
Golang和Rust語言常見功能/庫

序列化/反序列化

Golang在標準庫內置了 包用來實現JSON編碼/解碼功能。我們可以定義可以輕松讀取和寫入JSON的類型。下面一個例子:

  1. "id": 3137, 
  2. "author": { 
  3. "id": 420, 
  4. "name": "Chongchong" 
  5. }, 
  6. "body": "Hello,This is Chongchong web!", 
  7. "in_reply_to": 3135 

在Golang中,可以生成如下的結構體:

  1. type Author struct { 
  2. ID int `json:"id"` 
  3. Name string `json:"name"` 
  1. type Comment struct { 
  2. ID int `json:"id"` 
  3. Author Author `json:"author"` 
  4. Body string `json:"body"` 
  5. InReplyTo int `json:"in_reply_to"` 

Rust沒有開箱即用的功能,需要使用第三方板條箱,最常用的一個庫是serde,可以跨JSON和能想到的所有其他序列化方法使用。

  1. [dependencies] 
  2. serde = { version = "1"features = ["derive"] } 
  3. serde_json = "1" 

注意,上面serde的依賴配置,和其他包有差異。

Golang的JSON包通過使用struct標簽作為元數據來工作,但是Rust沒有,需要改用Rust的衍生功能。

因此,要將serde用于的注釋類型:

  1. use serde::{Deserialize, Serialize}; 
  2. #[derive(Clone, Debug, Deserialize, Serialize)] 
  3. pub struct Author { 
  4. pub id: i32, 
  5. pub name: String, 
  6. #[derive(Clone, Debug, Deserialize, Serialize)] 
  7. pub struct Comment { 
  8. pub id: i32, 
  9. pub author: Author, 
  10. pub body: String, 
  11. pub in_reply_to: i32, 

然后,使用以下代碼解析Json:

  1. fn main() { 
  2. let data = r#" 
  3. "id": 3137, 
  4. "author": { 
  5. "id": 420, 
  6. "name": "Chongchong" 
  7. }, 
  8. "body": "Hello,This is Chongchong web!", 
  9. "in_reply_to": 3135 
  10. "#; 
  11. let c: Comment = serde_json::from_str(data).expect("json to parse"); 
  12. println!("comment: {:#?}", c); 

cargo run

  1. ... 
  2. Finished dev [unoptimized + debuginfo] target(s) in 0.04s 
  3.      Running `target/debug/serdeex` 
  4. comment: Comment { 
  5.     id: 3137, 
  6.     author: Author { 
  7.         id: 420, 
  8.         name: "Chongchong", 
  9.     }, 
  10.     body: "Hello,This is Chongchong web!", 
  11.     in_reply_to: 3135, 
Golang和Rust語言常見功能/庫

Web開發

在Web開發中HTTP包必不可少的。Golang中可使用net/http充當生產級HTTP客戶端和服務器。

  1. import ( 
  2. "net/http" 
  3. "fmt" 
  4. "log" 
  5.  
  6. func sayhelloGolang(w http.ResponseWriter, r *http.Request) { 
  7. r.ParseForm() 
  8. fmt.Println("path", r.URL.Path) 
  9. w.Write([]byte("Hello Chongchong!")) 
  10.  
  11. func main() { 
  12. http.HandleFunc("/",hello) 
  13. err :http.ListenAndServe(":8080", nil) 
  14. if err != nil { 
  15. log.Fatal("ListenAndServe: ", err) 

它可以讓我們非常輕松地進行Web開發。Rust標準庫沒有開箱即用的HTTP功能,但是Web的框架也非常豐富。

客戶端

對于HTTP客戶端,可以使用。它還可以與serde無縫集成,以允許從HTTP解析JSON:

  1. [dependencies] 
  2. reqwest = { version = "0.10"features = ["json"] } 
  3. tokio = { version = "0.2"features = ["full"] } 

tokio默認情況下Rust不附帶異步運行時,tokio大約等同于Golang運行時幫助處理的大多數重要事項。簡單實例如下:

Golang和Rust語言常見功能/庫

運行此命令:

  1. cargo run  
  2. ... 
  3. Finished dev [unoptimized + debuginfo] target(s) in 3.31s 
  4.      Running `target/debug/webcer` 
  5. Status: 200 OK 
  6. Body: 
  7. <!doctype html> 
  8. <html> 
  9.   <head> 
  10.     <meta charset="utf-8"> 
  11. <meta http-equiv="X-UA-Compatible" content="chrome=1"> 
  12. <title>hyper.rs | hyper</title> 
  13. <meta name="description" content=""> 
Golang和Rust語言常見功能/庫

結合其他功能,reqwest可以做作為一個功能強大的HTTP客戶端。

服務器端

至于HTTP服務器,可以使用warp板條箱。warp是一個建立在Rust的類型系統之上的HTTP服務器框架。

  1. [dependencies] 
  2. tokio = { version = "0.2"features = ["macros"] } 
  3. warp = "0.2" 

讓我們寫個簡單的"Hello,Chongchong"示例:

  1. use warp::Filter; 
  2. #[tokio::main] 
  3. async fn main() { 
  4. // GET /hello/Chongchong=> 200 OK with body "Hello, Chongchong!" 
  5. let hello = warp::path!("hello" / String) 
  6. .map(|name| format!("Hello, {}!", name)); 
  7. warp::serve(hello) 
  8. .run(([127, 0, 0, 1], 3030)) 
  9. .await; 

然后通過127.0.0.1:3030/hello/Chongchong,就可以提示Hello, Chongchong!。

對 warp應用可以使用其or模式構建多條Web路由:

  1. let hello = warp::path!("hello" / String) 
  2. .map(|name| format!("Hello, {}!", name)); 
  3. let health = warp::path!(".within" / "health") 
  4. .map(|| "OK"); 
  5. let routes = hello.or(health); 

還可通過過濾器將其他數據類型注入到處理程序中:

  1. let fact = { 
  2. let facts = pfacts::make(); 
  3. warp::any().map(move || facts.clone()) 
  4. }; 
  5. let fact_handler = warp::get() 
  6. .and(warp::path("fact")) 
  7. .and(fact.clone()) 
  8. .and_then(give_fact); 

warp是功能強大的HTTP服務器,可以跨生產級Web應用程序所需的所有內容工作。

模版

Web開發中要常用模版來特定化頁面的輸出。Golang的標準庫還包括HTML和純文本模板包html/template和text/template。在Rust中有很多用于HTML模板化的解決方案,比如ructe板條箱。ructe使用Cargo的build.rs功能在編譯時為其模板生成Rust代碼。這樣就可以將HTML模板編譯成結果應用程序二進制文件,從而以驚人的速度呈現它們。

添加Cargo.toml:

  1. [build-dependencies] 
  2. ructe = { version = "0.12"features = ["warp02"] } 
  3. 還依賴mime板條箱: 
  1. [dependencies] 
  2. mime = "0.3.0" 

完成此操作后,templates在當前工作目錄中創建一個新文件夾。創建一個名為的文件hello.rs.html,并將以下內容放入其中:

  1. @(title: String, message: String) 
  2. <html> 
  3. <head> 
  4. <title>@title</title> 
  5. </head> 
  6. <body> 
  7. <h1>@title</h1> 
  8. <p>@message</p> 
  9. </body> 
  10. </html> 

然后使用模板templates.rs:

  1. use warp::{http::Response, Filter, Rejection, Reply}; 
  2. async fn hello_html(message: String) -> Result<impl Reply, Rejection> { 
  3. Response::builder() 
  4. .html(|o| templates::index_html(o, "Hello".to_string(), message).unwrap().clone())) 

在src/main.rs底部,通過以下語句引入模版定義:

  1. include!(concat!(env!("OUT_DIR"), "/templates.rs")); 

在main()函數中調用:

  1. let hello_html_rt = warp::path!("hello" / "html" / String) 
  2. .and_then(hello_html); 
  3. let routes = hello_html_rt.or(health).or(hello); 

總結

本文我們介紹了Golang和Rust中常用的功能包括命令行參數解析、錯誤處理、日志、Json處理和Web庫,我們可以發現基本上這些功能都在Golang標準庫中都提供了,而Rust則要引入額外的板條箱,但是借助強大的Cargo包管理工具,其使用也非常便捷。

 

責任編輯:趙寧寧 來源: 今日頭條
相關推薦

2020-10-21 14:54:02

RustGolang開發

2020-07-15 08:00:52

Rust語言技巧

2022-06-22 10:04:29

JavaScriptRust語言

2024-06-19 10:31:48

2021-12-27 03:36:09

語言For Golang

2021-11-14 23:05:28

GoCast語言

2017-12-04 14:13:24

物聯網ITOT

2021-05-07 15:28:03

Kafka客戶端Sarama

2021-01-29 08:56:13

Golang標準庫函數

2023-11-30 11:39:52

Rust生態框架

2022-05-17 12:23:25

排序算法面試

2015-11-25 10:43:03

DGORust

2023-10-26 12:01:30

Golang字符串

2023-02-22 16:47:09

編程語言RustGolang

2022-03-25 11:01:28

Golang裝飾模式Go 語言

2021-09-13 05:02:49

GogRPC語言

2020-07-07 07:00:00

RustGo語言編程語言

2021-03-23 14:50:16

編程語言Rust漏洞

2022-02-07 23:07:19

Golang語言Modules

2021-06-09 23:36:46

Golang語言版本
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 一级一级一级毛片 | 国产精品无码久久久久 | 国产精品日韩欧美一区二区三区 | 五月婷婷丁香婷婷 | 91久久久久久| 国产精品资源在线观看 | 毛片一级电影 | 亚洲视频在线观看 | 亚洲三区在线观看 | 日韩精品一区二区在线观看 | 亚洲天堂中文字幕 | 国产成人精品一区二区三 | 69堂永久69tangcom | 精品久久久久久久久久久久 | 日韩免费高清视频 | 日韩在线中文 | 91国产视频在线观看 | 福利视频一区 | 免费视频一区二区三区在线观看 | 日韩精品免费播放 | 国产精品不卡一区 | 国产高清在线视频 | 国产精品一区二区不卡 | 欧美国产日韩在线 | 99精品视频在线 | 免费在线a视频 | av毛片| 婷婷丁香激情 | 国产精品久久久久av | 天天天操操操 | 亚洲精品国产成人 | 精品视频免费 | 精品亚洲视频在线 | 免费黄色a级毛片 | 日韩三区在线观看 | 精品视频在线观看 | 日韩国产精品一区二区三区 | 国产欧美一区二区三区日本久久久 | 久久黄色网 | 亚洲www啪成人一区二区 | 亚洲综合二区 |