- Оригинальный адрес:A Simple Web App in Rust, Part 2b
- Оригинальный автор:Joel's Journal
- Перевод с:Программа перевода самородков
- Постоянная ссылка на эту статью:GitHub.com/rare earth/gold-no…
- Переводчик:LeopPro
Разработка простого веб-приложения на Rust, часть 2b
содержание
1 серия статей
В этой серии статей я задокументировал свой опыт разработки простого веб-приложения на Rust.
На данный момент у нас есть:
Предыдущий пост был отвратительным. На этот раз мы изучим форматы времени и даты Rust, сосредоточившись на записи времени в подходящем формате.
2 Использование Хроно
Поиск «дата» в crates.io дастпакет под названием хроно. Он горячий и часто обновляется, так что это выглядит как хороший кандидат. Из файла 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"
Далее в README говорится:
And put this in your crate root:
extern crate chrono;
Я не знаю, что это значит, но я попытаюсь вставить этоmain.rs
top, потому что это похоже на код 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, и он успешно компилируется и заканчивается. Думаю, следующим шагом будет попытка использовать его. По первому примеру в README хотелось бы так:
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» и печатаю правильно сформированное время, но трачу много времени на запись в файл. Я не знаю, что это значит. Хотя язык 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]
и&str
2Тип конфликт между, попробуем:
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 Заключение и следующие шаги
Ржавчина становится легче для меня. Теперь у меня есть работающий однофункциональный код, с которым можно работать, и я вполне уверен в разработке следующей части программы.
Когда я впервые планировал эту серию, моей следующей задачей было интегрировать код регистрации иnickel.rs
код, но пока, я думаю, это довольно просто. Я предполагаю, что следующей сложной частью будет выборпарсинг элемента.
—
Серия статей: Разработка простого веб-приложения на Rust
сноска:
1Очень разумно иметь много видов строк. Строки — это сложные объекты, которые трудно понять правильно. К сожалению, на первый взгляд строки настолько просты, что подобные вещи кажутся излишне сложными.
2Я тоже не знаю, о чем говорю. Все это теперь в пределах досягаемости.
Программа перевода самородковэто сообщество, которое переводит высококачественные технические статьи из Интернета сНаггетсДелитесь статьями на английском языке на . Охват контентаAndroid,iOS,внешний интерфейс,задняя часть,блокчейн,продукт,дизайн,искусственный интеллектЕсли вы хотите видеть более качественные переводы, пожалуйста, продолжайте обращать вниманиеПрограмма перевода самородков,официальный Вейбо,Знай колонку.