Информация об изменениях

Сообщение Re[4]: Откуда эта лютая любовь к знаковым целым? от 05.05.2020 17:43

Изменено 05.05.2020 18:49 netch80

Re[4]: Откуда эта лютая любовь к знаковым целым?
Здравствуйте, T4r4sB, Вы писали:

TB>От нуля до N-1. На беззнаковых такой перебор записывается довольно неестественно.

TB>Знак это дополнительный маркер, что мы вышли за диапазон в другую сторону.

Я буквально пару дней назад в похожую тему вцепился на хабре в треде про Rust, мне ответили:

=== cut here ===
Таким образом, для того, чтобы определить, какой код вызывается на каждой итерации цикла, нужно смотреть реализацию метода Range::next_back:

impl<A: Step> DoubleEndedIterator for ops::Range<A> {
    fn next_back(&mut self) -> Option<A> {
        if self.start < self.end {
            self.end = self.end.sub_one();
            Some(self.end.clone())
        } else {
            None
        }
    }
    // ...
}


Как видно из кода, в структуре хранятся начало и конец диапазона, а так как диапазон не включает верхнюю границу, то верхняя граница уменьшается на единицу перед тем, как она возвращается, а критерием остановки является условие равенства (в общем случае — превосходства) нижней и верхней границы.
=== end cut ===

В чуть более сложном формате цикла, чем стандартный для C, такое сделать можно, но напрямую в стандартном — нет (надо как минимум в начале тела цикла делать выборку того, что тут описали как Some, из объекта итератора).
Re[4]: Откуда эта лютая любовь к знаковым целым?
Здравствуйте, T4r4sB, Вы писали:

TB>От нуля до N-1. На беззнаковых такой перебор записывается довольно неестественно.

TB>Знак это дополнительный маркер, что мы вышли за диапазон в другую сторону.

Я буквально пару дней назад в похожую тему вцепился на хабре в треде про Rust, мне ответили:

=== cut here ===
Таким образом, для того, чтобы определить, какой код вызывается на каждой итерации цикла, нужно смотреть реализацию метода Range::next_back:

impl<A: Step> DoubleEndedIterator for ops::Range<A> {
    fn next_back(&mut self) -> Option<A> {
        if self.start < self.end {
            self.end = self.end.sub_one();
            Some(self.end.clone())
        } else {
            None
        }
    }
    // ...
}


Как видно из кода, в структуре хранятся начало и конец диапазона, а так как диапазон не включает верхнюю границу, то верхняя граница уменьшается на единицу перед тем, как она возвращается, а критерием остановки является условие равенства (в общем случае — превосходства) нижней и верхней границы.
=== end cut ===

В чуть более сложном формате цикла, чем стандартный для C, такое сделать можно, но напрямую в стандартном — нет (надо как минимум в начале тела цикла делать выборку того, что тут описали как Some, из объекта итератора). Постдекремент в условии проверки — вариация на то же.