С Новым годом! Форум программистов, компьютерный форум, киберфорум
Rust
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.72/25: Рейтинг темы: голосов - 25, средняя оценка - 4.72
Заблокирован
1

Проблемы Rust

04.03.2021, 13:30. Показов 4760. Ответов 31

Author24 — интернет-сервис помощи студентам
Привет всем. Предлагаю в этой теме собирать, обсуждать и предлагаю решение тех проблем, которые язык Rust создаёт своим пользователям.

Язык Rust предлагает много полезных инструментов своим пользователям.
Но и ставит препоны им он тоже довольно часто.
Самый простой пример - Rust не позволяет считать просто число из входного потока.
Вместо этого нам предлагают читать строки.

пример:


C
1
2
3
4
5
6
7
8
9
10
use std::io::{self, prelude::*};
 
fn main() {
   
   let mut number = String::new();
   
   io::stdin().read_line(&mut buf).unwrap();
 
   println!("{}", num);
}
Но что, если нам надо хранить входные данные именно как число, а не как строку?
Нам предлагается ее "распарсить".

C
1
2
3
4
5
6
7
8
9
10
11
12
13
use std::io::{self, prelude::*};
 
fn main() {
   
   let mut number = String::new();
   let mut digits = 0;
   
    io::stdin().read_line(&mut number).unwrap();
    digits = number.trim().parse::<i32>().unwrap(); //перед тем, как парсить нужно убрать из строки все лишнее, чтобы остались только цифры.
    //для этого применяем еще и  метод trim() к строке иначе получим ошибку!
    println!("{}", digits);
 
}
Все прекрасно.
Но что если введенное число больше i32?
Опять получим ошибку и панику.
Как быть? Парсить как самый большой тип, а потом приводить к нужному?
Тут опять возникают вопросы, так как не все типы можно приводить друг к другу.

Остаётся применять костыли и парсить саму строку именно как строку.

Например если я хочу получить число u8, то можно посчитать длину строки.

C
1
2
3
if number.len() > 3  {
  ...
}
И если она превышает 3 символа(без учёта символа конца строки), то это число уже точно не попадает в диапазон типа u8.
Тогда вам придётся знать и помнить диапазоны значений или вызывать их из библиотеки.

продолжение следует...

Добавлено через 46 минут
З.Ы. можно использовать синтаксис match, но проблема в том, что match должен возвращать один и тот же тип из всех ветвей: вернуть число или сообщить об ощибке просто так не выйдет. Придется создавать новый тип, который будет служить контейнером.
А вот синтаксис if let подойдет в самый раз. И не придется считать длинну строки.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
04.03.2021, 13:30
Ответы с готовыми решениями:

Проблемы в реализации md5 на Rust
решил сам реализовать md5 га Rust но возникла проблема. алгоритм вроде правильный но результат нет...

Я хочу писать на Rust но у меня возникли проблемы
при установке rustup - init вылезают подобные ошибки:error: could not rename component file from...

[Rust] Обсуждение возможностей и предстоящей роли языка Rust
Psilon, чем он тебя так привлек? И почему именно &quot;убийца плюсов&quot;? Если напишешь развернутый ответ,...

[Rust] Как привязывать WinAPI-функции к коду на Rust?
Может кто-нить дать код, КАК привязывать вин апишные функции к растовскому коду (на примере...

31
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
04.03.2021, 13:41 2
Цитата Сообщение от RatPoison Посмотреть сообщение
Опять получим ошибку и панику.
И это прекрасно. Жаль, что паника не в любом языке. Обрабатывай ошибки и говори о них пользователю.
0
Модератор
5106 / 3334 / 535
Регистрация: 01.06.2013
Сообщений: 6,999
Записей в блоге: 9
04.03.2021, 16:25 3
Цитата Сообщение от RatPoison Посмотреть сообщение
Предлагаю в этой теме собирать, обсуждать и предлагаю решение тех проблем, которые язык Rust создаёт своим пользователям.
Предлагаю для каждой проблемы создавать свою тему, как это обычно и делается на форумах.

Добавлено через 1 минуту
А ещё, кстати, предлагаю писать челобитную Микаэлю от нескольких человек чтобы он повелел прикрутить синтаксис rust-а к форуму.
0
Заблокирован
04.03.2021, 19:18  [ТС] 4
Цитата Сообщение от Vourhey Посмотреть сообщение
И это прекрасно. Жаль, что паника не в любом языке. Обрабатывай ошибки и говори о них пользователю.
Я забыл про синтексис if let, который тут подходит как никогда.

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
use std::io::{self, prelude::*};
 
fn main() {
   
   let mut number = String::new();
   let mut digits: u8 = 0;
 
  loop {
    print!("Число: ");
    io::stdout().flush().unwrap();
    io::stdin().read_line(&mut number).unwrap();
    
    if let Ok(n) = number.trim().parse::<u8>() {
      digits = n;
      break;
    } else {
      println!("Вводимое число не должно быть больше 255");
      number.clear();
      continue;
    }
 
  }
 
   println!("{}", digits);
}
Добавлено через 31 секунду
Цитата Сообщение от Curry Посмотреть сообщение
прикрутить синтаксис rust-а к форуму.
думаю прикрутят, когда в ветке будет чуть больше, чем 3 человека)
0
88 / 108 / 6
Регистрация: 16.04.2019
Сообщений: 451
Записей в блоге: 4
05.03.2021, 14:04 5
Цитата Сообщение от RatPoison Посмотреть сообщение
Но что если введенное число больше i32?
А что если введённое число состоит из 10 тысяч знаков? Вы скажете такого не может быть? Я скажу что может, если число может быть больше 32бит, то что мне мешает ввести тысячи знаков?
Цитата Сообщение от RatPoison Посмотреть сообщение
Как быть? Парсить как самый большой тип, а потом приводить к нужному?
Нет, разумно оценивать что ваша программа будет делать и с какими данными она будет работать? И если пользователь вздумал ввести число, которое больше чем 32бит сообщить ему об этом и попросить ввести корректные данные?
Цитата Сообщение от RatPoison Посмотреть сообщение
продолжение следует...
Да, давайте дальше, так как это назвать проблемой языка можно разве с натяжкой. И вообще это разве проблема языка, а не проблема его стандартной библиотеки?
0
Заблокирован
05.03.2021, 14:28  [ТС] 6
Цитата Сообщение от IamLost Посмотреть сообщение
А что если введённое число состоит из 10 тысяч знаков? Вы скажете такого не может быть? Я скажу что может, если число может быть больше 32бит, то что мне мешает ввести тысячи знаков?
Я вообще-то про это и говорил.
Цитата Сообщение от IamLost Посмотреть сообщение
Нет, разумно оценивать что ваша программа будет делать и с какими данными она будет работать?
И про это тоже.

Цитата Сообщение от IamLost Посмотреть сообщение
И если пользователь вздумал ввести число, которое больше чем 32бит сообщить ему об этом и попросить ввести корректные данные?
Как раз и рассуждал как это сделать без изобретения велосипеда. Синтаксис if let тут весьма помогает.

Цитата Сообщение от IamLost Посмотреть сообщение
И вообще это разве проблема языка, а не проблема его стандартной библиотеки?
Ну так библиотека реализована на возможностях языка. Если язык не предлагает других вариантов, то что едалть?

Если для вас это не проблема, то давайте почитайте соседнюю тему о возможной уязвимости при чтении входных данных в строку или в вектор.
А если вы из С пришли в Rust и хотите сделать что-то типа этого:

C
1
2
3
4
struct Person {
   name [u8; 50],
   surname [u8, 50]
}
То этот код у вас не скомпенсируется, так как длина массива в структурах не может быть больше 32.
Как я понимаю, это сделано потому, что можно сделать так:
C
1
2
3
4
struct Person<T> {
   name [T; 50],
   surname [T, 50]
}
Где Т может быть любого размера, что потенциально может привести к проблемам с памятью.
Вам придётся использовать Строки или Векторы для хранения данных. А прямое чтение данных в строку или вектор небезопасно, так как эти типы растут динамически по мере поступления данных
Единственный выход который я вижу - это завести буфер в виде статического массива фиксированной длинны и в него читать данные из потока, а потом уже, обработав полученные данные, эти данные писать в поля структуры.
0
88 / 108 / 6
Регистрация: 16.04.2019
Сообщений: 451
Записей в блоге: 4
05.03.2021, 16:19 7
Цитата Сообщение от RatPoison Посмотреть сообщение
Если для вас это не проблема, то давайте почитайте соседнюю тему о возможной уязвимости при чтении входных данных в строку или в вектор.
А если вы из С пришли в Rust и хотите сделать что-то типа этого:
Я тупой, я перечитал 3 раза и не понял в чём проблема. В том, что программа упадёт? В каком ЯП она не упадёт, если мы будем вводить строку действительно произвольной длины? Ввод же окончится после того как пользователь нажмёт Enter? Соотвественно в теории я могу ввести строку, в которой будет больше байт чем памяти компьютера.
0
Заблокирован
05.03.2021, 18:21  [ТС] 8
Цитата Сообщение от IamLost Посмотреть сообщение
Ввод же окончится после того как пользователь нажмёт Enter?
Если говорить о методе read-line - то да. Точнее пока read-line не встретит символ новой строки - '\n', так как данные можно читать из любого потока - файл, tcp соединение и тд.
Цитата Сообщение от IamLost Посмотреть сообщение
В каком ЯП она не упадёт, если мы будем вводить строку действительно произвольной длины?
Не знаю как в других языках, но от этого должна быть защита иначе это потенциальное место для возможных атак.
Цитата Сообщение от IamLost Посмотреть сообщение
Соотвественно в теории я могу ввести строку, в которой будет больше байт чем памяти компьютера.
Ну всю память навряд ли удастся занять. Программа будет запрашивать у ОС память снова и снова, пока ОС не скажет: "Хватит".
1
Модератор
5106 / 3334 / 535
Регистрация: 01.06.2013
Сообщений: 6,999
Записей в блоге: 9
05.03.2021, 19:25 9
Цитата Сообщение от RatPoison Посмотреть сообщение
Ну так библиотека реализована на возможностях языка. Если язык не предлагает других вариантов, то что едалть?
Язык не позволяет написать свой крейт или найти подходящий?
Цитата Сообщение от RatPoison Посмотреть сообщение
данные можно читать из любого потока - файл, tcp соединение
В 2021 не стоит обрабатывать большие данные через стандартные потоки.
Цитата Сообщение от RatPoison Посмотреть сообщение
от этого должна быть защита иначе это потенциальное место для возможных атак.
Вам же написали - читайте в буфер. Сами же нашли from_utf8_lossy. А если посмотреть как она реализована, то увидим что там используется модуль lossy, к сожалению, пока экспериментальный. А так то можно им читать входной буфер пока там полные UTF-8 символы. А остаток оставлять пока получения следующих данных.
1
Заблокирован
08.03.2021, 19:36  [ТС] 10
Если вы когда-нибудь имели дело с другими системными языками программирования, то наверняка заметили, что в Rust нет такой, казалось бы, простой и элементарной вещи, как функция закрывающая файл. Пользователям предлагается иметь дело либо с областями видимости и ждать, пока указатель на открытый фал сам "дропнится", либо воспользоваться функций drop напрямую. Однако при этом вы не сможете отловить ошибки, а возвращаемое значение при закрытии файла игнорируется, что является серьёзной ошибкой.
0
Модератор
5106 / 3334 / 535
Регистрация: 01.06.2013
Сообщений: 6,999
Записей в блоге: 9
08.03.2021, 21:05 11
Цитата Сообщение от RatPoison Посмотреть сообщение
Однако при этом вы не сможете отловить ошибки, а возвращаемое значение при закрытии файла игнорируется, что является серьёзной ошибкой.
А поискать?
https://docs.rs/close-file/0.1.0/close_file/
0
Заблокирован
08.03.2021, 21:10  [ТС] 12
Цитата Сообщение от Curry Посмотреть сообщение
А поискать?
Отдельный крейт для этой функции? По-моему несерьезно. Эта функция должна быть в стандартной библиотеке.
Интересно, она clib::fclose вызывает?
0
Модератор
5106 / 3334 / 535
Регистрация: 01.06.2013
Сообщений: 6,999
Записей в блоге: 9
08.03.2021, 22:03 13
Цитата Сообщение от RatPoison Посмотреть сообщение
Отдельный крейт для этой функции? По-моему несерьезно. Эта функция должна быть в стандартной библиотеке.
Ну, сырой rust по факту.
"Всё равно его не брошу
Потому что он хороший." (с) А. Барто.

Ничего нет страшного, если крейт в зависимости добавить.
Цитата Сообщение от RatPoison Посмотреть сообщение
Интересно, она clib::fclose вызывает?
Исходник посмотреть тоже никак?
Для линя вызывает. Для винды kernel32::CloseHandle.
0
Заблокирован
08.03.2021, 22:53  [ТС] 14
Цитата Сообщение от Curry Посмотреть сообщение
Ничего нет страшного, если крейт в зависимости добавить.
новичок не будет использовать сторонние крейты. он будет использовать стандартную библиотеку.
Если Rust за безопасность, то это должно прослеживаться везде, а не быть просто на словах.
Мы же хотим пользоваться хорошим языком ЯП.
0
Модератор
5106 / 3334 / 535
Регистрация: 01.06.2013
Сообщений: 6,999
Записей в блоге: 9
09.03.2021, 00:48 15
RatPoison, если хотите, поэкспериментируйте с sync_all, может быть его достаточно.
0
Заблокирован
09.03.2021, 11:22  [ТС] 16
Curry, да, я читал.
этот метод время кушает и бывает избыточен.
0
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
09.03.2021, 11:31 17
Цитата Сообщение от RatPoison Посмотреть сообщение
Если вы когда-нибудь имели дело с другими системными языками программирования, то наверняка заметили, что в Rust нет такой, казалось бы, простой и элементарной вещи, как функция закрывающая файл. Пользователям предлагается иметь дело либо с областями видимости и ждать, пока указатель на открытый фал сам "дропнится", либо воспользоваться функций drop напрямую. Однако при этом вы не сможете отловить ошибки, а возвращаемое значение при закрытии файла игнорируется, что является серьёзной ошибкой.
Да, это косяк.
0
Эксперт функциональных языков программированияЭксперт Java
4542 / 2736 / 486
Регистрация: 28.04.2012
Сообщений: 8,647
09.03.2021, 12:01 18
Цитата Сообщение от RatPoison Посмотреть сообщение
Если вы когда-нибудь имели дело с другими системными языками программирования, то наверняка заметили, что в Rust нет такой, казалось бы, простой и элементарной вещи, как функция закрывающая файл. Пользователям предлагается иметь дело либо с областями видимости и ждать, пока указатель на открытый фал сам "дропнится", либо воспользоваться функций drop напрямую. Однако при этом вы не сможете отловить ошибки, а возвращаемое значение при закрытии файла игнорируется, что является серьёзной ошибкой.
А если вы ещё имели дело и с C++, D, Ada и Vala…

https://github.com/rust-lang/rust/issues/59567
https://github.com/rust-lang/rust/issues/32255

Цитата Сообщение от RatPoison Посмотреть сообщение
этот метод время кушает и бывает избыточен.
Однако только он гарантирует, что данные и метаданные были записаны. А close не гарантирует, и про «серьёзную ошибку игнорирования результата close» в https://linux.die.net/man/2/close написано как раз в контексте потери данных:

Not checking the return value when closing the file may lead to silent loss of data.

If you need to be sure that the data is physically stored use fsync(2)
0
Заблокирован
09.03.2021, 12:09  [ТС] 19
Цитата Сообщение от Vourhey Посмотреть сообщение
Да, это косяк.
ага
Цитата Сообщение от korvin_ Посмотреть сообщение
Однако только он гарантирует, что данные и метаданные были записаны.
не обязательно при открытии файла читать данные всякий раз. может файл нужно открыть для чтения изначально. а уже потом, дальше в коде, для записи. Что тоже может привести к потере данных, если в первый раз файл не был закрыт.
0
Эксперт функциональных языков программированияЭксперт Java
4542 / 2736 / 486
Регистрация: 28.04.2012
Сообщений: 8,647
09.03.2021, 12:16 20
Вот интересное чтиво про close: https://lwn.net/Articles/576478/

At one time many years ago there was a path in the kernel that returned an error from close and it broke so many things. Even emacs crashed.

The widespread overwhelming belief is that close() is just going to always succeed, and there is more harm than good from signalling errors at all from that function.
Добавлено через 2 минуты
Цитата Сообщение от RatPoison Посмотреть сообщение
не обязательно при открытии файла читать данные всякий раз. может файл нужно открыть для чтения изначально.
Если файл только читается, то вызывать sync_all не нужно, очевидно же.

Цитата Сообщение от RatPoison Посмотреть сообщение
а уже потом, дальше в коде, для записи. Что тоже может привести к потере данных, если в первый раз файл не был закрыт.
Так после записи и вызывай sync_all, если хочешь убедиться, что всё записалось, в чём проблема?
0
09.03.2021, 12:16
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
09.03.2021, 12:16
Помогаю со студенческими работами здесь

[Rust] Расскажите о своём опыте программирования на Rust
Доброе утро! Расскажите, пожалуйста, о своём опыте программирования на Rust. Можно в сравнении с...

Убийца Rust
Пока программисты C++ думаю станет ли Rust тем языком, который сможет потеснить плюсы и занять их...

[Rust] Time
Подскажите как узнать время в Rust. //Rust extern crate time; fn main() { let now =...

Rust+assembler
Как связать язык rust и ассемблер не используя ассемблерные вставки(неудобно использовать их в...

Rust не хватает функциональности?
Rust вобрал в себя немало из функциональных языков, но ему, по-моему мнению, все же...

Примитивный чат на Rust
решил попробовать написать примитивный чат на Rust. получился приблизительно следующий код: use...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Счётчик на базе сумматоров + регистров и генератора сигналов согласования.
Hrethgir 07.01.2025
Создан с целью проверки скорости асинхронной логики: ранее описанного сумматора и предополагаемых fast регистров. Регистры созданы на базе ранее описанного, предполагаемого fast триггера. То-есть. . .
Как перейти с Options API на Composition API в Vue.js
BasicMan 06.01.2025
Почему переход на Composition API актуален В мире современной веб-разработки фреймворк Vue. js продолжает эволюционировать, предлагая разработчикам все более совершенные инструменты для создания. . .
Архитектура современных процессоров
inter-admin 06.01.2025
Процессор (центральный процессор, ЦП) является основным вычислительным устройством компьютера, которое выполняет обработку данных и управляет работой всех остальных компонентов системы. Архитектура. . .
История создания реляционной модели баз данных, правила Кодда
Programming 06.01.2025
Предпосылки создания реляционной модели В конце 1960-х годов компьютерная индустрия столкнулась с серьезными проблемами в области управления данными. Существовавшие на тот момент модели данных -. . .
Полезные поделки на Arduino, которые можно сделать самому
raxper 06.01.2025
Arduino как платформа для творчества Arduino представляет собой удивительную платформу для технического творчества, которая открывает безграничные возможности для создания уникальных проектов. Эта. . .
Подборка решений задач на Python
IT_Exp 06.01.2025
Целью данной подборки является предоставление возможности ознакомиться с различными задачами и их решениями на Python, что может быть полезно как для начинающих, так и для опытных программистов. . . .
С чего начать программировать микроконтроллер­­ы
raxper 06.01.2025
Введение в мир микроконтроллеров Микроконтроллеры стали неотъемлемой частью современного мира, окружая нас повсюду: от простых бытовых приборов до сложных промышленных систем. Эти маленькие. . .
Из чего собрать игровой компьютер
inter-admin 06.01.2025
Сборка игрового компьютера требует особого внимания к выбору комплектующих и их совместимости. Правильно собранный игровой ПК не только обеспечивает комфортный геймплей в современных играх, но и. . .
Обновление сайта www.historian.b­y
Reglage 05.01.2025
Обещал подвести итоги 2024 года для сайта. Однако начну с того, что изменилось за неделю. Добавил краткий урок по последовательности действий при анализе вредоносных файлов и значительно улучшил урок. . .
Как использовать GraphQL в C# с HotChocolate
Programming 05.01.2025
GraphQL — это современный подход к разработке API, который позволяет клиентам запрашивать только те данные, которые им необходимы. Это делает взаимодействие с API более гибким и эффективным по. . .
Модель полного двоичного сумматора с помощью логических операций (python)
AlexSky-coder 04.01.2025
def binSum(x:list, y:list): s=^y] p=x and y for i in range(1,len(x)): s. append((x^y)^p) p=(x and y)or(p and (x or y)) return s x=list() y=list()
Это мы не проходили, это нам не задавали...(аси­­­­­­­­­­­­­­­­­­­­­­­­­­х­р­о­н­­н­­­ы­­й счётчик с управляющим сигналом зад
Hrethgir 04.01.2025
Асинхронный счётчик на сумматорах (шестиразрядный по числу диодов на плате, но наверное разрядов будет больше - восемь или шестнадцать, а диоды на старшие), так как триггеры прошли тестирование и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru