The OpenNET Project / Index page

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



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

Оглавление

Выпуск языка программирования Rust 1.71 , opennews (??), 14-Июл-23, (0) [смотреть все]

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


99. "Выпуск языка программирования Rust 1.71 "  +/
Сообщение от Анонимусс (?), 14-Июл-23, 17:11 
Какой смысл сравнивать NonZeroI с нулем через больше или РАВНО, если оно NonZero?
А причина - строгая типизация, ты не можешь без неявного преобразования сравнить NonZero и numeric literal. И, в отличие от некоторых, тут решили не делать неявных преобразований.
Ответить | Правка | К родителю #32 | Наверх | Cообщить модератору

172. "Выпуск языка программирования Rust 1.71 "  +1 +/
Сообщение от Аноньимъ (ok), 15-Июл-23, 05:07 
Я смотрю вы в теме, как они этот тип вообще реализовывают? Это что-то из llvm ?
То есть что за этим скрывается? Что в ассемблере будет?
Ответить | Правка | Наверх | Cообщить модератору

183. "Выпуск языка программирования Rust 1.71 "  +/
Сообщение от Аноним (183), 15-Июл-23, 09:25 
На ассемблере будет обычный int. Но компилятор сможет учитывать, что этот int в своем нормальном состоянии никогда не будет равен нулю и использовать это в своих целях.

Самый банальный пример то, как будут выглядеть опциональные типы, то, что в C++ std::optional, а в расте std::option.

В структуре нужно хранить само значение и признак того, валидно оно или нет.

Т.е. обычно структура на плюсах упрощенно будет выглядеть как-то так:


class Option<T> {
    bool is_empty;
    T value;
}


В общем виде, примерно так же будет выглядеть эта структура и на расте. Но, если вместо T использовать значение, у которого одно из значений может отсутствовать, например нулевое значение, то от булевского флага можно избавиться и использовать нулевое значение этого типа как признак того, что этот optional пустой.

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

196. "Выпуск языка программирования Rust 1.71 "  –1 +/
Сообщение от ламер (ok), 15-Июл-23, 12:35 
Не в упрёк, а в дополнение (юзеру выше). Всё таки не стоит сильно упрощать. Говоря про реализацию Option, Result и т.д., мы говорим про типы-суммы. В самом примитивном варианте, да, это будет реализована как показано у Анонима, где в случае отсутствия значения у нас не будет инициализирована память, но это хаки небезопасных языков, что не защищают свои абстракции. Да и с точки зрения типов это не Option-тип.

Для правильного "низкоуровневого" Option<T> нам нужен тег(is_some/is_none) и union(из двух вариантов T и Unit). Вполне рабочий вариант для языков с бедной системой типов, но не для чего-то вроде того же C++. Там всё несколько сложнее.

В Rust многие типы(из коробки core, std, alloc) идут как языковые features, то есть тот же Option не захардкожен в компилятор, но в реализации имеет метки для компилятора aka это вот именно Option, благодаря чему у компилятора больше контекста для всячиских оптимизаций. То же, например, с трейтом Drop. Тот же NonZeroI помечен как nonzero, если вы посмотрите исходники.

И возвращаясь к C++, то эмитировать алгебраические типы данных можно ещё и объектной системой, это "эталонный" способ для так называемых менстримных ООП языков. В C++ это всё очень нетривиально, но в базе своей подход строиться на том, что у нас есть базовый абстрактный класс(тип), а его наследники, реализующие его интерфейс - конструкторы.

Для примера код на Haskell:

data Option a = None | Some a

На волшебном ООП языке X:

abstract class Option<T>
class Some<T> : Option<T>
class None : Option<_>


На поиграться можете в Rust создать тип-произведение, один из элементов которого nonzero, и посмотреть, что в итоге sizeof вашего типа A и Option<A> будет одинаковый.  

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

231. "Выпуск языка программирования Rust 1.71 "  +/
Сообщение от Аноним (231), 15-Июл-23, 22:43 
Что Вы тут нафантазировали?
Больно читать. Option это enum ( None и Some(T) T - тип )
Какие классы в Rust?
https://doc.rust-lang.org/std/num/struct.NonZeroI32.html - NonZeroI32
https://doc.rust-lang.org/std/option/enum.Option.html - Option
Ответить | Правка | Наверх | Cообщить модератору

251. "Выпуск языка программирования Rust 1.71 "  +1 +/
Сообщение от ламер (ok), 16-Июл-23, 02:28 
Я боюсь, что Вы слишком бегло просмотрели текст и не уловили контекст. Но в этом есть и моя вина, что написал не разборчиво. Выше просто поднялась тема про реализацию типов-сумм и я решил несколько раскрыть мысль, сделав небольшие ремарки.

В моем комментарии говорится про то, что в языках без тип-сумм их можно средствами тамошних систем типов. В примитивном варианте — через union-тип, в ООП — через объектную систему и её полиморфизм подтипов.

Я думаю, что осложнила восприятие изложение про связь в Rust компилятора и кода пользователем. Это было лишнее, Вы правы.

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

199. "Выпуск языка программирования Rust 1.71 "  +/
Сообщение от Аноньимъ (ok), 15-Июл-23, 14:21 
>этот int в своем нормальном состоянии никогда не будет равен нулю

За счёт чего это гарантируется?

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

228. "Выпуск языка программирования Rust 1.71 "  +/
Сообщение от warlock66613email (ok), 15-Июл-23, 22:19 
Просто нет возможности туда присвоить ноль. Нет публичного метода или ещё чего-то аналогичного.
Ответить | Правка | Наверх | Cообщить модератору

233. "Выпуск языка программирования Rust 1.71 "  +/
Сообщение от Аноним (231), 15-Июл-23, 22:54 
Просто учитывается Z флаг процессора при присвоении и выставляется валидность в поле структуры.
Но говорю сразу я не проверял _пока_.
Ответить | Правка | К родителю #199 | Наверх | Cообщить модератору

232. "Выпуск языка программирования Rust 1.71 "  +/
Сообщение от Аноним (231), 15-Июл-23, 22:48 
NonZero это структура с полем валидности (не ноль) и значением. Нет классов в расте. Структуры и из имплиментация. Отдельно выделяются трейты
Ответить | Правка | К родителю #183 | Наверх | Cообщить модератору

186. "Выпуск языка программирования Rust 1.71 "  +/
Сообщение от Анонимусс (?), 15-Июл-23, 10:17 
Просто как соответствующий i32. Остальные - аналогично.
Как и предположили выше используются оптимизации и оно занимает ровно столько же места в памяти.
https://godbolt.org/z/8K1PqdTr6

Чуть больше подробностей из доки:
An integer that is known not to equal zero.
This enables some memory layout optimization. For example, Option<NonZeroI32> is the same size as i32:
NonZeroI32 is guaranteed to have the same layout and bit validity as i32 with the exception that 0 is not a valid instance. Option<NonZeroI32> is guaranteed to be compatible with i32, including in FFI.
https://doc.rust-lang.org/stable/std/num/struct.NonZeroI32.html

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

200. "Выпуск языка программирования Rust 1.71 "  +/
Сообщение от Аноньимъ (ok), 15-Июл-23, 14:23 
>An integer that is known not to equal zero.

Откуда оно это знает?

Что будет если я напишу а = б - с ?

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

205. "Выпуск языка программирования Rust 1.71 "  +/
Сообщение от Анонимусс (?), 15-Июл-23, 15:08 
> Откуда оно это знает?

Ты его инициализируешь ненулевым значением.
Инициализатор new(n: i32) возвращает Option<NonZeroI32> и если ты передашь туда 0, то на выходе будет None. Т.е. проверка на 0 происходит только один раз при попытке создать, а дальше оно гарантировано будет ненулевое.

> Что будет если я напишу а = б - с ?

В таком виде оно просто не скомпилируется - у тебя же результат может оказаться нулем.
Для NonZeroI (пока еще?) не реализованы трейты вроде CheckedAdd и CheckedSub (и остальные из Crate num).
Поэтому придется сделать что-то вроде
    let n = NonZeroI32::new(123).unwrap();
    let m = NonZeroI32::new(321).unwrap();
    let k = NonZeroI32::new(m.get() - n.get());
И результат может быть None.

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

207. "Выпуск языка программирования Rust 1.71 "  +/
Сообщение от Аноньимъ (ok), 15-Июл-23, 16:01 
Выглядит как шаблонный ад с++.

В расте Юнион типы есть вообще?

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

208. "Выпуск языка программирования Rust 1.71 "  +/
Сообщение от Анонимусс (?), 15-Июл-23, 16:20 
Как в TS - нету.
Но оно реализуемо через enum
enum unionType {
  Str(String),
  Int(i32)
}
Ответить | Правка | Наверх | Cообщить модератору

210. "Выпуск языка программирования Rust 1.71 "  +/
Сообщение от Аноним (210), 15-Июл-23, 17:27 
Вообще-то есть. То, что Вы показываете(enum) — tagged union. Именно union он как бы unsafe.
Ответить | Правка | Наверх | Cообщить модератору

212. "Выпуск языка программирования Rust 1.71 "  +/
Сообщение от Анонимусс (?), 15-Июл-23, 17:33 
Вроде вопрос был про "Юнион типы", а не про юнионы.
Ответить | Правка | Наверх | Cообщить модератору

213. "Выпуск языка программирования Rust 1.71 "  +/
Сообщение от Аноним (210), 15-Июл-23, 17:34 
Согласен, прошу прощения. Тогда считайте мой комментарием дополнением к вашему.
Ответить | Правка | Наверх | Cообщить модератору

214. "Выпуск языка программирования Rust 1.71 "  +1 +/
Сообщение от Анонимусс (?), 15-Июл-23, 17:38 
Мда, налажал с терминологией, обычные union (как в си) тоже есть и, как написали выше, они unsafe.
https://doc.rust-lang.org/reference/items/unions.html
Ответить | Правка | К родителю #210 | Наверх | Cообщить модератору

224. "Выпуск языка программирования Rust 1.71 "  +/
Сообщение от Аноньимъ (ok), 15-Июл-23, 21:49 
> Мда, налажал с терминологией, обычные union (как в си) тоже есть и,
> как написали выше, они unsafe.
> https://doc.rust-lang.org/reference/items/unions.html

Не, речь шла именно про тип объединяющий два других типа.
То есть например (int8 U nill) что означает что функция может вернуть то или другое.

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

236. "Выпуск языка программирования Rust 1.71 "  +/
Сообщение от Аноним (249), 15-Июл-23, 23:37 
Для этого есть Option<i8>   fn foo() -> Option<i8>
что бы им воспользоваться вызывающему придется развернуть.
in_caller = foo();
let in_caller = match in_caller {
Some(a) => a,
None => {здесь то что понимается под nill },
};
Не совсем понятно что Вы понимаете под nill (Си)
Если отсутствие валидного значения - используйте Option
Если ошибку в вызванной функции - используйте Result. Result это enum ( ok(T) и Err(E) )
Ответить | Правка | Наверх | Cообщить модератору

240. "Выпуск языка программирования Rust 1.71 "  +/
Сообщение от Аноним (249), 15-Июл-23, 23:57 
Это не ад. Это то что должно быть сделано. Раст строг.

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

238. "Выпуск языка программирования Rust 1.71 "  +/
Сообщение от Аноним (249), 15-Июл-23, 23:48 
> let n = NonZeroI32::new(123).unwrap();

Ну если Вы сами реализуете... По-умолчанию нет такого метода у типа NonZeroI32

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

239. "Выпуск языка программирования Rust 1.71 "  +/
Сообщение от Аноним (249), 15-Июл-23, 23:51 
Посыпал голову пеплом - переклинило ((
Ответить | Правка | Наверх | Cообщить модератору

235. "Выпуск языка программирования Rust 1.71 "  +/
Сообщение от Аноним (249), 15-Июл-23, 23:19 
Не арифметики с NonZeroI*
Ответить | Правка | К родителю #200 | Наверх | Cообщить модератору

247. "Выпуск языка программирования Rust 1.71 "  +/
Сообщение от Аноним (249), 16-Июл-23, 02:05 
Вся арифметика через NonZero*.new()
use std::num::NonZeroI32;
  2 fn main() {
  3     let z = NonZeroI32::new(123).unwrap();
  4     let mut b:i32 = 1;
  5     let mut a:i32 = 3;
  6     let mut c:NonZeroI32 = match NonZeroI32::new(a - b) {
  7         Some(a) => a,
  8         None    => {panic!("Попытка присвоить нуль NonZero типу")},
  9     };
10     println!("{:?}",c);
11     c = NonZeroI32::new(4 + 7).unwrap();
12     println!("{:?}",c);
13
14 }
Если 0 требуется обработка или будет паника
Ответить | Правка | Наверх | Cообщить модератору

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

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




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

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