среда, 3 февраля 2016 г.

Поля переменной величины внутри struct

Делаю хранилище данных на основе файла. У хранилища есть поле, которое содержит путь к файлу.

use std::path::Path;

pub struct Store {
    path: Path
}

impl Store {
   
    pub fn new(path: Path) -> Store {
        Store {
            path: path
        }
    }
}


Если указать тип поля std::path::Path, то выплывет непонятная ошибка:

error: the trait `core::marker::Sized` is not implemented for the type `[u8]` [E0277]

Хорошо, что в подробном описании присутствует строчка:

all local variables must have a statically known size

Значит, причина ошибки в том, что Rust не понимает, сколько памяти резервировать под нашу структуру, потому что путь к файлу может содержать разное количество символов.

Что делать? Поле должно хранить указатель. Размер указателя на переменную Rast'у известен.

use std::path::Path;

pub struct Store {
    path: &Path
}

impl Store {
   
    pub fn new(path: &Path) -> Store {
        Store {
            path: path
        }
    }
}

Прежняя ошибка, действительно, пропала. Появилась новая:

error: missing lifetime specifier [E0106]

Она относится к определению поля стуктуры:

 pub struct Store {
    path: &Path
}


Да, язык программирования накладывает требование явно указывать время жизни, ести структура содержит указатели:

You’ll also need explicit lifetimes when working with structs that contain references

Доработаем код, с учётом этого обстоятельства.

use std::path::Path;

pub struct Store<'a> {
    path: &'a Path
}

impl Store {
   
    pub fn new(path: &Path) -> Store {
        Store {
            path: path
        }
    }
}

Ошибка пропала. Возникает однако другая проблема:

error: wrong number of lifetime parameters: expected 1, found 0 [E0107]

Неверно записано название структуры в блоке с методами:

impl Store {

Исправляем:

use std::path::Path;

pub struct Store<'a> {
    path: &'a Path
}

impl Store<'a> {
   
    pub fn new(path: &Path) -> Store {
        Store {
            path: path
        }
    }
}


Проблема решена. Появляется следующее препятствие:

error: use of undeclared lifetime name `'a` [E0261]

Оказывается, прежде чем использовать имя жизни, его нужно объявить сразу позади слова impl (см. документацию). Новый вариант кода выглядит теперь так:

use std::path::Path;

pub struct Store<'a> {
    path: &'a Path
}

impl<'a> Store<'a> {
   
    pub fn new(path: &Path) -> Store {
        Store {
            path: path
        }
    }
}

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

error: wrong number of lifetime parameters: expected 1, found 0 [E0107]

Статический метод new возвращает тип Store без указания времён жизни. Исправляем:

use std::path::Path;

pub struct Store<'a> {
    path: &'a Path
}

impl<'a> Store<'a> {
   
    pub fn new(path: &Path) -> Store<'a> {
        Store {
            path: path
        }
    }
}

Движемся дальше. Следующая ошибка относится к типу параметра метода new:

error: cannot infer an appropriate lifetime for automatic coercion due to conflicting requirements [E0495]

Добавляем время жизни в определение типа параметра path:

use std::path::Path;

pub struct Store<'a> {
    path: &'a Path
}

impl<'a> Store<'a> {
   
    pub fn new(path: &'a Path) -> Store<'a> {
        Store {
            path: path
        }
    }
}


Похоже, этот код работает. Конечно, время жизни пути к файлу должно совпадать со временем жизни экземпляра хранилища. Ошибок больше нет. Версия Rust 1.6




четверг, 30 июля 2015 г.

Rust - внедрение зависимостей (анонс)

Можно ли из Раста сделать Джаву? Не уверен... Однако, мне хватило бы фабрик и внедрения зависимостей, чтобы структурировать код в проекте.

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

Компилятор уже не ругается так сильно, как вначале. Отчёт ожидается в ближайшее время.


GitHub

воскресенье, 26 июля 2015 г.

Rust IDE на базе Sublime Text 3 - настроить в Windows

1. Создать директорию для размещения будущих проектов Rust. Например:

C:\Users\anna\Documents\rust



2. Установить Rust и Cargo. Установочный файл с расширением msi скачать со страницы:

http://www.rust-lang.org/install.html



3. Изменить переменную окружения Path, добавив в неё путь к директории с исполняемыми файлами rustc.exe и cargo.exe.

Пуск => Компьютер (правая кнопка мыши) => Свойства => Дополнительные параметры системы => Дополнительно => Переменные среды... => Системные переменные => Path (выбрать из списка) => Изменить => дописать ;C:\Program Files\Rust stable 1.1\bin => ОК




4. Проверить установку.

Пуск => Все программы => Rust => Rust 1.1 64 bit (Shell)
rustc --version



5. Разместить исходники языка в отдельной папке. Они нужны, чтобы в редакторе работали подсказки. Архив скачать со страницы:

http://www.rust-lang.org/install.html



Затем распаковать и поместить в любое удобное место на диске:

 C:\Users\anna\Documents\rust\rustc-1.1.0-src


6. Установить редактор Sublime Text 3. Скачать установочный файл со страницы:

http://www.sublimetext.com/3


7. Установить Git. Установочный файл скачать со страницы:

http://www.git-scm.com/downloads



8. Установить Racer. В консоли Rust перейти в директорию, которую создали ранее для проектов.

cd "C:\Users\anna\Documents\rust"



Скопировать ссылку на репозиторий по адресу:

https://github.com/phildawes/racer



Клонировать репозиторий в консоли:

git clone https://github.com/phildawes/racer.git



перейти в директорию rust

cd racer



Создать исполняемый файл при помощи Cargo:

cargo build --release


Результат находится по адресу:

C:\Users\anna\Documents\rust\racer\target\release\racer.exe

10. Добавить в редактор Sublime Text 3 возможность управления пакетами. В открытом окне редактора перейти в консоль.

View => Show Console


Скопировать кусок кода со страницы

https://packagecontrol.io/installation#st3



Вставить его в консоль и нажать Enter.


Закрыть редактор и открыть его снова.

11. Добавить пакет для работы с Rust в редактор Sublime Text 3. В открытом окне редактора нажать комбинацию клавиш Ctrl + Shift + P и выбрать из списка Package Control | Install Package.


В следующем списке выбрать пакет Rust.



12. Установить в редактор пакет, который позволит использовать Racer.  В открытом окне редактора нажать комбинацию клавиш Ctrl + Shift + P и выбрать из списка Package Control | Install Package.


В следующем списке выбрать RustAutoComplete.


Настроить пути. Для этого перейти в пункт меню:

Preferences -> Package settings -> RustAutoComplete -> Settings -> User


Указать путь до собранного ранее исполняемого файла racer.exe:

 C:\Users\anna\Documents\rust\racer\target\release\racer.exe

и путь до директории с распакованными ранее исходниками Rust:

C:\Users\anna\Documents\rust\rustc-1.1.0-src\rustc-1.1.0\src

Сохранить изменения. Перезапустить редактор на всякий случай.




Проверить работоспособность Racer.


13. Поручить сборку Cargo. В меню выбрать Tools => Build System => Cargo.



Для проверки выбрать в проекте файл Cargo.toml и перейти в меню

Tools => Build With... => Cargo - Run


Результат отобразится в консоли.


13. Установить пакет дополнительной проверки синтаксиса SublimeLinter-contrib-rustc:

https://github.com/oschwald/SublimeLinter-contrib-rustc

В открытом окне редактора нажать комбинацию клавиш Ctrl + Shift + P и выбрать из списка Package Control | Install Package.


В следующем списке выбрать нужный пакет.


Всё, что можно настроено, можно пользоваться. Приятного программирования на Расте!

суббота, 25 июля 2015 г.

Учебные материалы


Видео на английском:

введение

Масса материалов на сайте Zeev.

Написать программу на Rust и отладить её онлайн. Много заготовок программ разбиты по темам. rustbyexample

В июне 2015 вышла книга Rust Essentials по версии 1.0.

вторник, 16 июня 2015 г.

Файлы, ошибки...

Пробую создать файл как в примере:

use std::io::prelude::*;
use std::fs::File
pub fn write() {
 let mut f = try!(File::create("foo.txt"));
} 

Получаю ошибку "error: mismached types". Возвращается тип core::result::Result вместо юнита ().

Оказывется, макрос try! может вернуть такой тип и он будет возвращаемым типом функции write.

https://doc.rust-lang.org/stable/std/result/

Рабочим является такой вариант:

use std::io;
use std::fs;

pub fn write() -> io::Result<()> {

    let mut f = try!(fs::File::create("foo.txt"));
    Ok(())

}


Без точки с запятой после Ok(). Файл создался в корневой папке проекта.

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




пятница, 15 мая 2015 г.