Rust на примерах — страница 61 из 65

הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

$ ./args 1 2 3

Мой путь ./args.

У меня 3 аргумента: ["1", "2", "3"].

Крейты

В качестве альтернативы, существует несколько крейтов, которые предоставляют дополнительную функциональность при создании приложений командной сроки. Rust Cookbook показывает лучшие практики, как использовать один из самых популярных крейтов для аргументов командной строки, clap.

Парсинг аргументов

Сопоставление может быть использовано для разбора простых аргументов:

use std::env;

fn increase(number: i32) {

println!("{}", number + 1);

}

fn decrease(number: i32) {

println!("{}", number - 1);

}

fn help() {

println!("usage:

match_args 

Проверяет является ли данная строка ответом.

match_args {{increase|decrease}} 

Увеличивает или уменьшает число на 1.");

}

fn main() {

let args: Vec = env::args().collect();

match args.len() {

// аргументы не переданы

1 => {

println!("Я - 'match_args'. Попробуйте передать аргументы!");

},

// передан один аргумент

2 => {

match args[1].parse() {

Ok(42) => println!("Это ответ!"),

_ => println!("Это не ответ."),

}

},

// переданы одна команда и один аргумент

3 => {

let cmd = &args[1];

let num = &args[2];

// parse the number

let number: i32 = match num.parse() {

Ok(n) => {

n

},

Err(_) => {

eprintln!("ошибка: второй аргумент не является числом");

help();

return;

},

};

// парсим команду

match &cmd[..] {

"increase" => increase(number),

"decrease" => decrease(number),

_ => {

eprintln!("ошибка: неизвестная команда");

help();

},

}

},

// все остальные случаи

_ => {

// показываем сообщение с помощью

help();

}

}

}

הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

$ ./match_args Rust

Это не ответ.

$ ./match_args 42

Это ответ!

$ ./match_args do something

ошибка: второй аргумент не является числом

usage:

match_args 

Проверяет является ли данная строка ответом.

match_args {increase|decrease} 

Увеличивает или уменьшает число на 1.

$ ./match_args do 42

ошибка: неизвестная команда

usage:

match_args 

Проверяет является ли данная строка ответом.

match_args {increase|decrease} 

Увеличивает или уменьшает число на 1.

$ ./match_args increase 42

43

Foreign Function Interface

Rust предоставляет интерфейс внешних функций (Foreign Function Interface, FFI) к библиотекам, написанным на языке С. Внешние функции должны быть объявлены внутри блока extern и аннотированы при помощи атрибута #[link], который содержит имя внешней библиотеки.

use std::fmt;


// Этот extern-блок подключает библиотеку libm

#[link(name = "m")]

extern {

// Это внешняя функция, которая считает квадратный корень

// комплексного числа одинарной точности

fn csqrtf(z: Complex) -> Complex;


fn ccosf(z: Complex) -> Complex;

}


// Так как вызовы внешних функций считаются unsafe,

// принято писать над ними обёртки.

fn cos(z: Complex) -> Complex {

unsafe { ccosf(z) }

}


fn main() {

// z = -1 + 0i

let z = Complex { re: -1., im: 0. };


// вызов внешней функции - unsafe операция

let z_sqrt = unsafe { csqrtf(z) };


println!("квадратный корень от {:?} равен {:?}", z, z_sqrt);


// вызов безопасного API в котором находится unsafe операция

println!("cos({:?}) = {:?}", z, cos(z));

}


// Минимальная реализация комплексного числа одинарной точности

#[repr(C)]

#[derive(Clone, Copy)]

struct Complex {

re: f32,

im: f32,

}


impl fmt::Debug for Complex {

fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {

if self.im < 0. {

write!(f, "{}-{}i", self.re, -self.im)

} else {

write!(f, "{}+{}i", self.re, self.im)

}

}

}

Тестирование

Rust - это язык программирования, который очень заботится о корректности и включает в себя поддержку написания тестов программного обеспечения в самом языке.