rust - 如何使用堆引用惯用地构造结构?

标签 rust

所以我目前对初始化 struct 感到困惑通过加载 Yaml文件到堆内存中:

extern crate yaml_rust;

use std::io::prelude::*;
use std::fs;
use yaml_rust::{Yaml, YamlLoader};

struct Petrovich {
    middlename: Yaml,
    firstname: Yaml,
    lastname: Yaml
}

impl  Petrovich {

    fn new() -> Petrovich {

        // Open Rules File (Panics on error)
        let mut f = fs::File::open("./src/rules.yml").unwrap();
        // Create String Buffer and Read to it
        let mut buffer = String::new();
        f.read_to_string(&mut buffer).unwrap();
        // Pass Buffer to Yaml and unwrap
        let rules: &Yaml = &YamlLoader::load_from_str(&buffer).unwrap()[0];

        // Return Petrovich with preloaded rules
        Petrovich { 
            middlename: rules["middlename"],
            firstname: rules["firstname"],
            lastname: rules["lastname"]
        }
    }
}

但是我得到一个cannot move out of indexed content错误。我该如何解决这个问题?

编辑:我正在使用 yaml-rust为此,有一个文件 rules.ymlfirstname , lastnamemiddlename ./src 中包含的字段

可以在这里找到源代码:https://github.com/Latrasis/petrovich-rs

最佳答案

您正试图移出一个借用的指针(因为 rules[str] 返回一个 &Yaml ),但这是不合法的。我们需要使用允许我们将值移出主 Yaml 的函数目的。这将改变主要的 Yaml对象,但在这里没关系,因为我们将在函数结束时丢弃它。

首先,我们需要了解字符串索引的作用。 The implementation如果该值是哈希值并通过构造 Yaml::String 获取基础值,则仅返回重要值索引散列的值。

Yaml::Hash变体包装了一个 BTreeMap<Yaml, Yaml> .图书馆提供 as_hash方便的方法来访问它,但这只给出了一个不可变的指针。我们需要使用模式匹配来获取可变指针。

接下来,我们将使用 remove methodBTreeMap 上提取与我们感兴趣的键关联的值。

结果如下:

impl Petrovich {
    fn new() -> Petrovich {
        use yaml_rust::yaml::Hash as YamlHash;

        // Open Rules File (Panics on error)
        let mut f = fs::File::open("./src/rules.yml").unwrap();
        // Create String Buffer and Read to it
        let mut buffer = String::new();
        f.read_to_string(&mut buffer).unwrap();
        // Pass Buffer to Yaml and unwrap
        let rules: &mut Yaml = &mut YamlLoader::load_from_str(&buffer).unwrap()[0];
        let rules: &mut YamlHash = match *rules {
            Yaml::Hash(ref mut hash) => hash,
            _ => panic!("not a hash"),
        };

        // Return Petrovich with preloaded rules
        Petrovich {
            middlename: rules.remove(&Yaml::String("middlename".into())).unwrap(),
            firstname: rules.remove(&Yaml::String("firstname".into())).unwrap(),
            lastname: rules.remove(&Yaml::String("lastname".into())).unwrap(),
        }
    }
}

请注意,在您的原始代码(如果它有效)不会出现的情况下,此代码会出现困惑,因为您会得到 BadValue。相反。我会留给您根据需要处理错误。

关于rust - 如何使用堆引用惯用地构造结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35169985/

相关文章:

multithreading - Rayon 中的每线程初始化

rust - <T : Trait> Box<T> and &Trait/Box<Trait>? 有什么区别

stream - 我如何每 N 秒从无界队列中提取消息并将它们生成到 Tokio 处理程序?

rust - 如何为引用自身但不改变自身的迭代器的关联类型指定生命周期?

rust - 语法: 'let secretbox::Key(ref mut kb) = k;' 的解释

rust - 如何在 Rust 中获取向量中的最小值?

linker - Rust 无法将绑定(bind)链接到 C 库

rust - 如何等待第一个k future ?

pointers - 在 Rust 中返回指针时发生了什么?

rust - 如何在 Vector 上为我自己的结构实现 PartialEq?