Содержание
1. Выражения
В Rust почти все фигурные скобки являются выражением, это значит, что они могут вернуть какой-то результат. Такое поведение не всегда нужно, чтобы ничего не возвращать добавьте ; в конец.
Выражения в блоке могут использоваться в качестве r-values значений, а последнее будет назначено как l-value.
* Что такое Rvalue и Lvalue читайте здесь.
Но, если последнее выражение в блоке будет точкой с запятой, результат будет равен пустому кортежу: ().
fn main() { let x = 5u; let y = { let x_squared = x * x; let x_cube = x_squared * x; // `y` будет этим выражением x_cube + x_squared + x }; let z = { // Если в конце стоит точка с запятой, то выражение не // присваивается, вместо него переменная `z` будет содержать `()` 2 * x; }; println!("x is {}", x); println!("y is {}", y); println!("z is {}", z); }
2. Операторы ветвления
Ветвление if-else
является C-подобным. В отличие от C, логическое условие не должно быть заключено в круглые скобки, а каждому условию необходимы фигурные скобки.
if-else
так же является выражением; и, из-за типобезопасности Rust, все ветви должны возвращать значение одного типа.
fn main() { let n = 5i; if n < 0 { print!("{} is negative", n); } else if n > 0 { print!("{} is positive", n); } else { print!("{} is zero", n); } let big_n = if n < 10 && n > -10 { println!(", and is a small number, increase ten-fold"); // Это выражение возвращает `int` 10 * n } else { println!(", and is a big number, reduce by two"); // Это выражение должно возвращать `int` n / 2 // ^ Попробуйте поставить точку с запятой }; println!("{} -> {}", n, big_n); }
3. Петли
Ключевое слово loop
в Rust создает бесконечный цикл (петлю).
Оператор break
позволяет выйти из петли в любое время, а continue
пропускает оставшуюся часть итерации и начинает выполнение заново.
fn main() { let mut count = 0u; println!("Let's count until infinity!"); // Бесконечная петля loop { count += 1; if count == 3 { println!("three"); // Пропустим оставшуюся часть этой итерации continue; } println!("{}", count); if count == 5 { println!("OK, that's enough"); // Выход из этой петли break; } } }
3.1 Вложенность и ярлыки
Петли можно делать вложенными. В таких случаях они должны содержать какой-то ярлык 'label
, а операторы break/continue
писаться с этим ярлыком.
fn main() { 'outer: loop { println!("Entered the outer loop"); 'inner: loop { println!("Entered the inner loop"); // Выход из внутренней петли //break; // Выход из внешней петли break 'outer; } println!("This point will never be reached"); } println!("Exited the outer loop"); }
4. Цикл while
Тело цикла будет выполняться пока условие в while
не будет истинно.
Давайте напишем fizzbuzz используя цикл while
.
fn main() { // Переменная для счетчика let mut n = 1u; // Итерируем пока `n` меньше 101 while n < 101 { if n % 15 == 0 { println!("fizzbuzz"); } else if n % 3 == 0 { println!("fizz"); } else if n % 5 == 0 { println!("buzz"); } else { println!("{}", n); } // Увеличиваем счетчик n += 1; } }
5. Цикл for и функция range
Конструкцию for in
можно использовать для перебора Iterator
и генератора ленивых значений (подробнее позже). Функция range
это один из наиболее распространенных итераторов. range(a, b)
будет выдавать значения от a до b-1 изменяя шаг на единицу.
Давайте напишем fizzbuzz используя for
вместо while
.
fn main() { // `n` будет принимать значения: 1, 2, ..., 100 в каждой итерации for n in range(1u, 101) { if n % 15 == 0 { println!("fizzbuzz"); } else if n % 3 == 0 { println!("fizz"); } else if n % 5 == 0 { println!("buzz"); } else { println!("{}", n); } } }
6. Функции
Функции объявляются при помощи ключевого слова fn. Аргументы аннотируются типами, как и переменные; и, если функция возвращает значение, возвращаемый тип должен быть указан после стрелки ->.
Последнее выражение в теле функции будет использовано как возвращаемое значение или можно использовать оператор return
для раннего возврата значения из функции, даже из внутреннего цикла или условного оператора.
Перепишем fizzbuzz используя функции!
// Функция, которая возвращает булево значение fn is_divisible_by(lhs: uint, rhs: uint) -> bool { // Некорректный входной параметр, сразу выходим из функции if rhs == 0 { return false; } // Это выражение, так что ключевое слово `return` тут не нужно lhs % rhs == 0 } // Функции, которые не возвращают значение, на самом деле возвращают тип `()` fn fizzbuzz(n: uint) -> () { if is_divisible_by(n, 15) { println!("fizzbuzz"); } else if is_divisible_by(n, 3) { println!("fizz"); } else if is_divisible_by(n, 5) { println!("buzz"); } else { println!("{}", n); } } // Если функция возвращает `()`, возвращаемый тип можно опустить fn fizzbuzz_to(n: uint) { for n in range(1, n + 1) { fizzbuzz(n); } } fn main() { fizzbuzz_to(100); }
6.1 Неиспользуемые функции
Компилятор обеспечивает dead_code
lint, чтобы предупреждать о неиспользованных функциях. Можно добавить атрибут #[allow(dead_code)]
, чтобы отключить уведомление.
fn used_function() {} // `#[allow(dead_code)]` это атрибут, который отключает предупреждение `dead_code` #[allow(dead_code)] fn unused_function() {} fn noisy_unused_function() {} // ИСПРАВЬТЕ ^ Добавьте атрибут, чтобы отключить предупреждение fn main() { used_function(); }
Обратите внимание, что в реальных программах, вы должны устранить «мертвый код». В этих примерах мы его используем для демонстрации.
Заключение
Присоединяйтесь к google-группе: Rust по-русски для получения дополнительной информации по этому языку.
Можно помочь с переводом на Github: github.com/eg0r/rust-by-example
Все замечания, ошибки или неточности отправляйте мне в почту.
ссылка на оригинал статьи http://habrahabr.ru/post/233621/
Добавить комментарий