Как бы вы написали эквивалент этого цикла C ++ в Rust - PullRequest
0 голосов
/ 02 сентября 2018

Циклы for в Rust немного отличаются от циклов в языках C-стиля. Я пытаюсь понять, смогу ли я достичь того же результата ниже в Rust. Обратите внимание на условие, где i ^ 2

for (int i = 2; i * i < n; i++)
{
    // code goes here ...
}

Ответы [ 2 ]

0 голосов
/ 03 сентября 2018

Предложение take_while из ответа zwol является наиболее идиоматичным и, следовательно, обычно лучшим выбором. Вся информация о цикле хранится вместе в одном выражении, а не смешивается в теле цикла.

Однако, самая быстрая реализация предназначена для предварительного вычисления квадратного корня из n (на самом деле это странный вид округленного вниз квадратного корня). Это позволяет избегать сравнения на каждой итерации, поскольку вы знаете, что это всегда конечное значение i.

let m = (n as f64 - 0.5).sqrt() as _;
for i in 2 ..= m {
    // code goes here
}

В качестве примечания я попытался сравнить эти разные циклы. take_while был самым медленным. Версия, которую я только что предложил, всегда сообщала 0 ns/iter, и я не уверен, что это просто из-за того, что какой-то код оптимизирован до такой степени, что он вообще не работает, или он действительно слишком быстрый для измерения. Для большинства случаев разница не должна быть важной.

0 голосов
/ 02 сентября 2018

Вы всегда можете сделать буквальный перевод в цикл while.

let mut i = 2;
while i * i < n {
    // code goes here
    i += 1;
}

Вы также всегда можете написать цикл for в бесконечном диапазоне и выполнить произвольное условие:

for i in 2.. {
    if i * i >= n { break }
    // code goes here
}

Для этой конкретной проблемы вы также можете использовать take_while, но я не знаю, действительно ли это более читабельно, чем разрыв цикла for. Это будет иметь больше смысла как часть более длинной цепочки "комбинаторов".

for i in (2..).take_while(|i| i * i < n) {
    // code goes here
}
...