from &str to &[_]

46 views
Skip to first unread message

gig kaz

unread,
Dec 18, 2014, 9:33:58 AM12/18/14
to rust-r...@googlegroups.com
Добрый день, в процессе изучения rust возникла такая задача:

На вход поступает строка (String), которая должна служить seed-ом для SeedableRng.
let mut res = String::new();
...
//let seed: &[_] = &[1, 2, 3, 4]; // этот seed работает
let seed
: &[_] = res.as_slice(); // этот seed не работает
let mut rng: StdRng = SeedableRng::from_seed(seed);


При компиляции со вторым сидом - ошибка:
error: the trait `rand::SeedableRng<&[u8]>` is not implemented for the type `_`

Как из ошибки видно - трейт SeedableRng не имеет имплементации для типа _. Однако, если взять закомментированный сид, то все ok, хотя там вроде тоже явно указан тип _ слайса.

Vladimir Matveev

unread,
Dec 18, 2014, 4:11:02 PM12/18/14
to gig kaz, rust-r...@googlegroups.com
Добрый вечер!

Ваша проблема заключается в следующем. Вот список типов, реализующих
трейт `SeedableRng`:

impl<'a> SeedableRng<&'a [uint]> for StdRng
impl SeedableRng<&'a [u32]> for IsaacRng
impl SeedableRng<&'a [u64]> for Isaac64Rng
impl SeedableRng<&'a [u32]> for ChaChaRng
impl<S, R: SeedableRng<S>, Rsdr: Reseeder<R> + Default>
SeedableRng<(Rsdr, S)> for ReseedingRng<R, Rsdr>
impl SeedableRng<[u32, ..4]> for XorShiftRng

Вы можете его посмотреть в документации [1].

Метод `SeedableRng::from_seed()` возвращает `Self`, т.е. значение
типа, реализующего трейт. Но, как видно, `StdRng` реализует этот трейт
с параметром `&[uint]`. Это означает, что чтобы получить `StdRng`, вам
нужно передать в `from_seed()` слайс типа `&[uint]`, не `&[u8]`.
Поэтому напрямую `String` не может быть зерном для `StdRng`. Вам
понадобится либо преобразовать каждый байт строки в `uint` по одному и
собрать результат в вектор:

let seed: Vec<_> = seed.as_bytes().iter().map(|&b| b as uint).collect();

Либо вы можете преобразовать слайс байтов напрямую в слайс uint'ов с
помощью `std::mem::transmute()` и `std::raw::Slice`, заранее
убедившись, что длина байтового слайса нацело делится на
`std::mem::size_of::<uint>()`:

assert!(seed.as_bytes().len() % mem::size_of::<uint>() == 0);
let seed: &[uint] = unsafe { mem::transmute(raw::Slice {
data: seed.as_bytes().as_ptr() as *const uint,
len: seed.as_bytes().len() / mem::size_of::<uint>()
}) };

[1]: http://doc.rust-lang.org/std/rand/trait.SeedableRng.html

18 декабря 2014 г., 15:33 пользователь gig kaz <cht...@gmail.com> написал:
> --
> Вы получили это сообщение, поскольку подписаны на группу "Rust по-русски".
> Чтобы отменить подписку на эту группу и больше не получать от нее сообщения,
> отправьте письмо на электронный адрес
> rust-russian...@googlegroups.com.
> Чтобы посмотреть обсуждение на веб-странице, перейдите по ссылке
> https://groups.google.com/d/msgid/rust-russian/c0a06e21-bc8e-4484-994d-099f26afcf56%40googlegroups.com.
> Чтобы настроить другие параметры, перейдите по ссылке
> https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages