【问题标题】:Is the return type of this method a slice or a borrowed array?这个方法的返回类型是切片还是借来的数组?
【发布时间】:2021-03-19 07:32:30
【问题描述】:

我正在阅读 Rust 书籍,特别是第 8.3 节中的“部门”练习。

我对从我创建的方法返回的内容感到有些困惑。

#[derive(Debug, PartialEq, Eq, Hash)]
enum Department {
    Sales,
    Engineering,
}

#[derive(Debug)]
struct Company {
    users: HashMap<Department, Vec<String>>,
}

impl Company {
    fn add_user_to_department(&mut self, department: Department, employee: String) {
        let users = self.users.entry(department).or_insert(Vec::new());
        users.push(employee);
    }

    fn get_users_in_department(&self, department: Department) -> &[String] {
        match self.users.get(&department) {
            Some(u) => &u,
            None => &[]
        }
    }
}

起初我以为get_users_in_department 方法返回的是Vec 的一部分(或者在None 的情况下是静态文字)。

但在我的match 语句中,我没有使用切片语法,而是返回了对Vec 的借用引用。

match self.users.get(&department) {
    Some(u) => &u,
    None => &[]
}

如果我要返回一个切片,我是否必须返回 Some(u) =&gt; &amp;u[..],

我想我的困惑归结为get_users_in_department 的返回类型是什么。它是返回对String 数组的引用,还是String 数组的切片。由于某种强制,这两种类型是否可以互换?如果可以区分两者,我将如何以及何时返回其中一个?

【问题讨论】:

    标签: arrays vector types rust slice


    【解决方案1】:

    From Type Coercions in The Rust Reference:

    类型强制是改变值类型的隐式操作。它们在特定位置自动发生,并且在实际强制的类型方面受到高度限制。

    以下类型之间允许强制:

    • &amp;T&amp;mut T&amp;U 如果 T 实现 Deref&lt;Target = U&gt;

    这种类型的强制称为deref 强制。相关示例:Vec&lt;T&gt; 实现了Deref&lt;Target = [T]&gt;,因此可以将&amp;Vec&lt;T&gt; 强制转换为&amp;[T]

    强制只能发生在程序中的某些强制位置;这些通常是所需类型是显式的或可以通过从显式类型传播(没有类型推断)派生的地方。可能的强制网站有:

    • 函数结果 - 块的最后一行(如果它不是以分号结尾)或返回语句中的任何表达式。

    例子:

    // no type coercion
    fn vec_to_vec<T>(vec: &Vec<T>) -> &Vec<T> {
        vec
    }
    
    // &Vec<T> coerced to &[T] via deref coercion
    fn vec_to_slice<T>(vec: &Vec<T>) -> &[T] {
        vec
    }
    

    playground

    为了更直接地回答您的问题,get_users_in_department 中的&amp;u 的类型是&amp;Vec&lt;String&gt;,但编译器会为您强制转换为&amp;[String]

    【讨论】:

    • 在贴出的代码中有清晰可见的-&gt; &amp;[String]时,写“get_users_in_department的返回类型为&amp;Vec&lt;String&gt;”是不是有点混乱?最好说:“get_users_in_department 的返回类型是 &amp;[String](切片引用),因为这是写在代码中的内容,这就是可能的方式”?
    • 感谢您的评论,我已经更新了我的答案以更清楚。
    猜你喜欢
    • 1970-01-01
    • 2019-12-16
    • 1970-01-01
    • 1970-01-01
    • 2013-04-26
    • 2018-10-09
    • 1970-01-01
    • 2019-06-29
    • 1970-01-01
    相关资源
    最近更新 更多