LINUX.ORG.RU

Привычки и Rust

 , ,


0

4

На сишке привык циклы с предусловием писать так:

while(k--) {
   ...
}

В Rust это превращается (насколько я понимаю) в

while k > 0 {
    k -= 1;
    ...
}

Что не совсем красиво и неочевидно, с первого взгляда.
Как принято в Rust записывать циклы с предусловием, чтобы красиво и понятно?

★★★★★

Проходил я тут мимо и понял, что пребывание на ЛОРе меня совсем испортило. Я про Haskell, «побочные эффекты» и сравнительно показательный Жаваскрипт. Сначала один вроде неглупый (сужу по предыдущему опыту общения) участник вместо того, чтобы написать кот самому, выкладывает какой-то бред с Розеттакода. Такое ощущение, что автор того хаскельного кода никогда на функциональных языках не писал, и поэтому накостылил эту императивноподобную убогость на СТРефах с эмуляцией мутабельности. Потом другой участник видя это, верит, что это и есть настоящий Haskell, пишет свое видение вопроса и начинает делать свои глобальные выводы.... Вот полный перевод на хаскель той жаваскриптовой реализации Брезенхайма, чистая функция. И демонстрация ее работы - вывод растровых значений в консоль и отрисовка отрезка в отдельном графическом окне через глатский опЕнгл...

import Graphics.Rendering.OpenGL
import Graphics.UI.GLUT

--------- Чистый Брезенхайм

line x0 x1 y0 y1 = takeWhile (not . (== (x1, y1)))
                   . map fst . iterate f $ ((x0, y0), e) where
    [dx, dy] = map abs    [x1 - x0, y1 - y0]
    [sx, sy] = map signum [x1 - x0, y1 - y0]
    e | dx > dy = dx | otherwise = -dy

    tx ((x, y), e) = ((x+sx, y), e - dy*2)
    ty ((x, y), e) = ((x, y+sy), e + dx*2)

    f (p,e) | e > -dx*2 && e < dy*2 = ty . tx $ (p,e)
            | e > -dx*2 = tx (p,e)
            | e <  dy*2 = ty (p,e)
            | otherwise = (p,e)

norm k (x, y) = (f x / f k, f y / f k) where f = fromIntegral

--------- Вывод точек отрезка и отрисовка в окне

main = do
    let ps = line 2 12 6 2
    print ps
    _ <- getArgsAndInitialize
    _ <- createWindow "Bresenham"
    displayCallback $= display (map (norm 15) ps)
    mainLoop

display ps = do
    clear [ColorBuffer]
    pointSize $= 3
    renderPrimitive Points $ do
        currentColor $= Color4 1 1 1 1
        mapM_ vertex $ map (\(x,y) -> Vertex2 (x :: GLdouble) (y :: GLdouble)) ps
    flush
Ivana
()
Ответ на: комментарий от Deleted

Кстати, раз уж такая пьянка. Можно ли в Rust, Swift или другом современном ЯП при помощи for-in итерироваться через массив при том, что иногда в зависимости от содержимого элемента нужно взять следующий и обработать его по-особенному?

Если необходим только 1 итератор, то через for-in не получится, но можно поступить так:

fn main() {
    let arr = [1, 2, 2, 3];
    let mut iter = arr.iter().peekable();
    while let Some(item) = iter.next() {
        if *item == 2 {
            let peek = iter.peek().unwrap();
            println!("after 2: {}", peek);
        }
    }
}
Вывод:
after 2: 2
after 2: 3
`.peek()` позволяет взять следующий элемент без перехода к следующей итерации.

shaiZaigh
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.