Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
любое объявление extern crate package_name в библиотеке должно быть также продублировано в main.rs приложения
extern crate whatver; только в корне crate'а, т.е. в вашем случае в main.rs. В остальных модулях внешнюю библиотеку можно просто use'ать, как любой другой модуль.Особого упоминания заслуживает такая штука, как время жизни (lifetime) в Rust. С ней я долго боролся. Вообще говоря в Rust у каждой переменной и ссылки есть свой lifetime. Просто он выводится компилятором автоматически на основе определенных правил. Однако иногда его требуется указывать явно. Чтение статьи про время жизни из книги раста ничего для меня не прояснило. (хотя я ее 3 раза перечитал) Я так и не понял, почему же в моем случае Rust попросил указать lifetime. По сути я просто добавил эти странные <'_> везде, где компилятор указывал на ошибку с неуказанным lifetime, так и не разобравшись, зачем же ему это от меня было надо. Если есть знающие люди, буду рад, если просветите в комментариях. Почему именно подчерк, а не какой-то другой знак после апострофа? Просто в сообщении об ошибке про несоответствие типов было sdl2::render::Renderer<'_>. Поначалу я пытался обозначать поле как просто renderer: Renderer, но компилятор меня ругал: error: wrong number of lifetime parameters: expected 1, found 0
'_ — это обозначение анонимного lifetime-параметра, используемое внутри компилятора. На самом деле то, что сейчас можно писать '_ и всё будет работать — это в некотором роде недосмотр, и есть RFC на эту тему, которое, если будет принято, изменит семантику '_. Именно подчерк просто потому, что так компилятор обозначает анонимные lifetime'ы.cargo doc:% git clone https://github.com/AngryLawyer/rust-sdl2
% cd rust-sdl2
% cargo doc
% open target/doc/sdl2/index.html
sdl2::init().video().unwrap() возвращает значение типа sdl2::Sdl, которое позволяет, в частности, создавать новые окна. sdl_context.window(...).....unwrap() возвращает значение типа sdl2::video::Window. Из окна можно создать renderer для этого окна, и это делает window.renderer().build().unwrap() — этот код возвращает значение типа sdl2::video::Renderer<'static>. Внимание на lifetime-параметр — он равен 'static. Это специальный lifetime, обозначающий нечто, что может жить до конца всей программы. В данном случае 'static используется из-за того, что полученный renderer самодостаточен — он получен из поглощённого значения Window (есть другой случай, когда renderer создаётся из поверхности (surface), и тогда он связан с этой поверхностью с помощью этого lifetime-параметра) и не зависит от жизни никакого другого значения.pub struct Canvas {
renderer: Renderer<'static>,
sdl_context: Sdl,
xsize: u32,
ysize: u32,
}
extern crate sdl2; из canvas.rs приводит к тому, что проект отказывается компилироваться с ошибкой error: failed to resolve. Use of undeclared type or module `sdl2` . Получается, что extern'ы должны быть как в main.rs, так и в файлах модулей.let sdl_context = sdl2::init().video().unwrap();наlet sdl_context = ::sdl2::init().video().unwrap();(обратите внимание на :: перед sdl2).main.rs написали mod canvas;, вы определили новый модуль, который Rust ищет в canvas.rs или canvas/mod.rs.use foo::bar::something. Тем самым вы добавляете something в текущую область видимости. И здесь кроется одна маленькая, но важная деталь.use, используется абсолютный путь. Например:use sdl2::render::Renderer;означает, что мы поднимаемся до самого корня (mais.rs), там мы находим extern crate sdl2;, далее находим внутри контейнера модуль render и внутри него — нечто с именем Renderer.use, используется относительный путь. Например:let sdl_context = sdl2::init().video().unwrap();означает, что Rust будет искать, что такое sdl2 в текущем модуле (canvas, потому что мы в canvas.rs). Потому и error: failed to resolve.::). Тем самым, мы сконвертировали относительный путь в абсолютный. Как и в первом случае, теперь, чтобы найти sdl2, Rust будет подниматься до корня контейнера (main.rs) и начинать искать sdl2 оттуда.use sdl2::init;тогда можно будет использовать функцию init из sdl2.
self?). Мне в своё время очень помогло чьё-то неофициальное объяснение модулей: Rust's Modules are Weird :) А потом можно почитать соответствующее обсуждение на reddit.use:use sdl2;
use sdl2::Sdl;
В книге раста не было статей с названием Classes/Objects/Constructors и т. п.
Пишем свой упрощенный OpenGL на Rust — часть 1 (рисуем линию)