Ржавчина `&mutuffer[..]` вместо просто `&mutuffer`

В документации Rust для std::io::Read::read() я наткнулся на такой пример:

fn main() -> io::Result<()> {
    let mut f = File::open("foo.txt")?;
    let mut buffer = [0; 10];

    // read up to 10 bytes
    let n = f.read(&mut buffer[..])?;
    // Is there any difference between the previous line and the next one?
    // let n = f.read(&mut buffer)?;

    println!("The bytes: {:?}", &buffer[..n]);
    Ok(())
}

Вы можете видеть, что let n = f.read(&mut buffer[..])?;, buffer[ .. ] содержит все значения от начала до конца, а затем у нас есть изменяемая ссылка на них.

Будет ли какая-то разница, если я вместо этого напишу let n = f.read(&mut buffer)?;?

Я попробовал, и мне кажется то же самое, но мне стало интересно, почему авторы использовали &mut buffer[..], я что-то упускаю?

&mut buffer означает то же самое, что и &mut buffer[..] только в тех местах, где разрешено приведение к разыменованию, при условии, что buffer является Vec
Ivan C 16.08.2024 20:02

В примере это массив, поэтому технически это не разыменование, но это приведение.

drewtato 16.08.2024 20:07

Принудить &mut [u8; 10] к &mut [u8]

Timsib Adnap 17.08.2024 04:32

@TimsibAdnap Я бы рекомендовал .as_mut_slice() вместо &mut [..]. Но я согласен с ОП, простой &mut тоже подойдет и, по моему мнению, лучше.

Finomnis 17.08.2024 12:19

@drewtato Если вы хотите быть педантичным, это приведение к неразмерному значению.

Finomnis 17.08.2024 12:40
Почему Python в конце концов умрет
Почему Python в конце концов умрет
Последние 20 лет были действительно хорошими для Python. Он прошел путь от "просто языка сценариев" до основного языка, используемого для написания...
0
5
81
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Типы разные:

buffer[u8; 10]&mut buffer&mut [u8; 10]&mut buffer[..]&mut [u8]buffer.as_mut_slice()&mut [u8]

Так почему же функция, которой нужен аргумент &mut [u8], может принимать &mut buffer?

Волшебство здесь заключается в автоматическом приведении типов , которое гласит, что &mut [u8; 10] можно автоматически привести к &mut [u8].

Функционально разницы нет. Это похоже на разницу между явным и неявным приведением типов. &mut [..] явно преобразуется в срез, и приведение не происходит, &mut не преобразуется явно, и происходит неявное приведение. Результирующий машинный код будет идентичен.

Дополнительную информацию о разнице между [u8; 10] и [u8] читайте В чем разница между срезом и массивом?.

Так что писать f.read(&mut buffer) вполне нормально, и, на мой взгляд, предпочтительнее, чем f.read(&mut buffer[..]). Это просто легче читать.

Обновлено: @ChayimFriedman отметил, что принуждение не всегда происходит автоматически, и это правильно. Принуждение может иметь место только на сайтах принуждения . Соответствующий сайт приведения для этого примера использует переменную в качестве «аргумента для вызова функции». Если у вас есть ситуация, когда сайт приведения отсутствует, тогда явное преобразование действительно может потребоваться.

Обратите внимание, что иногда (не в этом случае) принуждение не срабатывает, поэтому необходима явность.

Chayim Friedman 17.08.2024 19:35

Другие вопросы по теме