索引操作的返回类型是什么? [英] What is the return type of the indexing operation?

查看:50
本文介绍了索引操作的返回类型是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用切片,但没有成功.

我已将第一个问题简化为:

fn at<'a, T>(slice: &'a [T], index: usize) ->&'a T {让 item = slice[index];物品}

鉴于 文档:

pub trait Index{类型输出;fn index(&'a self, index: &Index) ->&'a <Self as Index<Index>>::Output;//^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}

然而,编译器给了我一个错误:

<块引用>

错误[E0308]:类型不匹配-->src/main.rs:3:5|3 |物品|^^^^ 预期引用,找到类型参数|= 注意:预期类型`&'a T`找到类型`T`

我将其解释为 item 的类型与函数的返回类型不匹配(我引入 item 仅用于调试目的,将表达式求值从返回).

如果我将返回类型切换为 T,即 item 的类型,我会收到另一条错误消息:

<块引用>

error[E0508​​]: 不能移出类型 `[T]`,一个非复制切片-->src/main.rs:2:16|2 |让 item = slice[index];|^^^^^^^^^^^^^|||不能离开这里|帮助: 考虑使用引用代替:`&slice[index]`

稍加修改后,我找到了两种解决方法:

fn at<'a, T>(slice: &'a [T], index: usize) ->&'a T {&slice[索引]//^}fn at<'a, T>(slice: &'a [T], index: usize) ->&'a T {让 ref item = slice[index];//^~~物品}

强制类型为引用就行了.

首先为什么需要这些恶作剧?我做错了什么吗?

解决方案

这是编译器为您所做的一些有用的人体工程学,以使代码看起来更好一些.

Index trait 的返回值一个引用,但是当你使用加糖语法时,编译器会自动为你插入一个解引用<代码>[].大多数其他语言只会从数组中返回项目(复制它或返回对对象的另一个引用,无论合适).

由于 Rust 对移动/复制语义的重要性,您不能总是复制一个值,因此在这些情况下,您通常会使用 &:

let items = &[1u8, 2, 3, 4];让 a: u8 = items[0];让 a: u8 = *items.index(&0);//相当于上面的让 b: &u8 = &items[0];让 b: &u8 = &*items.index(&0);//相当于上面的

请注意,索引值也是自动通过引用获取的,类似于自动取消引用.

I am trying, quite unsuccessfully, to play around with slices.

I have reduced my first issue to:

fn at<'a, T>(slice: &'a [T], index: usize) -> &'a T {
    let item = slice[index];
    item
}

It is my expectation that the return type of slice[index] be a reference, given the documentation:

pub trait Index<Index> {
    type Output;
    fn index(&'a self, index: &Index) -> &'a <Self as Index<Index>>::Output;
//                                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
}

However, the compiler gives me an error:

error[E0308]: mismatched types
 --> src/main.rs:3:5
  |
3 |     item
  |     ^^^^ expected reference, found type parameter
  |
  = note: expected type `&'a T`
             found type `T`

Which I interpret as meaning that the type of item does not match the return type of the function (I introduced item solely for debugging purpose, to split expression evaluation from return).

If I switch the return type to T, which is the type of item, I get another error message:

error[E0508]: cannot move out of type `[T]`, a non-copy slice
 --> src/main.rs:2:16
  |
2 |     let item = slice[index];
  |                ^^^^^^^^^^^^
  |                |
  |                cannot move out of here
  |                help: consider using a reference instead: `&slice[index]`

After tinkering a bit, I found two work-arounds:

fn at<'a, T>(slice: &'a [T], index: usize) -> &'a T {
    &slice[index]
//  ^
}

fn at<'a, T>(slice: &'a [T], index: usize) -> &'a T {
    let ref item = slice[index];
//      ^~~
    item
}

forcing the type to be a reference does the trick.

Why are these shenanigans necessary in the first place? Am I doing something wrong?

解决方案

This is a bit of helpful ergonomics that the compiler does for you in order to make the code look a bit nicer.

The return value of the Index trait is a reference, but the compiler automatically inserts a dereference for you when you use the sugared syntax []. Most other languages would just return the item from the array (copying it or returning another reference to the object, whatever is appropriate).

Due to Rust's importance of move / copy semantics, you can't always make a copy a value, so in those cases, you will usually use a &:

let items = &[1u8, 2, 3, 4];

let a: u8 = items[0];
let a: u8 = *items.index(&0); // Equivalent of above

let b: &u8 = &items[0];
let b: &u8 = &*items.index(&0); // Equivalent of above

Note that the indexing value is also automatically taken by reference, similar to the automatic dereference.

这篇关于索引操作的返回类型是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆