-
chevron_right
Ржавый стыд
nerdfella · Wednesday, 22 April, 2020 - 18:33 · 3 minutes
Друзьяшечки, я учу Rust, и пока пишу на нём такую дичь, что аж стыдно и противно.
Сейчас кодить не могу, но могу сделать обзор своего же кода. Программка состоит из двух файлов как в 12 главе Rust Book'а. main.rs только запускает функцию run из lib.rs. А вот сам lib.rs:
1> extern crate yaml_rust;
2>
3> use yaml_rust::{YamlLoader, YamlEmitter};
4> use yaml_rust::yaml::Yaml;
5> use std::fs::File;
6> use std::io::prelude::*;
7> use std::collections::HashMap;
8> use std::error::Error;
9>
10> pub struct Config {
11> pub layout: String,
12> pub corpus: String,
13> }
14>
15> impl Config {
16> pub fn new(args: &[String]) -> Result<Config, &'static str> {
17> if args.len() > 1 {
18> return Err("Too many arguments.");
19> }
20>
21> let layout = String::from("layout.yaml");
22> let corpus = String::from("corpus.yaml");
23>
24> Ok(Config {layout, corpus})
25> }
26> }
27>
28> struct Layout(HashMap<String, HashMap<String, String>>);
29>
30> impl Layout {
31> fn from_yaml(yaml: &Yaml) -> Layout {
32> let mut layout: HashMap<String, HashMap<String, String>> = HashMap::new();
33> for (lang, keys) in yaml.as_hash().unwrap() {
34> let mut hash: HashMap<String, String> = HashMap::new();
35> for (key, chord) in keys.as_hash().unwrap() {
36> hash.insert(key.as_str().unwrap().to_string(),
37> chord.as_str().unwrap().to_string());
38> }
39> layout.insert(lang.as_str().unwrap().to_string(), hash);
40> }
41> Layout(layout)
42> }
43>
44> fn score(layout: Layout, corpus: Corpus) -> Result<f64, Box<dyn Error>> {
45> let mut summ = 0.0;
46> summ = summ + 1.0;
47> Ok(summ)
48> }
49> }
50>
51> struct Corpus(HashMap<String, HashMap<String, f64>>);
52>
53> impl Corpus {
54> fn from_yaml(yaml: &Yaml) -> Corpus {
55> let mut corpus: HashMap<String, HashMap<String, f64>> = HashMap::new();
56> for (lang, pairs) in yaml.as_hash().unwrap() {
57> let mut hash: HashMap<String, f64> = HashMap::new();
58> for (pair, weight) in pairs.as_hash().unwrap() {
59> hash.insert(pair.as_str().unwrap().to_string(),
60> weight.as_f64().unwrap());
61> }
62> corpus.insert(lang.as_str().unwrap().to_string(), hash);
63> }
64> Corpus(corpus)
65> }
66> }
67>
68> pub fn run(config: Config) -> Result<(), Box<dyn Error>> {
69> let mut file = File::open(config.layout).expect("Unable to open file");
70> let mut contents = String::new();
71> file.read_to_string(&mut contents)
72> .expect("Unable to read file");
73>
74> let layout_yaml = &YamlLoader::load_from_str(&contents).unwrap()[0];
75> let layout = Layout::from_yaml(layout_yaml);
76> Ok(())
77> }
78>
Начну с начальца.
1> extern crate yaml_rust;
Я не знаю что делает эта строка. То ли надо Rust Book перечитывать, то ли я ещё не дошёл до объяснения этой конструкции. Я пока прочитал только первые 12 глав.
3> use yaml_rust::{YamlLoader, YamlEmitter};
Надо, конечно, убрать YamlEmitter, я им пока не пользуюсь.
3> use yaml_rust::{YamlLoader, YamlEmitter};
4> use yaml_rust::yaml::Yaml;
5> use std::fs::File;
6> use std::io::prelude::*;
7> use std::collections::HashMap;
8> use std::error::Error;
В каком порядке принято это всё писать? Зачем нужны пространства std::io и std::fs, в чём разница?
10> pub struct Config {
11> pub layout: String,
12> pub corpus: String,
13> }
Надо повторить разницу между String и &str. Ко всем остальным употреблениям String это тоже относится.
28> struct Layout(HashMap<String, HashMap<String, String>>);
Хотел определить новый тип для хранения раскладки. На stackoverflow ещё был вариант с trait'ами. Не понимаю как это работает и как этим пользоваться. Идём дальше.
31> fn from_yaml(yaml: &Yaml) -> Layout {
32> let mut layout: HashMap<String, HashMap<String, String>> = HashMap::new();
33> for (lang, keys) in yaml.as_hash().unwrap() {
34> let mut hash: HashMap<String, String> = HashMap::new();
35> for (key, chord) in keys.as_hash().unwrap() {
36> hash.insert(key.as_str().unwrap().to_string(),
37> chord.as_str().unwrap().to_string());
38> }
39> layout.insert(lang.as_str().unwrap().to_string(), hash);
40> }
41> Layout(layout)
42> }
Это что за жесть? Почему так многословно? И это при том, что я использовал unwrap(), а не полноценный pattern matching. И я в HashMap преобразую даже не файл, а уже переменную типа Yaml. Ниже ещё несколько строчек с чтением файла, тоже уродливых.
И да, в похожей функции для Corpus'а я использую f64, потому что Yaml выдаёт только f64. Мне такая высокая точность не нужна, но как преобразовать в f32 я не знаю.
Если у вас есть какие-то комментарии или ответы на мои вопросы, то я с удовольствием вас послушаю.