мне не нравится реальность
Photo
#prog #rust
Поясню на практическом примере, почему нужны generic associated types. Посмотрим на трейт std::io::BufRead. Это трейт, который расширяет функционал std::io::Read функционалом, который слишком неэффективно реализовывать напрямую на методах, предоставляемых
Один из методов, предоставляемых
Метод
Как мы можем обойти эту проблему? Вот тут и вступает в дело generic associated types. Мы можем написать альтернативное определение итератора:
Погоди, но вроде это можно реализовать и без GAT с таким определением:
Поясню на практическом примере, почему нужны generic associated types. Посмотрим на трейт std::io::BufRead. Это трейт, который расширяет функционал std::io::Read функционалом, который слишком неэффективно реализовывать напрямую на методах, предоставляемых
Read
. Подразумевается, что тип, реализующий BufRead
, имеет некоторый внутренний буфер, доступ к которому можно получить при помощи fill_buf. Наличие этого внутреннего буфера позволяет реализовать некоторые операции, которые затруднительно реализовывать непосредственно поверх Read
, например, read_until.Один из методов, предоставляемых
BufRead
— это lines, который возвращает итератор строк. Но что именно возвращает этот итератор? Он возвращает Result<String, std::io::Error>
. То есть каждый вызов Iterator::next
выделяет память в куче под строку. Как-то не zero cost. В конце концов, у типа, реализующего BufRead
, есть некий внутренний буфер, так почему нельзя возвращать ссылку на него? Давайте посмотрим внимательнее на типы.Метод
Iterator::next
имеет следующую сигнатуру:fn next(&mut self) -> Option<Self::Item>;Обратите внимание: несмотря на то, что в
next
неявно входит лайфтайм, этот лайфтайм отсутствует в возвращаемом типе! Это означает, что значение, возвращаемое next
, может быть, и не владеющее, но оно по крайне мере точно ничего не заимствует из self
. А как должен выглядеть гипотетический next
у нашего итератора, который возвращает ссылку на внутренний буфер?fn next<'a>(&'a mut self) -> Option<&'a str>;(Я сейчас намеренно опускаю вопрос об ошибках, потому что это не главное в том, что я хочу донести). Чем эта сигнатура кардинально отличается от
Iterator::next
? А тем, что (я даже специально расписал лайфтаймы, чтобы это было видно более ясно) возвращаемое значение заимствует self
! Таким образом, даже не смотря на то, что технически мы можем написать этот метод, он не подходит под сигнатуру Iterator::next
, а значит, мы не можем использовать все эти полезные итераторные комбинаторы.Как мы можем обойти эту проблему? Вот тут и вступает в дело generic associated types. Мы можем написать альтернативное определение итератора:
trait AnotherIterator {Новая версия итератора позволяет явно выразить тот факт, что мы не можем вызвать
type Item<'a>; // обратите внимание: тип параметризован
fn next<'a>(&'a mut self) -> Option<Self::Item<'a>>;
// комбинаторы поверх next
}
next
два раза подряд, сохранив оба результата. Да, нам придётся реализовать комбинаторы заново, но этот будут общие методы, а не функции под конкретный тип, которые плохо композируются друг с другом.Погоди, но вроде это можно реализовать и без GAT с таким определением:
trait OneMoreiterator<'a> {Можно. Но это решение обладает рядом недостатков. Первое: его неудобно использовать на практике. Так как нужный нам лайфтайм
type Item;
fn next(&'a mut self) -> Option<&'a Self::Item>;
}
'a
, скорее всего, будет локальным, а не обобщённым параметром, нам придётся использовать HRTB и писать что-то вродеfn do_stuff<I>(iter: I)Во-вторых — и это уже куда как более сильное ограничение — данное определение позволяет возвращать из
where
I: for<'a> OneMoreIterator<'a>,
{
//...
}
next
лишь ссылку на Item
, а не произвольный тип, параметризованный лайфтаймом (скажем, я могу себе представить тип, реализующий AnotherIterator
и возвращающий MutexGuard). В качестве примера, демонстрирующего оба недостатка, можно назвать WindowsMut
, несуществующий пока аналог Windows, возвращающий перекрывающиеся мутабельные подслайсы исходного слайса.GitHub
rfcs/text/1598-generic_associated_types.md at master · rust-lang/rfcs
RFCs for changes to Rust. Contribute to rust-lang/rfcs development by creating an account on GitHub.
Forwarded from Так говорил 2Pizza
Please open Telegram to view this post
VIEW IN TELEGRAM
rusta::mann
< мем из профунктора Я сгорел, ведь правильно приготовленный type-driven design оберегает от кучи логических ошибок, особенно связанных с проверками инвариантов (пресловутый is_initialized() вместо типа, который гарантирован находиться в валидном состояннии…
#prog #article
Продолжение темы от того же автора: Names are not type safety.
https://lexi-lambda.github.io/blog/2020/11/01/names-are-not-type-safety/
В рассуждениях автора легко провести параллели с тем, как использовать и ограничивать unsafe-код в Rust.
Продолжение темы от того же автора: Names are not type safety.
https://lexi-lambda.github.io/blog/2020/11/01/names-are-not-type-safety/
В рассуждениях автора легко провести параллели с тем, как использовать и ограничивать unsafe-код в Rust.
Я:
— Я взрослый мужчина, у которого есть работа и который знает цену деньгам, и я не буду делать импульсивных покупок.
Также я:
— Я взрослый мужчина, у которого есть работа и который знает цену деньгам, и я не буду делать импульсивных покупок.
Также я:
#prog #rust #csharp #article
Статья о взаимной интеграции кода на C# и Rust. Спойлер: работает, но выглядит (на мой взгляд) шатко
Статья о взаимной интеграции кода на C# и Rust. Спойлер: работает, но выглядит (на мой взгляд) шатко
Structured Blog
How we integrate Rust with C#
Seq is a log server that's built using a few programming languages; we have a
storage engine called Flare written in Rust, and a server application written in
C#. Our language stack is something I've talked about previously
[https://blog.getseq.net/rust-at…
storage engine called Flare written in Rust, and a server application written in
C#. Our language stack is something I've talked about previously
[https://blog.getseq.net/rust-at…
Онлайн-инструмент для просмотра диффов между текстами, изображениями, PDF и листами Excel.
https://www.diffchecker.com/
https://www.diffchecker.com/
Diffchecker
Diffchecker - Compare text online to find the difference between two text files
Diffchecker will compare text to find the difference between two text files. Just paste your files and click Find Difference!
Forwarded from Pavel
единственное асексуальное кондитерское изделие, которое мне известно — пирожок с вишней в маке