- Оригинальный адрес:A Simple Web App in Rust, Part 1
- Оригинальный автор:Joel's Journal
- Перевод с:Программа перевода самородков
- Постоянная ссылка на эту статью:GitHub.com/rare earth/gold-no…
- Переводчик:LeopPro
- Корректор:pthtc hippyk
Разработка простого веб-приложения на Rust, часть 1
1 Введение и предыстория
С точки зрения опытного разработчика, плохо знакомого с экосистемой, каково это — разрабатывать небольшое веб-приложение на Rust? Читать дальше.
Я заинтересовался ржавчиной, когда я впервые услышал об этом. Язык уровня системы, который поддерживает макросы и имеет место для роста в терминах абстракций высокого уровня. Потрясающий!
До сих пор я только взорвал ржавчину и сделал очень простой «Hello World» программы уровня. Итак, я думаю, мое мнение обязано нагреть.
Не так давно я увидел эту статью об изучении Racket.эта статья, я чувствую себя очень хорошо. Нам нужно больше людей, чтобы поделиться своим опытом в качестве технических новичков, особенно тех, кто уже имеет значительный технический опыт.[1]. Мне также очень нравится его подход к «потоку мыслей». Я думаю, что написание учебника по Rust, подобного этому, должно быть очень хорошей попыткой.
Ладно, предисловие закончилось, приступим!
2 приложения
Приложение, которое я хочу создать, удовлетворяет моему простому требованию: записывать время, которое я ежедневно принимаю бездумно. Я думаю, что я нажимаю на ссылку на главном экране, чтобы записать посещение, и это будет сохранено как запись о том, когда я принимаю лекарство.
Rust кажется подходящим для этого приложения. Это быстро, особенно меньше запускать простое потребление ресурсов сервера, поэтому это не нагрузка на мой VPS. Я также хотел бы сделать некоторые более практичные вещи с Rust.
MVP довольно маленький, но у него есть место для роста, если я захочу добавить больше функций. Звучит превосходно!
3 плана
Я должен признать одну вещь: я потерял раннюю версию этого проекта, которая имеет следующие недостатки: Когда я воспроизводю ее, я не чувствую себя так странно, как когда я только прикоснулся к ней несколько недель назад. Тем не менее, я думаю, что до сих пор помню, что делало меня несчастным в то время, и я попытаюсь воспроизвести эти трудности.
Я знаю, что здесь нужно сказать правду: одной отдельной программе гораздо проще использовать существующие API, чем пытаться выполнить всю работу самостоятельно.
Для достижения этого у меня есть следующий план:
- Создайте простой веб-сервер, который отображает «Hello World» на экране, когда я его посещаю.
- Создайте небольшую программу, которая записывает текущее время в формате при каждом запуске.
- Объедините два вышеуказанных в одну программу.
- Разверните это приложение на моем VPS Digital Ocean.
4. Написание веб-приложения «Hello World»
Итак, я собираюсь создать новый репозиторий Git и установить homebrew. По крайней мере, я знаю, что мне нужно сначала установить Rust.
4.1 Установите Руст
$ brew update
...
$ brew install rust
==> Downloading https://homebrew.bintray.com/bottles/rust-1.0.0.yosemite.bottle.tar.gz
############################################################ 100.0%
==> Pouring rust-1.0.0.yosemite.bottle.tar.gz
==> Caveats
Bash completion has been installed to:
/usr/local/etc/bash_completion.d
zsh completion has been installed to:
/usr/local/share/zsh/site-functions
==> Summary
/usr/local/Cellar/rust/1.0.0: 13947 files, 353M
Хорошо, прежде чем мы начнем, давайте напишем обычную программу «Hello World».
$ cat > hello_world.rs
fn main() {
println!("hello world");
}
^D
$ rustc hello_world.rs
$ ./hello_world
hello world
$
Все идет нормально. Rust работает, или, по крайней мере, работает компилятор Rust.
Друг предложил мне попробовать использоватьnickle.rs, который представляет собой фреймворк веб-приложений для Rust. Я хорошо себя чувствую.
На сегодняшний день его первый пример:
#[macro_use] extern crate nickel;
use nickel::Nickel;
fn main() {
let mut server = Nickel::new();
server.utilize(router! {
get "**" => |_req, _res| {
"Hello world!"
}
});
server.listen("127.0.0.1:6767");
}
В первый раз, когда я делал их, я немного отвлекся и пошел немного изучать Cargo. На этот раз я заметил этоРуководство по началу работы, так что я собираюсь следовать за ним, вместо того, чтобы натыкаться на все самостоятельно.
Вот скрипт, который я должен передатьcurl
Скачайте и запустите с root-правами. Но "страдая обсессивно-компульсивным расстройством" я планирую сначала скачать сценарий и проверить его.
curl -LO https://static.rust-lang.org/rustup.sh
Хорошо, на самом деле это не то, что я ожидал, этот скрипт делает много работы, большую часть которой я не хочу делать сам прямо сейчас. И я хотел бы знать,cargo
использовать лиrustc
установить?
$ which cargo
/usr/local/bin/cargo
$ cargo -v
Rust 包管理器
用法:
cargo <命令> [<参数>...]
cargo [选项]
选项:
-h, --help 显示帮助信息
-V, --version 显示版本信息并退出
--list 安装命令列表
-v, --verbose 使用详细的输出
常见的 cargo 命令:
build 编译当前工程
clean 删除目标目录
doc 编译此工程及其依赖项文档
new 创建一个新的 cargo 工程
run 编译并执行 src/main.rs
test 运行测试
bench 运行基准测试
update 更新 Cargo.lock 中的依赖项
search 搜索注册过的 crates
执行 'cargo help <command>' 获取指定命令的更多帮助信息。
Хорошо, я думаю, это выглядит хорошо, верно? Я начну использовать его сейчас.
$ rm rustup.sh
4.2 Проект настройки
Следующим шагом будет создание нового каталога проекта, но он у меня уже есть. В любом случае, я все равно собираюсь попробовать.
$ cargo new . --bin
目标 `/Users/joel/Projects/simplelog/.` 已经存在
Хм... не работает.
$ cargo -h
在 <路径> 处创建一个新的 Cargo 包。
用法:
cargo new [选项] <路径>
cargo new -h | --help
选项:
-h, --help 显示帮助信息
--vcs <vcs> 为指定的版本管理系统(git 或 hg)
初始化一个新仓库
或者不使用版本管理系统(none)
--bin 创建可执行文件工程而不是库工程
--name <name> 设置结果包名
-v, --verbose 使用详细的输出
В первой строке приведенного выше кода
cargo -h
Должно быть, это опечатка автора, но это так.cargo new -h
. (Примечание переводчика)
Хм, похоже, не работает, как я ожидал, мне нужно восстановить репозиторий.
$ cd ../
$ rm -rf simplelog/
$ cargo new simple-log --bin
$ cd simple-log/
Хорошо, давайте посмотрим, что здесь?
$ tree
.
|____.git
| |____config
| |____description
| |____HEAD
| |____hooks
| | |____README.sample
| |____info
| | |____exclude
| |____objects
| | |____info
| | |____pack
| |____refs
| | |____heads
| | |____tags
|____.gitignore
|____Cargo.toml
|____src
| |____main.rs
Смотрите, он создает репозиторий Git,Cargo.toml
файл и вsrc
в каталогеmain.rs
файл, выглядит нормально.
Согласно руководству Никеля по началу работы, яCargo.toml
добавить в файлnickel.rs
Зависимость, теперь она выглядит так:
[package]
name = "simple-log"
version = "0.1.0"
authors = ["Joel McCracken <mccracken.joel@gmail.com>"]
[dependencies.nickel]
git = "https://github.com/nickel-org/nickel.rs.git"
Мне это легко понять. Однако я не уверенdependencies.nickel
действительныйзначениечто.dependencies
это сnickel
хэш ключа? Но, конечно же, мы привнесли в проект никель, и это здорово!
4.3 Запуск примера «Hello World»
Кого это волнует, я скопировал этот пример вmain.rs
середина:
#[macro_use] extern crate nickel;
use nickel::Nickel;
fn main() {
let mut server = Nickel::new();
server.utilize(router! {
get "**" => |_req, _res| {
"Hello world!"
}
});
server.listen("127.0.0.1:6767");
}
Какие?macro_use
,extern
кто они такие? зачем использоватьuse
? Я отвечу на эти вопросы один за другим ниже.
Вот у меня есть несколько вопросов,macro_use
похоже на макрос[2], но я не увидел вызова макроса, поэтому удалил его. Но теперь я заметилrouter!
, поэтому я предпочитаю, чтобы это был макрос. Между тем, я подозреваю, что с помощью指令
Уместен ли этот термин для обозначения, так что не будьте слишком уверены.
Давай попробуем:
cargo run
Updating git repository `https://github.com/nickel-org/nickel.rs.git`
Updating registry `https://github.com/rust-lang/crates.io-index`
Downloading unsafe-any v0.4.1
Downloading httparse v0.1.2
Downloading traitobject v0.0.3
Downloading lazy_static v0.1.10
Downloading pkg-config v0.3.4
Downloading num_cpus v0.2.5
Downloading modifier v0.1.0
Downloading groupable v0.2.0
Downloading unicase v0.1.0
Downloading gcc v0.3.5
Downloading time v0.1.25
Downloading log v0.3.1
Downloading url v0.2.34
Downloading plugin v0.2.6
Downloading hyper v0.4.0
Downloading matches v0.1.2
Downloading mustache v0.6.1
Downloading bitflags v0.1.1
Downloading typeable v0.1.1
Downloading openssl v0.6.2
Downloading rustc-serialize v0.3.14
Downloading typemap v0.3.2
Downloading regex v0.1.30
Downloading cookie v0.1.20
Downloading mime v0.0.11
Downloading libc v0.1.8
Downloading openssl-sys v0.6.2
Compiling modifier v0.1.0
Compiling traitobject v0.0.3
Compiling regex v0.1.30
Compiling libc v0.1.8
Compiling lazy_static v0.1.10
Compiling matches v0.1.2
Compiling httparse v0.1.2
Compiling rustc-serialize v0.3.14
Compiling groupable v0.2.0
Compiling pkg-config v0.3.4
Compiling gcc v0.3.5
Compiling bitflags v0.1.1
Compiling unicase v0.1.0
Compiling typeable v0.1.1
Compiling unsafe-any v0.4.1
Compiling log v0.3.1
Compiling num_cpus v0.2.5
Compiling typemap v0.3.2
Compiling mime v0.0.11
Compiling plugin v0.2.6
Compiling openssl-sys v0.6.2
Compiling time v0.1.25
Compiling openssl v0.6.2
Compiling url v0.2.34
Compiling mustache v0.6.1
Compiling cookie v0.1.20
Compiling hyper v0.4.0
Compiling nickel v0.5.0 (https://github.com/nickel-org/nickel.rs.git#69546f58)
Compiling simple-log v0.1.0 (file:///Users/joel/Projects/simple-log)
Running `target/debug/simple-log`
Listening on http://127.0.0.1:6767
Ctrl-C to shutdown server
^C
О ху! в моем браузереlocalhost:6767
Визит удался!
4.4 Последнее испытание
Хорошо, теперь я хочу попробовать одну вещь и объявить об этом сегодня вечером: могу ли я переместить «Hello World» в отдельную функцию? В конце концов, мы сейчас находимся в стадии малыша.
fn say_hello() {
"Hello dear world!";
}
fn main() {
let mut server = Nickel::new();
server.utilize(router! {
get "**" => |_req, _res| {
say_hello();
}
});
server.listen("127.0.0.1:6767");
}
Ошибка... Когда я запускаю этот раз, я вижу "Не найдено". На этот раз избавимся от точки с запятой, на всякий случай:
fn say_hello() {
"Hello dear world!"
}
fn main() {
let mut server = Nickel::new();
server.utilize(router! {
get "**" => |_req, _res| {
say_hello()
}
});
server.listen("127.0.0.1:6767");
}
Ну... теперь компилятор выдает другое сообщение об ошибке:
$ cargo run
Compiling simple-log v0.1.0 (file:///Users/joel/Projects/simple-log)
src/main.rs:6:5: 6:24 错误:不匹配的类型:
预期 `()`,
找到 `&'static str`
(预期 (),
找到 &-ptr) [E0308]
src/main.rs:6 "Hello dear world!"
^~~~~~~~~~~~~~~~~~~
错误:由于先前的错误而中止
不能编译 `simple-log`。
想查看更多信息,请加上 --verbose 重新运行命令。
Судя по сообщению об ошибке, япредполагатьВажно наличие или отсутствие точки с запятой. Теперь это вызывает ошибку типа. О, я на 90% уверен, что это здесь()
Относится к «юниту», который является пустым, неопределенным или неопределенным в Rust. Я знаю, что это не совсем правильно, но я думаю, что это имеет смысл.
яПредположениеRust делает вывод типов. Разве компилятор этого не делает? Или это не делается только вблизи границ функций? В порядке……
Сообщение об ошибке говорит мне, что компилятор ожидает, что возвращаемое значение функции будет «единицей», но возвращаемое значение на самом деле является статической строкой (что это?). Я видел синтаксис возвращаемых функцией значений, давайте посмотрим:
#[macro_use] extern crate nickel;
use nickel::Nickel;
fn say_hello() -> &'static str {
"Hello dear world!"
}
fn main() {
let mut server = Nickel::new();
server.utilize(router! {
get "**" => |_req, _res| {
say_hello()
}
});
server.listen("127.0.0.1:6767");
}
на мой взгляд&'static str
Тип очень странный. Будет ли он успешно скомпилирован? Будет ли это работать нормально?
$ cargo run &
[1] 14997
Running `target/debug/simple-log`
Listening on http://127.0.0.1:6767
Ctrl-C to shutdown server
$ curl http://localhost:6767
Hello dear world!
$ fg
cargo run
^C
Ура, сработало! На этот раз Раст не разочаровал. Я не знаю, потому ли это, что я лучше знаком с инструментами, или я решил прочитать больше документации, но мне весело.читатьязык иПисатьРазличия между языками поразительны. Хотя я понимаю примеры кода, я все еще не могу их эффективно редактировать.
—
В следующей главе мы завершим процесс записи файлов в текущую дату. ты сможешьздесьпрочитайте это.
—
Серия статей: Разработка простого веб-приложения на Rust
сноска:
[1] Я не хочу сказать, что опыт новичка бесполезен — это далеко не так! Я думаю, что новички часто приносят какие-то уникальные инсайты по сравнению с бывалыми, и они могут заметить, что что-то в экосистеме нестандартно.
[2] Обычно я говорю директивы времени компиляции, но это не имеет особого смысла для компилируемого языка, такого как Rust. Поэтому я не знаю, как это выразить, кроме как макросами.
Программа перевода самородковэто сообщество, которое переводит высококачественные технические статьи из Интернета сНаггетсДелитесь статьями на английском языке на . Охват контентаAndroid,iOS,внешний интерфейс,задняя часть,блокчейн,продукт,дизайн,искусственный интеллектЕсли вы хотите видеть более качественные переводы, пожалуйста, продолжайте обращать вниманиеПрограмма перевода самородков,официальный Вейбо,Знай колонку.