код на Rust

Вопросы написания собственного программного кода (на любых языках)

Модератор: Olej

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: код на Rust

Непрочитанное сообщение Olej » 14 фев 2018, 16:59

Olej писал(а): И вот где оно это всё после обновления оказывается:
На 3 уровня выше (и дальше вглубь) от каталога проекта, где выполнялся build:

Код: Выделить всё

[olej@dell complex]$ pwd
/home/olej/2018_WORK/own.BOOKs/ManyLang/rust/rust-rosetta-master/tasks/arithmetic/complex

[olej@dell complex]$ ls ../../../target/debug/
build  complex  complex.d  deps  examples  incremental  native

[olej@dell complex]$ ls ../../../target/debug/deps/
complex-d31843c062db5acc              libnum_iter-ed0d7c6d5e519bf5.rlib
liblibc-e5d15e2dd1f6d9b4.rlib         libnum_rational-c5118a8ab68d2e88.rlib
libnum-81c9c05433349247.rlib          libnum_traits-7ac63177061a0ce2.rlib
libnum_bigint-d1cc116193b9aca8.rlib   librand-ac0d6e7c8ce6a500.rlib
libnum_complex-3aae3620f5df861d.rlib  librustc_serialize-3daf7fbbbeb27b1f.rlib
libnum_integer-57c79c389e9bc502.rlib

[olej@dell deps]$ file libnum-81c9c05433349247.rlib 
libnum-81c9c05433349247.rlib: current ar archive
Это всё становится понятно по логике происходящего (связывание с библиотеками) ... но совершенно непонятно, пока, каким образом связываются (по путям, видимости) эти каталоги? ... посредством чего? где определено?
И 2-й вопрос: как увязать с библиотеками ручную, консольной командой, компиляцию?

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: код на Rust

Непрочитанное сообщение Olej » 14 фев 2018, 17:17

Olej писал(а):И 2-й вопрос: как увязать с библиотеками ручную, консольной командой, компиляцию?
Сложилось! :lol: (здесь файл complex.rs - совершенно другой, копия, в произвольном рабочем каталоге):

Код: Выделить всё

[olej@dell rust]$ rustc -L ~/2018_WORK/own.BOOKs/ManyLang/rust/rust-rosetta-master/target/debug/deps complex.rs -o complex1

[olej@dell rust]$ ls complex*
complex1  complex.rs

[olej@dell rust]$ ./complex1 
a = -4+5i
b = 1+1i
a + b = -3+6i
a * b = -9+1i
1 / a = -0.09756097-0.12195122i
-a = 4-5i
conj a = -4-5i

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: код на Rust

Непрочитанное сообщение Olej » 14 фев 2018, 18:22

Olej писал(а): И вот где оно это всё после обновления оказывается:
Все крейты по умолчанию подтягиваются вот отсюда: https://github.com/rust-lang/crates.io-index ... но источники могут быть и добавлены как-то в конфигурациях.
Там всё очень бурно обновляется:
Latest commit c7f9943 15 minutes ago
Искать для себя имеющиеся библиотеки так:

Код: Выделить всё

[olej@dell rust]$ cargo search num
    Updating registry `https://github.com/rust-lang/crates.io-index`
num = "0.1.42"                      # A collection of numeric types and traits for Rust, including bigint, complex, rational, range iterators, generic integers, and …
resource_proof = "0.6.0"            # A 'proof' of bandwidth, cpu and storage for nodes in a decentralised network.
concurrent_prime_sieve = "0.3.3"    # Tools for generating filters and collections with primes concurrently. Rust implementation of the Sieve of Atkin. This implemen…
num-cmp = "0.1.0"                   # Comparison between differently typed numbers
num-digitize = "0.4.2"              # Converts integer of type N into Vec<i8> containing its digits.
num-derive = "0.1.44"               # Numeric syntax extensions
timi = "0.2.1"                      # A visual template instantiation machine interpreter to understand how lazy functional programming languages evaluate
num-traits = "0.2.0"                # Numeric traits for generic mathematics
num_cpus = "1.8.0"                  # Get the number of CPUs on a machine.
num-complex = "0.1.42"              # Complex numbers implementation for Rust
... and 155 crates more (use --limit N to see more)
Правда, как установить библиотеку по произвольному пути я пока не понимаю:

Код: Выделить всё

[olej@dell fibo_cargo]$ cargo install --root ./tmp num-complex
    Updating registry `https://github.com/rust-lang/crates.io-index`
  Installing num-complex v0.1.42
error: specified package has no binaries

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: код на Rust

Непрочитанное сообщение Olej » 14 фев 2018, 23:36

Решаем конкретную задачу ... аналогичную как на Swift и на Tcl:
- определение координат 2D точек, составных [X,Y] из 2-х Double значений
- ввод покоординатно таких чисел с терминала
- с контролем ошибок ввода: <2 или >2 чисел введено, не числовое значение, отработку конца ввода EOF=^D и т.д.
На Rust:

Код: Выделить всё

use std::io::stdin;
use std::io::{self, Write};

struct Point<T> {
    x: T,
    y: T,
}

fn main() {
   'coord: loop {
      print!( "координаты в формате X Y : " );
      let _ = io::stdout().flush();
      let mut input = String::new();
      let res = stdin().read_line( &mut input ).unwrap();
      if 0 == res {                                   // ^D - EOF
         println!( "" );
         break; 
      }
      let words = input.split_whitespace()
          .take( 5 )
          .map( |s| s.parse().ok() )
          .collect::<Vec<Option<f32>>>();
      if 0 == words.len() { break; }                  // Enter
      if words.len() < 2 {
         println!( "мало чисел" );
         continue;
      }
      if words.len() > 2 {
         println!( "много чисел" );
         continue;
      }
      for i in 0 .. words.len() {
         if None == words[ i ] {  
            println!( "не число" );
            continue 'coord;
         }
      }
      let p = Point::<f32> { x:words[ 0 ].unwrap(),   // p is of type Point<f32>
                             y:words[ 1 ].unwrap() };
      println!("[{},{}]", p.x, p.y);
      
   }
   println!( "завершение ввода" ); 
}

Код: Выделить всё

[olej@dell rust]$ rustc 2Din.rs -A unused-variables -A dead-code -o 2Din

Код: Выделить всё

[olej@dell rust]$ ./2Din 
координаты в формате X Y : 1 2
[1,2]
координаты в формате X Y : .1 5.
[0.1,5]
координаты в формате X Y : -1.1 -2.2
[-1.1,-2.2]
координаты в формате X Y : 1.2.3 4.5
не число
координаты в формате X Y : 1a 3
не число
координаты в формате X Y : 2 3b
не число
координаты в формате X Y : 
завершение ввода
Вложения
2Din.rs
(1.21 КБ) 109 скачиваний

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: код на Rust

Непрочитанное сообщение Olej » 15 фев 2018, 01:28

Olej писал(а):Решаем конкретную задачу ...
Или, ещё интереснее, для моих целей (!), так:

Код: Выделить всё

extern crate num;
use std::io::stdin;
use std::io::{self, Write};
use num::complex::Complex;

fn main() {
   'coord: loop {
      print!( "координаты в формате X Y : " );
      let _ = io::stdout().flush();
      let mut input = String::new();
      let res = stdin().read_line( &mut input ).unwrap();
      if 0 == res {                                   // ^D - EOF
         println!( "" );
         break; 
      }
      let words = input.split_whitespace()
          .take( 5 )
          .map( |s| s.parse().ok() )
          .collect::<Vec<Option<f32>>>();
      if 0 == words.len() { break; }                  // Enter
      if words.len() < 2 {
         println!( "мало чисел" );
         continue;
      }
      if words.len() > 2 {
         println!( "много чисел" );
         continue;
      }
      for i in 0 .. words.len() {
         if None == words[ i ] {  
            println!( "не число" );
            continue 'coord;
         }
      }
      let c = Complex::new( words[ 0 ].unwrap(), words[ 1 ].unwrap() );
      println!( "{} | x={},y={}", c, c.re, c.im );
   }
   println!( "завершение ввода" ); 
}

Код: Выделить всё

[olej@dell rust]$ cat Makefile 
ROPT = -A unused-variables -A dead-code 
LIB = -L ~/2018_WORK/own.BOOKs/ManyLang/rust/rust-rosetta-master/target/debug/deps

%: %.rs
	rustc $(ROPT) $(LIB) -O $< -o $@

Код: Выделить всё

[olej@dell rust]$ make 2Dinc 
rustc -A unused-variables -A dead-code  -L ~/2018_WORK/own.BOOKs/ManyLang/rust/rust-rosetta-master/target/debug/deps -O 2Dinc.rs -o 2Dinc

Код: Выделить всё

[olej@dell rust]$ ./2Dinc
координаты в формате X Y : 1 2
1+2i | x=1,y=2
координаты в формате X Y : .1 5.
0.1+5i | x=0.1,y=5
координаты в формате X Y : 
завершение ввода
Вложения
2Dinc.rs
(1.15 КБ) 107 скачиваний

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: код на Rust

Непрочитанное сообщение Olej » 15 фев 2018, 10:52

О-очень интересная глава из документации, настолько интересная, что нельзя не сделать "зарубку" на память: Вызов кода на Rust из других языков:
Rust включает поддержку FFI в обоих направлениях: он легко может вызвать C код, и он так же легко, как и C код, может быть вызван извне. Rust сочетает в себе отсутствие сборщика мусора и низкие требования к среде исполнения, что делает Rust отличным кандидатом на роль вызываемого из других языков, когда нужны некоторые дополнительные возможности.
...
Ruby
...
Python
...
Node.js
И связанная тема: Интерфейс внешних функций (foreign function interface)

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: код на Rust

Непрочитанное сообщение Olej » 15 фев 2018, 16:41

Olej писал(а): Или, ещё интереснее, для моих целей (!), так:
И, наконец, приложение эквивалентное тому, что показывалось на многих других языках программирования - как это теперь выглядит на Rust... : ввод координат произвольного выпуклого многоугольника (N-угольника) + расчёт его периметра и площади.

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

1. Строим новый пустой проект и заходим в каталог проекта...

Код: Выделить всё

[olej@dell rust]$ cargo new triangle --bin
     Created binary (application) `triangle` project

[olej@dell triangle]$ pwd
/home/olej/2018_WORK/own.BOOKs/ManyLang/rust/triangle
2. Создаём пустой проект...

Код: Выделить всё

[olej@dell triangle]$ cargo build
    Updating registry `https://github.com/rust-lang/crates.io-index`
 Downloading num-iter v0.1.35
 Downloading num-rational v0.1.42
 Downloading num-integer v0.1.36
 Downloading num-traits v0.2.0
 Downloading num-bigint v0.1.43
 Downloading rand v0.4.2
 Downloading libc v0.2.36
   Compiling libc v0.2.36
   Compiling num-traits v0.2.0
   Compiling rustc-serialize v0.3.24
   Compiling rand v0.4.2
   Compiling num-integer v0.1.36
   Compiling num-iter v0.1.35
   Compiling num-bigint v0.1.43
   Compiling num-complex v0.1.42
   Compiling num-rational v0.1.42
   Compiling num v0.1.42
   Compiling triangle v0.1.0 (file:///home/olej/2018_WORK/own.BOOKs/ManyLang/rust/triangle)
    Finished dev [unoptimized + debuginfo] target(s) in 14.91 secs
3. Дописываю в манифест проекта Cargo.toml строку зависимости ([dependencies]) от crate (библиотеки):

Код: Выделить всё

[olej@dell triangle]$ cat Cargo.toml
[package]
name = "triangle"
version = "0.1.0"
authors = ["Olej <o.tsiliuric@yandex.ua>"]

[dependencies]
num = "0.1"
4. Теперь в src/main.rs проекта я могу вкопировать свой код и дальше его отрабатывать...

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: код на Rust

Непрочитанное сообщение Olej » 15 фев 2018, 16:47

Olej писал(а):4. Теперь в src/main.rs проекта я могу вкопировать свой код и дальше его отрабатывать...
В конечном итоге это отработалось вот в такое:

Код: Выделить всё

extern crate num;
use std::io::stdin;
use std::io::{self, Write};
use num::complex::Complex;

struct Polygon {
   v: Vec<Complex<f64>>,
}

impl Polygon {
   fn perimeter( &self ) -> f64 {
      let mut summa : f64 = 0.0;
      for n in 0 .. self.v.len() {
         let prev = if 0 == n { self.v.len() - 1 } else { n - 1 }; 
         summa += ( self.v[ n ] - self.v[ prev ] ).norm_sqr().sqrt(); 
      }      
      summa
   }
   fn square(  &self ) -> f64 {
      let mut summa : f64 = 0.0;
      for n in 1 .. self.v.len() - 1 {
         let ( r1, a1 ) = ( self.v[ n ] - self.v[ 0 ] ).to_polar();
         let ( r2, a2 ) = ( self.v[ n + 1 ] - self.v[ 0 ] ).to_polar();
         summa += r1 * r2 * ( a2 - a1 as f64 ).sin().abs() / 2.0;
      }      
      summa
   }
} 

fn main() {
   loop {
      let mut count = 1;
      let mut plg = Polygon { v : vec![] };
      println!( "координаты вершин в формате: X Y (^D конец ввода)" );         
      'point: loop { 
         print!( "вершина № {} : ", count );         
         let _ = io::stdout().flush();
         let mut input = String::new();
         let res = stdin().read_line( &mut input ).unwrap();
         if 0 == res {                                   // ^D - EOF
            print!( "\r" );
            break; 
         }
         let words = input.split_whitespace().take( 5 )
             .map( |s| s.parse().ok() )
             .collect::<Vec<Option<f64>>>();
         if 0 == words.len() { break; }                  // Enter
         if words.len() != 2 {
            println!( "{} чисел", if words.len() < 2 { "мало" } else { "много" } );
            continue;
         }
         for i in 0 .. words.len() {
            if None == words[ i ] {  
               println!( "не число" );
               continue 'point;
            }
         }
         plg.v.push( Complex::new( words[ 0 ].unwrap(), words[ 1 ].unwrap() ) );
         count += 1;
      }
      if plg.v.len() < 3 { break; }
      println!( "периметр = {:.*}", 3, plg.perimeter() );
      println!( "площадь = {:.*}", 3,  plg.square() );
   }      
   println!( "завершение ввода" ); 
}
Построение приложения:

Код: Выделить всё

[olej@dell src]$ cargo build
   Compiling triangle v0.1.0 (file:///home/olej/2018_WORK/own.BOOKs/ManyLang/rust/triangle)
    Finished dev [unoptimized + debuginfo] target(s) in 1.17 secs
А выполняется это так:

Код: Выделить всё

[olej@dell src]$ cargo run
   Compiling triangle v0.1.0 (file:///home/olej/2018_WORK/own.BOOKs/ManyLang/rust/triangle)
    Finished dev [unoptimized + debuginfo] target(s) in 1.25 secs
     Running `/home/olej/2018_WORK/own.BOOKs/ManyLang/rust/triangle/target/debug/triangle`
координаты вершин в формате: X Y (^D конец ввода)
вершина № 1 : 0 0
вершина № 2 : 0 1
вершина № 3 : 1 0
периметр = 3.414
площадь = 0.500
координаты вершин в формате: X Y (^D конец ввода)
вершина № 1 : 0 0
вершина № 2 : 1 0
вершина № 3 : 1 1
вершина № 4 : 1 0
периметр = 4.000
площадь = 1.000
координаты вершин в формате: X Y (^D конец ввода)
вершина № 1 : 1 2 3
много чисел
вершина № 1 : 1
мало чисел
вершина № 1 : 1 2a 
не число
вершина № 1 : 4b 3
не число
вершина № 1 : .5 .5
вершина № 2 : .1 1.5
вершина № 3 : .3 0
периметр = 3.129
площадь = 0.200
координаты вершин в формате: X Y (^D конец ввода)
завершение ввода
Вложения
triangle.rs
(2.16 КБ) 101 скачивание

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: код на Rust

Непрочитанное сообщение Olej » 15 фев 2018, 21:09

Olej писал(а): В конечном итоге это отработалось вот в такое:
В Rust много интересных возможностей...
Вот, например, кортежная (tuple) структура (через структуры реализуется ООП) без именования полей (последовательность полей может определяться их индексом). Переписанный таким образом пример:

Код: Выделить всё

extern crate num;
use std::io::stdin;
use std::io::{self, Write};
use num::complex::Complex;

struct Polygon( Vec<Complex<f64>> );  // кортежная структура

impl Polygon {
   fn perimeter( &self ) -> f64 {
      let mut summa : f64 = 0.0;
      for n in 0 .. self.0.len() {
         let prev = if 0 == n { self.0.len() - 1 } else { n - 1 }; 
         summa += ( self.0[ n ] - self.0[ prev ] ).norm_sqr().sqrt(); 
      }
      summa
   }
   fn square(  &self ) -> f64 {
      let mut summa : f64 = 0.0;
      for n in 1 .. self.0.len() - 1 {
         let ( r1, a1 ) = ( self.0[ n ] - self.0[ 0 ] ).to_polar();
         let ( r2, a2 ) = ( self.0[ n + 1 ] - self.0[ 0 ] ).to_polar();
         summa += r1 * r2 * ( a2 - a1 as f64 ).sin().abs() / 2.0;
      }
      summa
   }
} 

fn main() {
   loop {
      let mut count = 1;
      let mut plg = Polygon( vec![] );
      println!( "координаты вершин в формате: X Y (^D конец ввода)" );         
      'point: loop { 
         print!( "вершина № {} : ", count );         
         let _ = io::stdout().flush();
         let mut input = String::new();
         let res = stdin().read_line( &mut input ).unwrap();
         if 0 == res {                                   // ^D - EOF
            print!( "\r" );
            break; 
         }
         let words = input.split_whitespace().take( 5 )
             .map( |s| s.parse().ok() )
             .collect::<Vec<Option<f64>>>();
         if 0 == words.len() { break; }                  // Enter
         if words.len() != 2 {
            println!( "{} чисел", if words.len() < 2 { "мало" } else { "много" } );
            continue;
         }
         for i in 0 .. words.len() {
            if None == words[ i ] {  
               println!( "не число" );
               continue 'point;
            }
         }
         plg.0.push( Complex::new( words[ 0 ].unwrap(), words[ 1 ].unwrap() ) );
         count += 1;
      }
      if plg.0.len() < 3 { break; }
      println!( "периметр = {:.*}", 3, plg.perimeter() );
      println!( "площадь = {:.*}", 3,  plg.square() );
   }      
   println!( "завершение ввода" ); 
}
Сравните с предыдущим.

Код: Выделить всё

[olej@dell triangle]$ cargo build
   Compiling triangle v0.1.0 (file:///home/olej/2018_WORK/own.BOOKs/ManyLang/rust/triangle)
    Finished dev [unoptimized + debuginfo] target(s) in 1.18 secs
[olej@dell triangle]$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
     Running `target/debug/triangle`
координаты вершин в формате: X Y (^D конец ввода)
вершина № 1 : 0 0
вершина № 2 : 0 1
вершина № 3 : 1 1
вершина № 4 : 1 0
периметр = 4.000
площадь = 1.000
координаты вершин в формате: X Y (^D конец ввода)
вершина № 1 : 1
мало чисел
вершина № 1 : 3
мало чисел
вершина № 1 : 1 2 3
много чисел
вершина № 1 : 3a 4b
не число
завершение ввода
Вложения
trianglet.rs
(2.18 КБ) 90 скачиваний

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: код на Rust

Непрочитанное сообщение Olej » 16 фев 2018, 21:06

Olej писал(а):
A crate is a compilation unit in Rust. Whenever rustc some_file.rs is called, some_file.rs is treated as the crate file. If some_file.rs has mod declarations in it, then the contents of the module files would be inserted in places where mod declarations in the crate file are found, before running the compiler over it. In other words, modules do not get compiled individually, only crates get compiled.

A crate can be compiled into a binary or into a library. By default, rustc will produce a binary from a crate. This behavior can be overridden by passing the --crate-type flag to rustc.
10 Контейнеры
Контейнер (crate) — единица компиляции в языке Rust. Когда вызывается rustc some_file.rs, some_file.rs обрабатывается как файл контейнера. Если в some_file.rs есть декларация mod, то содержимое модуля будет объединено с файлом контейнера перед его компиляцией. Другими словами, модули не собираются отдельно, собираются лишь контейнеры.

Контейнер может быть скомпилирован в исполняемый файл или в библиотеку. По умолчанию, rustc создаёт исполняемый файл из контейнера. Это поведение может быть изменено добавлением флага --crate-type к rustc.

Ответить

Вернуться в «Программирование»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 8 гостей