Перегрузка функций по параметрам

В Rust, по релизиозно-техническим причинам не хотят добавлять перегрузку функций по параметрам. Фактически, доступен только вариант из Си с созданием кучи функций с разными именами. На мой взгляд, это просто дико не удобно. Немного подумав, нашел не очень красивый, но работающий обходной вариант:

enum foo_param {
    i(int),
    s(str)
}

fn foo(param: foo_param) {
    alt param {
        i(int_val) {
            io::println(#fmt("foo was called with int == %d", int_val));
        }
        s(str_val) {
            io::println(#fmt("foo was called with str == %s", str_val));
        }
    }
}

fn main() {
    foo(i(10));
    foo(s("test"));
}

Continue reading

Когнитивный диссонанс

Вчера я был поражен на столько, что усомнился в том, во что верил уже лет 10. А именно в том, что при выравнивании 8, размер структур с полями {u64, u32, u16} и {u8, u32, u16} будет одинаков, т.е. равен 16. А ведь приложение собранное Rust утверждает что в первом случае размер 16, что и следовало ожидать, а во втором 12(!!!).

type tuple_type1 = (u64, u32, u16);
type tuple_type2 = (u8, u32, u16);

fn main() {
    io::println(#fmt("size of tuple_type1 = %u, size of tuple_type2 = %u",
        sys::size_of::<tuple_type1>(), sys::size_of::<tuple_type2>()));
    io::println(#fmt("align of tuple_type1 = %u, align of tuple_type2 = %u",
        sys::align_of::<tuple_type1>(), sys::align_of::<tuple_type2>()));
}

Содержимое консоли:

> ./main
size of tuple_type1 = 16, size of tuple_type2 = 12
align of tuple_type1 = 8, align of tuple_type2 = 8

Continue reading

Юнит-тесты и Rust

ИДея написания интегрированных юнит-тестов в Rust мне очень понравилась. Суть в том, что код тестов пишется не где-то сбоку, а в одном и том же файле что и основной рабочий код. И это еще не все! В процессе сборке, при помощи ключа компилятора –test можно запустить их на выполнение и посмотреть результаты их работы. Причем, совершенно не важно то, что у модуля нет функции main, она будет доавленна автоматически.
На практике это выглядит так:

fn foo() -> uint {
    ret 42;
}

#[test]
fn test_foo() {
    let foo_val = foo();

    assert foo_val != 0u;
}

Собираем и смотрим:

> rustc --test test.rc
> ./test
running 1 tests
test test_foo ... ok

result: ok. 1 passed; 0 failed; 0 ignored

На мой взгляд, реализация тестирования в Rust претендует на гордое звание идеальная!

**char to str

С документацией по Rust на данный момент не очень, зато в почтовой рассылке rust-dev@mozilla.org на вопросы отвечают очень быстро. Пусть и дают примеры с ошибками
Сейчас я пишу враппер для libevent, правильнее сказать начал писать. С первой же функцией, которую я выбрал как наиболее простую и ни на что не завязанную, я натолкнулся на вопрос с преобразованием массива Си строк в массив Rust строк.
Для начала пишем прототип функции event_get_supported_methods из libevent и объясняем Rust с какой библиотекой линковаться.

import libc::c_char;

#[link_name = "event"]
native mod c {
    fn event_get_supported_methods() -> **libc::c_char;
}

Теперь сам метод, где нам требуется перекодировка: Continue reading