The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]



Вариант для распечатки  
Пред. тема | След. тема 
Форум Разговоры, обсуждение новостей
Режим отображения отдельной подветви беседы [ Отслеживать ]

Оглавление

Для ядра Linux предложен драйвер GPIO, написанный на Rust, opennews (ok), 20-Июл-21, (0) [смотреть все]

Сообщения [Сортировка по времени | RSS]


346. "Для ядра Linux предложен драйвер GPIO, написанный на Rust"  +/
Сообщение от Ordu (ok), 22-Июл-21, 00:27 
> вот и гадай где data.lock() отпустят. или в какой-то из функций внутри или по выходу..

_guard начинается с подчёркивания, что является заявлением компилятору, что переменная не используется. В смысле она есть, существует, но код на неё никак не ссылается. Если программист попытается её использовать, компилятор будет ругаться -- я не знаю, не проверял, будет ли он выкидывать ошибку или варнинг, но что-нибудь такое он выкинет по-любому.

Это значит, что переменная будет существовать неизменной вплоть до выхода из зоны видимости, когда она будет уничтожена, то есть лок она будет держать ровно до того момента.

Но в целом, я согласен, несколько странный API. Я бы ожидал чего-нибудь в стиле:

  fn ack(data: &Ref<DeviceData>, irq_data: &IrqData) {
        let mask = bit(irq_data.hwirq() % u64::from(PL061_GPIO_NR));
        let data_ref = data.lock();
        if let Some(pl061) = data_ref.resources() {
            let _ = pl061.base.try_writeb(mask.into(), GPIOIC);
        }
    }

То как оно написано, неясно что будет, если я, не сделав data.lock(), попытаюсь вызвать data.resources(). Я получу панику? Или чтение без синхронизации? Разве не стоило бы сделать невозможным обращение к resources без синхронизации, если синхронизация нужна?

Если иногда надо с синхронизацией, а иногда можно без неё, я б пометил метод IrqData::resources как unsafe, чтоб соблазна не возникало без нужды его дёргать, а если хочешь без unsafe, то вызови IrqData::lock, получи взамен "умный указатель" IrqDataLocked, который предоставит тебе метод IrqDataLocked::resources, который уже не будет unsafe. Но с другой стороны, я ничего не знаю про этот IrqData, может и есть какое-то обоснование тому, как они сделали.

Ответить | Правка | К родителю #261 | Наверх | Cообщить модератору

349. "Для ядра Linux предложен драйвер GPIO, написанный на Rust"  –3 +/
Сообщение от Аноним (347), 22-Июл-21, 01:14 
Какая прекрасная логичность и целостность языка: для указания, что переменная изменятся, надо добавить отдельное слово "мут", а что она не используется - к имени пририсовать подчеркивание.

Логика уровня "раст".

Ответить | Правка | Наверх | Cообщить модератору

355. "Для ядра Linux предложен драйвер GPIO, написанный на Rust"  +1 +/
Сообщение от Ordu (ok), 22-Июл-21, 02:12 
> Какая прекрасная логичность и целостность языка: для указания, что переменная изменятся,
> надо добавить отдельное слово "мут", а что она не используется -
> к имени пририсовать подчеркивание.

Угу. Очень удобно. Подобные штуки часто встречаются в языках с паттерн-матчингом и деструктуризацией, потому как... ну, например...

Пускай у нас есть функция:

fn rotate_vector(x: f32, y: f32, angle: f32) -> (f32, f32) {
...
}

Она принимает координаты вектора и угол и возвращает tuple из двух флоатов, которые представляют собой координаты повёрнутого вектора. Я могу написать:

    let coords = rotate_vector(1.0, 0.0, 90.0);

и потом ссылаться на x, через coords.0, а на y через coords.1, но я могу поступить интереснее:

    let (x, y) = rotate_vector(1.0, 0.0, 90.0);

это называется деструктуризация: при присвоении я разбиваю структуру из правой части на именованные куски, в данном случае на x и y. Оно так чаще понятнее выходит.

Но что делать, если мне нужен, скажем, только x? Если я оставлю y, то раст начнёт варнинги кидать о том, что переменная y не используется. На такой случай можно написать:

    let (x, _) = rotate_vector(1.0, 0.0, 90.0);

тут _ -- это специальное имя для переменной, которая не используется, но она нужна только чтобы место занять конкретно в этом выражении. Этот _ можно читать как "пoxpeн что".

Но иногда хочется в коде оставить подсказку, что же там в _: если переменной дать название, то код будет понятнее, будет сразу понятно, какие части возвращаемого значения мы игнорим. Читать проще. И вот тут как раз можно и рыбку съесть и жoпy не ободрать:

    let (x, _y) = rotate_vector(1.0, 0.0, 90.0);

Но это не только так используется -- когда коллбеки передаёшь куда-нибудь, этот коллбек может игнорировать какие-то аргументы. Аргументы тем не менее надо упомянуть в заголовке функции, но потом раст начнёт варнинги кидать о том, что ты их забыл использовать. _ спасает.

> Логика уровня "раст".

Ты льстишь расту. В этом нет ничего нового. Такого рода штуку я ещё в пайтоне видел. Но там, если память мне не изменяет, вместо _ используется *. И я вот не упомню точно, но, вроде, я не только в расте видел использование значка _ в смысле "пoxpeн что".

Ответить | Правка | Наверх | Cообщить модератору

385. "Для ядра Linux предложен драйвер GPIO, написанный на Rust"  +/
Сообщение от freecoder (?), 22-Июл-21, 21:18 
Вообще-то _ и _y - это принципиально разные вещи. Просто подчеркивание - это вообще не имя, а служебное слово языка, которое в паттерне обозначает игнорирование. Это важно понимать, так как в этом случае никакого связывания вообще не происходит, в отличии от варианта _y, где используется уже действительно имя и оно связывается со значением.
Ответить | Правка | Наверх | Cообщить модератору

387. "Для ядра Linux предложен драйвер GPIO, написанный на Rust"  –1 +/
Сообщение от Ordu (ok), 22-Июл-21, 21:40 
> Вообще-то _ и _y - это принципиально разные вещи. Просто подчеркивание -
> это вообще не имя, а служебное слово языка, которое в паттерне
> обозначает игнорирование.

Ты говоришь, что это принципиально разные вещи, в чём "принципиальность" разницы? Что ты называешь принципиальной разницей? Чем принципиальная разница отличается от непринципиальной?

Тебе не кажется, что синтаксис языка определяет, что принципиально разные вещи в этом языке, а что нет? Мне кажется, что именно так. Если синтаксис языка говорит, что if принципиально отличается от foo, потому что if -- это ключевое слово, то значит это принципиальное отличие. Вот lisp, например, не говорит, что if -- это что-то принципиально отличающееся от foo, if -- это просто ещё один символ, и действие его ты можешь повторить, реализовав if как макрос. Ты можешь присвоить значение if'у, или сделать его функцией. В лиспе эта разница непринципиальна. В лиспе просто принято использовать if, как if. В C же if -- это ключевое слово, его поведение невоспроизводимо средствами языка, ты не можешь средствами языка переопределить if и научить его танцевать польку.

> Это важно понимать, так как в этом случае никакого
> связывания вообще не происходит, в отличии от варианта _y, где используется
> уже действительно имя и оно связывается со значением.

Связывание происходит в обоих случаях, только в первом с безымянной переменной, во второй с переменной имеющей имя. В любом случае значение будет существовать до выхода переменной из области видимости.

Ответить | Правка | Наверх | Cообщить модератору

421. "Для ядра Linux предложен драйвер GPIO, написанный на Rust"  +/
Сообщение от freecoder (?), 25-Июл-21, 18:24 
> Ты говоришь, что это принципиально разные вещи, в чём "принципиальность" разницы?
> Связывание происходит в обоих случаях, только в первом с безымянной переменной, во
> второй с переменной имеющей имя. В любом случае значение будет существовать
> до выхода переменной из области видимости.

Разница принципиальная, так как в случае использования _ нет никакого байндинга и нет передачи владения (потому что подчеркивание - это не имя). А вот в случае использования имен _x - байндинг есть и передача владения есть. Вот этот код скомпилируется:

let string = Some("foo".to_string());
if let Some(_) = string {
}
println!("{:?}", string);

Но если ты заменишь _ на _x - то не скомпилируется.

Ответить | Правка | Наверх | Cообщить модератору

422. "Для ядра Linux предложен драйвер GPIO, написанный на Rust"  +/
Сообщение от Ordu (ok), 25-Июл-21, 18:59 
> вот в случае использования имен _x - байндинг есть и передача
> владения есть. Вот этот код скомпилируется:
> let string = Some("foo".to_string());
> if let Some(_) = string {
> }
> println!("{:?}", string);
> Но если ты заменишь _ на _x - то не скомпилируется.

Хм. Да, действительно.

Ответить | Правка | Наверх | Cообщить модератору

398. "Для ядра Linux предложен драйвер GPIO, написанный на Rust"  +/
Сообщение от n00by (ok), 23-Июл-21, 07:23 
> вроде, я не только в расте видел использование значка _ в
> смысле "пoxpeн что".

В паттерн-матчинге _ используется именно в таком смысле, вот пример на OCaml:


let fib n =
  let rec fib_aux m a b =
    match m with
    | 0 -> a
    | _ -> fib_aux (m - 1) b (a + b)
  in fib_aux n 0 1

в данном случае из-за вывода типов возможные значения _ сужены до "любое целое".
Ответить | Правка | К родителю #355 | Наверх | Cообщить модератору

414. "Для ядра Linux предложен драйвер GPIO, написанный на Rust"  +/
Сообщение от Аноньимъ (ok), 24-Июл-21, 04:31 
Это ещё в лиспе было в бородатые года когда сишка была бредовой фантазией в головах корпорастов.
Ответить | Правка | К родителю #355 | Наверх | Cообщить модератору

358. "Для ядра Linux предложен драйвер GPIO, написанный на Rust"  +1 +/
Сообщение от Аноним (-), 22-Июл-21, 03:27 
> Какая прекрасная логичность и целостность языка: для указания, что переменная изменятся,
> надо добавить отдельное слово "мут", а что она не используется - к имени пририсовать подчеркивание.
> Логика уровня "раст".

http://www.cse.unsw.edu.au/~billw/dictionaries/prolog/
>> the appearance of the same variable in two (or more places) in effect says that when the variable is bound to a value, it must be bound to the same value in all the places that it appears in a given rule.
>> The Prolog variable _ (underscore) is a "don't-care" variable, which will match anything (atom, number, structure, …). For example, the rule
>>  In Prolog interpreters that report singleton variables (variables that are only used once in a rule - often these are caused by typographical errors in the code, which is why Prolog warns you about them) do not report singleton variables that begin with _

Какой прекрасный парад невежества уровня "опеннетный антирастовый комментарий".  

Ответить | Правка | К родителю #349 | Наверх | Cообщить модератору

365. "Для ядра Linux предложен драйвер GPIO, написанный на Rust"  –1 +/
Сообщение от Совершенно другой аноним (?), 22-Июл-21, 09:37 
как я понимаю претензия была не к переменной "_", а к тому, что к префиксу "_" привязали какой-то функционал/ограничение. Правда я не понял, это так на уровне языка потребовали (в каких-нибудь официальных документах), и я уже не имею права называть свои переменные с символом подчёркивания в начале, или это такая негласная, но широко распространённая договорённость.
Ответить | Правка | Наверх | Cообщить модератору

386. "Для ядра Linux предложен драйвер GPIO, написанный на Rust"  +/
Сообщение от freecoder (?), 22-Июл-21, 21:23 
Неиспользуемая переменная - это ворнинг компилятора. Несколько раз меня спасал от досадных логических ошибок.
Ответить | Правка | Наверх | Cообщить модератору

366. "Для ядра Linux предложен драйвер GPIO, написанный на Rust"  +/
Сообщение от Совершенно другой аноним (?), 22-Июл-21, 09:57 
Впрочем, перечитал Ordu - если действительно компилятор на это подчёркивание смотрит, решение довольно странное, более логично было-бы его подкрашивать через ключевое слово, имхо.
Ответить | Правка | К родителю #358 | Наверх | Cообщить модератору

378. "Для ядра Linux предложен драйвер GPIO, написанный на Rust"  +1 +/
Сообщение от Ordu (ok), 22-Июл-21, 14:36 
> Впрочем, перечитал Ordu - если действительно компилятор на это подчёркивание смотрит, решение
> довольно странное, более логично было-бы его подкрашивать через ключевое слово, имхо.

Это могло бы быть логичным в C или в C++. Поэтому в них есть __attribute__((unused)). В расте это не логично. Потому как:

1. Раст настаивает на том, чтобы неиспользуемые переменные были бы помечены как неиспользуемые. Местами он задалбывает этим хуже некуда, когда у тебя неиспользуемость временна, и ты компиляцию используешь только чтобы проверить наполовину написанный кусок кода. Или если ты закомментировал половину кода, чтобы посмотреть на то как будет работать без неё. Писать __attribute__((unused)) к каждой переменной, которая не используется, бррр

А как насчёт такого (допустим, что open там возвращает не -1 в случае ошибки, а очень по растовому Err(some_error), а в случае успеха -- Ok(file_descriptor)):

let filedesc = match open(file_name, O_APPEND) {
     Ok(fd) => fd,
     Err(_) => panic!("I cannot open file {:?}. I'm panicking now and going to die soon.", file_name),
};

Видишь там Err(_)? Это тоже деструктуризация, на этот раз в процессе паттерн-матчинга, и это тоже объявление неиспользуемой переменной. можно было бы написать Err(_error) например. Если ты там не обозначишь переменную как неиспользуемую, то раст начнёт тебя клевать, мол, "переменная не используется". И что, ещё туда вставлять __attribute__((unused))? Как ты потом читать будешь всё это?

2. Компилятор раста, хоть и любит заклёвывать своим перфекционизмом, очень заботливый, и если ты, читая RustBook не обратил внимания на _ или обратил, но забыл потом, то он по-ходу дела объяснит тебе, как и когда его использовать. Если б он не был таким заботливым, я подозреваю, растоманов было бы в разы меньше, потому как через несколько часов возни с компилятором, ведущим себя как дятел-перфекционист, они бы разбили бы себе мониторы и растоптали бы свои клавиатуры. С рядах растоманов остались бы только 100% флегматики, абсолютно неспособные к эмоциям.

А, и ещё, ежели тебе кажется, что трактовать имена переменных с определённым префиксом специальным образом, это изобретение rust'а, то опять это не так. В Common Lisp'е имена символов начинающиеся с : в начале автоматически имеют себя в качестве своего значения, их поэтому можно использовать как символические ключи в парах (ключ значение), не парясь о том, чтобы квотировать их дописывая ' в начале. То есть это вроде как и переменная, но сколько бы раз в процессе вычислений на эту переменную не выполнялся бы eval, она от этого не изменится. Очень удобно. Можно было бы ключами использовать строки, типа ("ключ" значение), но там ряд неудобств возникает: кавычек много писать надо, и :ключ будет иметь ровно одну копию в памяти, в то время как строк "ключ" может быть создано сколько угодно, и хоть они и будут равны друг-другу, но они будут разными объектами, занимающими память, и проверять на равенство их каждый раз придётся посимвольно, то есть со сложностью O(N), вместо O(1).

Тоже кстати дискриминация: почему я не могу называть свои переменные с именем, начинающимся с двоеточия? =)

Ответить | Правка | Наверх | Cообщить модератору

374. "Для ядра Linux предложен драйвер GPIO, написанный на Rust"  +/
Сообщение от Ordu (ok), 22-Июл-21, 13:58 
> http://www.cse.unsw.edu.au/~billw/dictionaries/prolog/

О, точно же, в прологе так было!

Ответить | Правка | К родителю #358 | Наверх | Cообщить модератору

377. "Для ядра Linux предложен драйвер GPIO, написанный на Rust"  +/
Сообщение от Аноним (377), 22-Июл-21, 14:28 
>> http://www.cse.unsw.edu.au/~billw/dictionaries/prolog/
> О, точно же, в прологе так было!

Ну да, правда в раст оно скорее всего из хаскеля попало:
https://typeclasses.com/underscore
> When the underscore appears alone in a pattern,This is perhaps the most common use of an underscore. it is a reserved identifier that acts as a wildcard: a pattern that matches anything A pattern that always succeeds is called an irrefutable pattern. but does not introduce a new variable.
> Beginning a name with an underscore is sometimes used to name variables we will not use – and thus don’t really care about – but care just enough about to give it a name to remind ourselves of what is being discarded.

Ответить | Правка | Наверх | Cообщить модератору

Архив | Удалить

Рекомендовать для помещения в FAQ | Индекс форумов | Темы | Пред. тема | След. тема




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру