译文出自: 掘金翻译计划
本文永久链接: github.com/xitu/gold-m
译者: LeopPro
使用 Rust 开发一个简单的 Web 应用, 第 2b 部分
目录
在这个系列文章中, 我记录下了, 我在尝试使用 Rust 开发一个简单的 Web 应用过程中获得的经验
到目前为止, 我们有:
制定目标 & Hello World 级 Web 服务器
搞清楚如何写入文件
上一篇文章很恶心这次我们会探索 Rust 的时间日期格式, 重点是用一个合适的格式记录时间
2 使用 Chrono
在 crates.io 中搜索日期将得到一个名为 chrono 的包它热度很高, 更新频繁, 所以这看起来是一个好的候选方案 从 README 文件来看, 它有着很棒的的日期时间输出功能
第一件事情是在 Cargo.toml 中添加 Chrono 依赖, 但在此之前, 我们先把旧的 main.rs 移出, 腾出空间用于实验:
- $ ls
- Cargo.lock Cargo.toml log.txt src target
- $ cd src/
- $ ls
- main.rs web_main.rs
- $ git mv main.rs main_file_writing.rs
- $ touch main.rs
- $ git add main.rs
- $ git status
- On branch master
- Your branch is up-to-date with 'origin/master'.
- Changes to be committed:
- (use "git reset HEAD <file>..." to unstage)
- modified: main.rs
- copied: main.rs -> main_file_writing.rs
- Untracked files:
- (use "git add <file>..." to include in what will be committed)
- ../log.txt
- $ git commit -m 'move file writing out of the way for working with dates'
- [master 4cd2b0e] move file writing out of the way for working with dates
- 2 files changed, 16 deletions(-)
- rewrite src/main.rs (100%)
- copy src/{main.rs => main_file_writing.rs} (100%)
在 Cargo.toml 中添加 Chrono 依赖:
- [package]
- name = "simple-log"
- version = "0.1.0"
- authors = ["Joel McCracken <mccracken.joel@gmail.com>"]
- [dependencies]
- chrono = "0.2"
- [dependencies.nickel]
- git = "https://github.com/nickel-org/nickel.rs.git"
自述文件接着说:
- And put this in your crate root:
- extern crate chrono;
我不知道这是什么意思, 但我要尝试把它放到 main.rs 顶部, 因为它看起来像是 Rust 代码:
- extern crate chrono;
- fn main() {}
编译:
- $ cargo run
- Updating registry `https://github.com/rust-lang/crates.io-index`
- Downloading num v0.1.25
- Downloading rand v0.3.8
- Downloading chrono v0.2.14
- Compiling rand v0.3.8
- Compiling num v0.1.25
- Compiling chrono v0.2.14
- Compiling simple-log v0.1.0 (file:///Users/joel/Projects/simple-log)
- Running `/Users/joel/Projects/simple-log/target/debug/simple-log`
好了, 它似乎下载了 Chrono, 并且编译成功了结束了我想下一步就是尝试使用它根据自述文件第一个例子, 我想这样:
- extern crate chrono;
- use chrono: :*;
- fn main() {
- let local: DateTime < Local > =Local: :now();
- println ! ('{}', local);
- } = >$ cargo run Compiling simple - log v0.1.0(file: ///Users/joel/Projects/simple-log)
- main.rs: 6 : 14 : 6 : 16 error: unterminated character constant: '{
- main.rs:6 println!(' {}
- ', local);
- ^~
- Could not compile `simple-log`.
- To learn more, run the command again with --verbose.'
? 我愣了几秒后, 我意识到它是告诉我, 我应该使用双引号, 而不是单引号这是有道理的, 单引号被用于生命周期规范
从单引号切换到双引号之后:
- $ cargo run
- Compiling simple-log v0.1.0 (file:///Users/joel/Projects/simple-log)
- Running `/Users/joel/Projects/simple-log/target/debug/simple-log`
- 2015-06-05 16:54:47.483088 -04:00
哇偶, 这真简单看起来 println! 可以调用某种接口以打印各种不同的东西
这很讽刺我很轻松就构建一个简单的 Hello World 级 Web 应用并且打印了一个格式良好的时间, 但我在写入文件上花费了很多时间我不知道这意味着什么尽管 Rust 语言很难用 (对我来说), 但是我相信 Rust 社区已经做了许多努力使系统包工作良好
3 将日期时间写入文件
我认为, 下一步我们应该将这个字符串写入文件为此, 我想看看上一篇文章的结尾:
- $ cat main_file_writing.rs use std: :io: :prelude: :*;
- use std: :fs: :File;
- use std: :io;
- fn log_something(filename: &'static str, string: &'static[u8; 12]) - >io: :Result < () > {
- let mut f =
- try ! (File: :create(filename));
- try ! (f.write_all(string));
- Ok(())
- }
- fn main() {
- match log_something("log.txt", b "ITS ALIVE!!!") {
- Ok(..) = >println ! ("File created!"),
- Err(..) = >println ! ("Error: could not create file.")
- }
- }
我只是将上面那个例子和这个合并到一起:
- extern crate chrono;
- use std: :io: :prelude: :*;
- use std: :fs: :File;
- use std: :io;
- use chrono: :*;
- fn log_something(filename: &'static str, string: &'static[u8; 12]) - >io: :Result < () > {
- let mut f =
- try ! (File: :create(filename));
- try ! (f.write_all(string));
- Ok(())
- }
- fn main() {
- let local: DateTime < Local > =Local: :now();
- println ! ('{}', local);
- match log_something("log.txt", b "ITS ALIVE!!!") {
- Ok(..) = >println ! ("File created!"),
- Err(..) = >println ! ("Error: could not create file.")
- }
- }
编译:
- $ ls
- Cargo.lock Cargo.toml log.txt src target
- $ pwd
- /Users/joel/Projects/simple-log
- $ ls
- Cargo.lock Cargo.toml log.txt src target
- $ rm log.txt
- $ cargo run
- Compiling simple-log v0.1.0 (file:///Users/joel/Projects/simple-log)
- Running `target/debug/simple-log`
- 2015-06-05 17:08:57.814176 -04:00
- File created!
- $ cat log.txt
- ITS ALIVE!!!$
它工作了! 和语言作斗争真有意思, 很顺利地把两个东西放在一起
4 构建时间记录器
我们离写一个真正的完整的最终系统越来越近我突然想起, 我可以为这个代码写一些测试, 但是不急, 一会再说
以下是这个函数应该做的事情:
给定一个文件名,
如果它不存在则创建它, 然后打开这个文件
创建一个时间日期字符串,
将这个字符串写入文件, 然后关闭这个文件
4.1 对 u8 的误解
我的第一次尝试:
- extern crate chrono;
- use std: :io: :prelude: :*;
- use std: :fs: :File;
- use std: :io;
- use chrono: :*;
- fn log_time(filename: &'static str) -> io::Result<()> {
- let local: DateTime<Local> = Local::now();
- let time_str = local.format("%Y").to_string();
- let mut f = try!(File::create(filename));
- try!(f.write_all(time_str));
- Ok(())
- }
- fn main() {
- match log_time("log.txt") {
- Ok(..) => println!("File created!"),
- Err(..) => println!("Error: could not create file.")
- }
- }'
- =>
- $ cargo run
- Compiling simple-log v0.1.0 (file:///Users/joel/Projects/simple-log)
- src/main.rs:13:22: 13:30 error: mismatched types:
- expected `&[u8]`,
- found `collections::string::String`
- (expected &-ptr,
- found struct `collections::string::String`) [E0308]
- src/main.rs:13 try!(f.write_all(time_str));
- ^~~~~~~~
- <std macros>:1:1: 6:48 note: in expansion of try!
- src/main.rs:13:5: 13:33 note: expansion site
- error: aborting due to previous error
- Could not compile `simple-log`.
- To learn more, run the command again with --verbose.
我知道 Rust 中有很多字符串类型 1, 看起来这里我需要另一种类型我不知道怎么下手, 所以我只能搜索一番
我记得在 Rust 文档的某一部分中特别提到了字符串查一查, 它说, 可以使用 & 符号实现从 String 到 &str 的转换我感觉这不是我们需要的, 因为它应该是 [u8] 与 &str2 之间的类型冲突, 让我们试试:
- extern crate chrono;
- use std: :io: :prelude: :*;
- use std: :fs: :File;
- use std: :io;
- use chrono: :*;
- fn log_time(filename: &'static str) -> io::Result<()> {
- let local: DateTime<Local> = Local::now();
- let time_str = local.format("%Y").to_string();
- let mut f = try!(File::create(filename));
- try!(f.write_all(&time_str));
- Ok(())
- }
- fn main() {
- match log_time("log.txt") {
- Ok(..) => println!("File created!"),
- Err(..) => println!("Error: could not create file.")
- }
- }'
- =>
- $ cargo run
- Compiling simple-log v0.1.0 (file:///Users/joel/Projects/simple-log)
- src/main.rs:13:22: 13:31 error: mismatched types:
- expected `&[u8]`,
- found `&collections::string::String`
- (expected slice,
- found struct `collections::string::String`) [E0308]
- src/main.rs:13 try!(f.write_all(&time_str));
- ^~~~~~~~~
- <std macros>:1:1: 6:48 note: in expansion of try!
- src/main.rs:13:5: 13:34 note: expansion site
- error: aborting due to previous error
- Could not compile `simple-log`.
- To learn more, run the command again with --verbose.
好吧, 显然, 添加 & 符号只能从 String 转换到 &String 这似乎与 Rust 文档中所说的直相矛盾, 但也可能是我不知道发生了什么事情
而且我刚刚读了字符串的章节的末尾据我所知, 这里没有任何东西
我离开了一段时间去忙别的事情 (家长里短, 你懂), 当我走的时候, 我恍然大悟在此之前, 我一直以为 u8 是 UTF-8 的缩写, 但是现在我仔细想想, 它肯定是无符号 8 位整数的意思而且我记得我看见过 as_bytes 方法, 所以, 我们试一下:
- extern crate chrono;
- use std: :io: :prelude: :*;
- use std: :fs: :File;
- use std: :io;
- use chrono: :*;
- fn log_time(filename: &'static str) -> io::Result<()> {
- let local: DateTime<Local> = Local::now();
- let bytes = local.format("%Y").to_string().as_bytes();
- let mut f = try!(File::create(filename));
- try!(f.write_all(bytes));
- Ok(())
- }
- fn main() {
- match log_time("log.txt") {
- Ok(..) => println!("File created!"),
- Err(..) => println!("Error: could not create file.")
- }
- }'
- =>
- $ cargo run
- Compiling simple-log v0.1.0 (file:///Users/joel/Projects/simple-log)
- main.rs:10:17: 10:47 error: borrowed value does not live long enough
- main.rs:10 let bytes = local.format("%Y").to_string().as_bytes();
- ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- main.rs:10:59: 14:2 note: reference must be valid for the block suffix following statement 1 at 10:
- 58...
- main.rs:10 let bytes = local.format("%Y").to_string().as_bytes();
- main.rs:11 let mut f = try!(File::create(filename));
- main.rs:12 try!(f.write_all(bytes));
- main.rs:13 Ok(())
- main.rs:14 }
- main.rs:10:5: 10:59 note: ...but borrowed value is only valid for the statement at 10:4
- main.rs:10 let bytes = local.format("%Y").to_string().as_bytes();
- ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- main.rs:10:5: 10:59 help: consider using a `let` binding to increase its lifetime
- main.rs:10 let bytes = local.format("%Y").to_string().as_bytes();
- ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- error: aborting due to previous error
- Could not compile `simple-log`.
- To learn more, run the command again with --verbose.
好吧, 我希望事情有所进展这个错误是否意味着我修正了一些东西, 而还有一些其他的错误掩盖了这个问题? 我是不是遇到了一个全新的问题?
奇怪的是错误信息集中体现在同一行上我并不是很明白, 但我觉得它是想告诉我, 我需要添加一个赋值语句在方法中我们试一下:
- fn log_time(filename: &'static str) -> io::Result<()> {
- let local: DateTime<Local> = Local::now();
- let formatted = local.format("%Y").to_string();
- let bytes = formatted.as_bytes();
- let mut f = try!(File::create(filename));
- try!(f.write_all(bytes));
- Ok(())
- }'
- =>
- $ cargo run
- Compiling simple-log v0.1.0 (file:///Users/joel/Projects/simple-log)
- Running `target/debug/simple-log`
- File created!
- $ cat log.txt
- 2015$
太棒了! 我们想要的都在这了在我继续之前, 我想吐槽一下, 我有一点失望没有我的提示, Rust 也应该可以通过上下文推断正确的行为
测试脚本:
- $ ls
- Cargo.lock Cargo.toml log.txt src target
- $ rm log.txt
- $ cargo run
- Running `target/debug/simple-log`
- File created!
- $ cat log.txt
- 2015$ cargo run
- Running `target/debug/simple-log`
- File created!
- $ cat log.txt
- 2015$
4.2 查缺补漏
一些问题:
没有另起一行, 这忍不了
格式需要一些处理
新的日期会覆盖旧的
Let's verify #3 by fixing the format. If the time changes between runs, then we will know that's what is happening.
DateTime 中的 format 方法使用标准 strftime 格式公约理想情况下, 我希望时间看起来像是这样的:
- Sat, Jun 6 2015 05:32:00 PM
- Sun, Jun 7 2015 08:35:00 AM
等等这可读性应该是足够的, 供我使用查阅文档后, 我想出了这个:
- extern crate chrono;
- use std: :io: :prelude: :*;
- use std: :fs: :File;
- use std: :io;
- use chrono: :*;
- fn log_time(filename: &'static str) -> io::Result<()> {
- let local: DateTime<Local> = Local::now();
- let formatted = local.format("%a, %b %d %Y %I:%M:%S %p\n").to_string();
- let bytes = formatted.as_bytes();
- let mut f = try!(File::create(filename));
- try!(f.write_all(bytes));
- Ok(())
- }
- fn main() {
- match log_time("log.txt") {
- Ok(..) => println!("File created!"),
- Err(..) => println!("Error: could not create file.")
- }
- }'
测试:
- $ rm log.txt
- $ cargo run
- Running `target/debug/simple-log`
- File created!
- $ cat log.txt
- Sun, Jun 07 2015 06:37:21 PM
- $ sleep 5; cargo run
- Running `target/debug/simple-log`
- File created!
- $ cat log.txt
- Sun, Jun 07 2015 06:37:41 PM
显然, 程序覆盖我想要的日志项我记得 File::create 的文档中指出了这里发生的事所以, 为了正确处理文件我需要再次查阅文档
我进行了一些搜索, 基本上找到答案都是无关紧要的随后, 我找到了 std::path::Path 的文档, 其中有一个 exists 模式
此时, 我的程序中的类型转换变得越来越难以管理我感到紧张, 所以继续之前, 我要提交一次
我想把对时间实体字符串的处理逻辑从 log_time 函数中抽取出来, 因为时间的创建与格式化显然与文件操作代码不同所以, 我做了如下尝试:
- extern crate chrono;
- use std: :io: :prelude: :*;
- use std: :fs: :File;
- use std: :io;
- use chrono: :*;
- fn log_time_entry() - >String {
- let local: DateTime < Local > =Local: :now();
- let formatted = local.format("%a, %b %d %Y %I:%M:%S %p\n").to_string();
- formatted
- }
- fn log_time(filename: &'static str) -> io::Result<()> {
- let bytes = log_time_entry().as_bytes();
- let mut f = try!(File::create(filename));
- try!(f.write_all(bytes));
- Ok(())
- }
- fn main() {
- match log_time("log.txt") {
- Ok(..) => println!("File created!"),
- Err(..) => println!("Error: could not create file.")
- }
- }'
- =>
- $ cargo run
- Compiling simple-log v0.1.0 (file:///Users/joel/Projects/simple-log)
- src/main.rs:16:17: 16:33 error: borrowed value does not live long enough
- src/main.rs:16 let bytes = log_time_entry().as_bytes();
- ^~~~~~~~~~~~~~~~
- src/main.rs:16:45: 20:2 note: reference must be valid for the block suffix following statement 0 at
- 16:44...
- src/main.rs:16 let bytes = log_time_entry().as_bytes();
- src/main.rs:17 let mut f = try!(File::create(filename));
- src/main.rs:18 try!(f.write_all(bytes));
- src/main.rs:19 Ok(())
- src/main.rs:20 }
- src/main.rs:16:5: 16:45 note: ...but borrowed value is only valid for the statement at 16:4
- src/main.rs:16 let bytes = log_time_entry().as_bytes();
- ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- src/main.rs:16:5: 16:45 help: consider using a `let` binding to increase its lifetime
- src/main.rs:16 let bytes = log_time_entry().as_bytes();
- ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- error: aborting due to previous error
- Could not compile `simple-log`.
- To learn more, run the command again with --verbose.
好吧, 这看起来就像我以前遇到的问题是不是假借或持有要求函数拥有明确的资源引用? 这似乎有一点奇怪我再次尝试修复它:
- extern crate chrono;
- use std: :io: :prelude: :*;
- use std: :fs: :File;
- use std: :io;
- use chrono: :*;
- fn formatted_time_entry() - >String {
- let local: DateTime < Local > =Local: :now();
- let formatted = local.format("%a, %b %d %Y %I:%M:%S %p\n").to_string();
- formatted
- }
- fn log_time(filename: &'static str) -> io::Result<()> {
- let entry = formatted_time_entry();
- let bytes = entry.as_bytes();
- let mut f = try!(File::create(filename));
- try!(f.write_all(bytes));
- Ok(())
- }
- fn main() {
- match log_time("log.txt") {
- Ok(..) => println!("File created!"),
- Err(..) => println!("Error: could not create file.")
- }
- }'
- =>
- $ cargo run
- Compiling simple-log v0.1.0 (file:///Users/joel/Projects/simple-log)
- Running `target/debug/simple-log`
- File created!
所以, 看起来添加一个明确的引用解决了问题不管怎样, 这个规则还蛮简单
下面, 我要将文件操作代码抽取至它自己的函数:
- extern crate chrono;
- use std: :io: :prelude: :*;
- use std: :fs: :File;
- use std: :io;
- use chrono: :*;
- fn formatted_time_entry() - >String {
- let local: DateTime < Local > =Local: :now();
- let formatted = local.format("%a, %b %d %Y %I:%M:%S %p\n").to_string();
- formatted
- }
- fn record_entry_in_log(filename: &str, bytes: &[u8]) - >io: :Result < () > {
- let mut f =
- try ! (File: :create(filename));
- try ! (f.write_all(bytes));
- Ok(())
- }
- fn log_time(filename: &'static str) -> io::Result<()> {
- let entry = formatted_time_entry();
- let bytes = entry.as_bytes();
- try!(record_entry_in_log(filename, &bytes));
- Ok(())
- }
- fn main() {
- match log_time("log.txt") {
- Ok(..) => println!("File created!"),
- Err(..) => println!("Error: could not create file.")
- }
- }'
它正常工作我犯了一些一开始的错误, 但它们很快被纠正了这里已经是修改后的代码
查阅文档中的 std::fs::File, 我注意到文档对 std::fs::OpenOptions 的介绍, 这正是我一直在寻找的这肯定比使用 std::path 更好
我的第一次尝试:
- extern crate chrono;
- use std: :io: :prelude: :*;
- use std: :fs: :{
- File,
- OpenOptions
- };
- use std: :io;
- use chrono: :{
- DateTime,
- Local
- };
- fn formatted_time_entry() - >String {
- let local: DateTime < Local > =Local: :now();
- let formatted = local.format("%a, %b %d %Y %I:%M:%S %p\n").to_string();
- formatted
- }
- fn record_entry_in_log(filename: &str, bytes: &[u8]) - >io: :Result < () > {
- let mut file =
- try ! (OpenOptions: :new().append(true).create(true).open(filename));
- try ! (file.write_all(bytes));
- Ok(())
- }
- fn log_time(filename: &'static str) -> io::Result<()> {
- let entry = formatted_time_entry();
- let bytes = entry.as_bytes();
- try!(record_entry_in_log(filename, &bytes));
- Ok(())
- }
- fn main() {
- match log_time("log.txt") {
- Ok(..) => println!("File created!"),
- Err(..) => println!("Error: could not create file.")
- }
- }
- =>
- $ cargo run
- Compiling simple-log v0.1.0 (file:///Users/joel/Projects/simple-log)
- src/main.rs:4:15: 4:19 warning: unused import, #[warn(unused_imports)] on by default
- src/main.rs:4 use std::fs::{File,OpenOptions};
- ^~~~
- Running `target/debug/simple-log`
- Error: could not create file.'
有趣其实它成功创建文件了哦, 我注意错误提示是我硬编码到 main 的信息我认为这样它将工作:
- extern crate chrono;
- use std: :io: :prelude: :*;
- use std: :fs: :{
- File,
- OpenOptions
- };
- use std: :io;
- use chrono: :{
- DateTime,
- Local
- };
- fn formatted_time_entry() - >String {
- let local: DateTime < Local > =Local: :now();
- let formatted = local.format("%a, %b %d %Y %I:%M:%S %p\n").to_string();
- formatted
- }
- fn record_entry_in_log(filename: &str, bytes: &[u8]) - >io: :Result < () > {
- let mut file =
- try ! (OpenOptions: :new().append(true).create(true).open(filename));
- try ! (file.write_all(bytes));
- Ok(())
- }
- fn log_time(filename: &'static str) -> io::Result<()> {
- let entry = formatted_time_entry();
- let bytes = entry.as_bytes();
- try!(record_entry_in_log(filename, &bytes));
- Ok(())
- }
- fn main() {
- match log_time("log.txt") {
- Ok(..) => println!("File created!"),
- Err(e) => println!("Error: {}", e)
- }
- }
- =>
- $ cargo run
- Compiling simple-log v0.1.0 (file:///Users/joel/Projects/simple-log)
- src/main.rs:4:15: 4:19 warning: unused import, #[warn(unused_imports)] on by default
- src/main.rs:4 use std::fs::{File,OpenOptions};
- ^~~~
- Running `target/debug/simple-log`
- Error: Bad file descriptor (os error 9)'
奇怪搜索非法的文件描述错误信息似乎表明, 被使用的文件描述已经被关闭了如果我注释掉 file.write_all 调用, 将会发生什么呢?
- $ rm log.txt
- $ cargo run
- Compiling simple-log v0.1.0 (file:///Users/joel/Projects/simple-log)
- src/main.rs:3:5: 3:25 warning: unused import, #[warn(unused_imports)] on by default
- src/main.rs:3 use std::io::prelude::*;
- ^~~~~~~~~~~~~~~~~~~~
- src/main.rs:4:15: 4:19 warning: unused import, #[warn(unused_imports)] on by default
- src/main.rs:4 use std::fs::{File,OpenOptions};
- ^~~~
- src/main.rs:15:40: 15:45 warning: unused variable: `bytes`, #[warn(unused_variables)] on by default
- src/main.rs:15 fn record_entry_in_log(filename: &str, bytes: &[u8]) -> io::Result<()> {
- ^~~~~
- src/main.rs:16:9: 16:17 warning: unused variable: `file`, #[warn(unused_variables)] on by default
- src/main.rs:16 let mut file = try!(OpenOptions::new().
- ^~~~~~~~
- src/main.rs:16:9: 16:17 warning: variable does not need to be mutable, #[warn(unused_mut)] on by de
- fault
- src/main.rs:16 let mut file = try!(OpenOptions::new().
- ^~~~~~~~
- Running `target/debug/simple-log`
- File created!
- $ ls
- Cargo.lock Cargo.toml log.txt src target
不出所料, 有一堆未使用的警告信息, 但是无他, 文件的确被创建了
这似乎有点傻, 但我尝试向函数调用链中添加 .write(true) 后, 它工作了语义上 .append(true) 就意味着 .write(true), 但我想规定上不是这样的
搞定了这个, 它工作了! 最终版本:
- extern crate chrono;
- use std: :io: :prelude: :*;
- use std: :fs: :{
- File,
- OpenOptions
- };
- use std: :io;
- use chrono: :{
- DateTime,
- Local
- };
- fn formatted_time_entry() - >String {
- let local: DateTime < Local > =Local: :now();
- let formatted = local.format("%a, %b %d %Y %I:%M:%S %p\n").to_string();
- formatted
- }
- fn record_entry_in_log(filename: &str, bytes: &[u8]) - >io: :Result < () > {
- let mut file =
- try ! (OpenOptions: :new().append(true).write(true).create(true).open(filename));
- try ! (file.write_all(bytes));
- Ok(())
- }
- fn log_time(filename: &'static str) -> io::Result<()> {
- let entry = formatted_time_entry();
- let bytes = entry.as_bytes();
- try!(record_entry_in_log(filename, &bytes));
- Ok(())
- }
- fn main() {
- match log_time("log.txt") {
- Ok(..) => println!("File created!"),
- Err(e) => println!("Error: {}", e)
- }
- }'
- =>
- $ ls
- Cargo.lock Cargo.toml src target
- $ cargo run
- Running `target/debug/simple-log`
- File created!
- $ cargo run
- Running `target/debug/simple-log`
- File created!
- $ cat log.txt
- Sun, Jun 07 2015 10:40:01 PM
- Sun, Jun 07 2015 10:40:05 PM
5 结论 & 后续步骤
Rust 对我来说越来越容易了我现在有一些有效的单功能的代码可以使用, 我对下一部分程序的开发感到相当有信心
当我首次规划这个系列的时候, 我计划下一个任务是整合日志代码和 nickel.rs 代码, 但是现在, 我认为这是非常简单的我猜测, 下一个有挑战的部分将是处理选项解析
系列文章: 使用 Rust 开发一个简单的 Web 应用
- Part 1
- Part 2a
- Part 2b
Part 3(正在翻译)
Part 4(正在翻译)
Conclusion
脚注:
1 有很多种类的字符串是非常合理的事情字符串是一个复杂的实体, 很难得到正确的表达不幸的是, 乍一看字符串非常简单, 这种事情似乎没必要复杂
2 我也不知道我在说什么这些就是现在所能企及的
掘金翻译计划 是一个翻译优质互联网技术文章的社区, 文章来源为 掘金 上的英文分享文章内容覆盖 AndroidiOS 前端后端区块链产品设计人工智能等领域, 想要查看更多优质译文请持续关注 掘金翻译计划官方微博知乎专栏
来源: https://juejin.im/post/5a8196716fb9a0635c0478d7