62、IndexMut trait(可变索引trait)

Mutable indexing

 

Index允许只读访问。它不允许我们更改检索到的值。

 

IndexMut

 

如果我们想要支持可变性,那我们就需要实现IndexMut trait。

// Slightly simplified
// 略微简化
pub trait IndexMut<Idx>: Index<Idx>
{
    // Required method
    // 必须的方法
    fn index_mut(&mut self, index: Idx) -> &mut Self::Output;
}

 

只有当类型已经实现了Index trait的时候,才能实现IndexMut trait。因为它解锁了额外的功能。

 

练习

 

这一节的内容挺少的,其实把它和上一节合在一起比较合适,但还是这样搞了,因为RustRover分开了。

 

看一下这一节的题目:

// TODO: Implement `IndexMut<&TicketId>` and `IndexMut<TicketId>` for `TicketStore`.

use std::ops::{Index, IndexMut};
use ticket_fields::{TicketDescription, TicketTitle};

#[derive(Clone)]
pub struct TicketStore {
    tickets: Vec<Ticket>,
    counter: u64,
}

#[derive(Clone, Copy, Debug, PartialEq)]
pub struct TicketId(u64);

#[derive(Clone, Debug, PartialEq)]
pub struct Ticket {
    pub id: TicketId,
    pub title: TicketTitle,
    pub description: TicketDescription,
    pub status: Status,
}

#[derive(Clone, Debug, PartialEq)]
pub struct TicketDraft {
    pub title: TicketTitle,
    pub description: TicketDescription,
}

#[derive(Clone, Debug, Copy, PartialEq)]
pub enum Status {
    ToDo,
    InProgress,
    Done,
}

impl TicketStore {
    pub fn new() -> Self {
        Self {
            tickets: Vec::new(),
            counter: 0,
        }
    }

    pub fn add_ticket(&mut self, ticket: TicketDraft) -> TicketId {
        let id = TicketId(self.counter);
        self.counter += 1;
        let ticket = Ticket {
            id,
            title: ticket.title,
            description: ticket.description,
            status: Status::ToDo,
        };
        self.tickets.push(ticket);
        id
    }

    pub fn get(&self, id: TicketId) -> Option<&Ticket> {
        self.tickets.iter().find(|&t| t.id == id)
    }
}

impl Index<TicketId> for TicketStore {
    type Output = Ticket;

    fn index(&self, index: TicketId) -> &Self::Output {
        self.get(index).unwrap()
    }
}

impl Index<&TicketId> for TicketStore {
    type Output = Ticket;

    fn index(&self, index: &TicketId) -> &Self::Output {
        &self[*index]
    }
}

/* TODO */

/* TODO */

 

解答:

impl IndexMut<TicketId> for TicketStore {
    fn index_mut(&mut self, index: TicketId) -> &mut Self::Output{
        &mut self.tickets[index.0 as usize]
    }
}

impl IndexMut<&TicketId> for TicketStore {
    fn index_mut(&mut self, index: &TicketId) -> &mut Self::Output{
        &mut self.tickets[index.0 as usize]
    }
}

 

我们要做的事情也很简单,就是为TicketStore实现IndexMuttrait。其实跟上一节的内容差别也不大。

 

这一节的学习就先到这里了。

 

阅读剩余
THE END