La rouille est-elle si terrible qu'elle est peinte

Il y a quelque temps, j'ai commencé à comprendre la nécessité de diversifier mon expérience de programmation exclusivement en C #. Après quelques études sur différentes options, telles que Haskell, Scala, Rust et quelques autres, le choix s'est porté sur cette dernière. Au fil du temps, j'ai commencé à faire attention à ce que Rust soit de plus en plus annoncé uniquement comme un «langage système», qui est nécessaire pour les compilateurs complexes et les systèmes surchargés, avec des exigences particulières pour la sécurité et le multithreading, et Go / Python / Java / ..., alors que j'ai apprécié et utilisé avec succès en remplacement de mon cheval de bataille C #.



Dans cet article, je voulais expliquer pourquoi je considère cette tendance comme nuisible en général et pourquoi Rust est un bon langage à usage général qui peut être utilisé pour tout type de projets, en commençant par tous les microservices et en terminant par les scripts de routine quotidiens.


Présentation


Pourquoi, en fait, apprendre une nouvelle langue, d’autant plus compliquée? Il me semble que la réponse à l'article «Conquérir la médiocrité» est la plus proche de la vérité, à savoir:


Tout le monde sait que l'écriture manuelle de l'ensemble du programme en langage machine est une erreur. Mais ils sont beaucoup moins susceptibles de comprendre qu'il existe un principe plus général: s'il y a un choix de plusieurs langues, il est erroné de programmer sur autre chose que la plus puissante, si le choix n'est pas affecté par d'autres raisons.

Plus la langue est complexe, plus les phrases élaborées avec son aide sont riches et mieux elle peut exprimer le sujet souhaité. Parce que les concepts ne sont généralement étudiés qu'une seule fois et appliqués de manière répétée, c'est beaucoup plus rentable du point de vue d'investir votre propre temps pour étudier toutes sortes de mots effrayants comme «transformateurs monadiques» (et aussi, de préférence, leur signification), puis pour économiser votre force mentale et les dépenser pour quelque chose de plus agréable. Et c'est donc très triste de voir la tendance de certaines entreprises à faire des langages spécialement «simplifiés». En conséquence, le vocabulaire de ces langues est beaucoup plus petit, et il n'est pas difficile de l'apprendre, mais ensuite lire les programmes «à moi pour acheter des oignons» est très difficile, sans parler des interprétations ambiguës possibles.


Les bases


Comment un débutant apprend-il généralement à connaître un langage de programmation? Il google le livre de langue le plus populaire, le sort et commence à lire. En règle générale, il contient HelloWorld, des instructions pour installer le compilateur, puis des informations de base sur la langue avec une complication progressive. Dans le cas de rasta, il s'agit d'un salaud , et le premier exemple est de lire un numéro sur la console et de l'afficher à l'écran. Comment ferions-nous dans le même C #? Eh bien, probablement quelque chose comme ça


var number = int.Parse(Console.ReadLine());
Console.WriteLine($"You guessed: {number}");

?


let mut guess = String::new();

io::stdin().read_line(&mut guess)
    .expect("Failed to read line");

let guess: u32 = guess.trim().parse()
    .expect("Please type a number!");

println!("You guessed: {}", guess);

, ( !), , .. " " "" .


:


let mut guess = String::new();
io::stdin().read_line(&mut guess)?;
let guess: u32 = guess.trim().parse()?;
println!("You guessed: {}", guess);

, , . , , . , , .


? - , , C# , , - .



.


fn search<F>(self, hash: u64, is_match: F, compare_hashes: bool)  
   -> RawEntryMut<'a, K, V, S>
  where for<'b> F: FnMut(&'b K) -> bool

, " ", " , ", " , GC ".


. , , . :


  • Each elided lifetime in input position becomes a distinct lifetime parameter.
  • If there is exactly one input lifetime position (elided or not), that lifetime is assigned to all elided output lifetimes.
  • If there are multiple input lifetime positions, but one of them is &self or &mut self, the lifetime of self is assigned to all elided output lifetimes.
  • Otherwise, it is an error to elide an output lifetime.

, , , , . . , -


struct Point(i32, i32);

impl Point {
    pub fn get_x(&self) -> &i32 {
        &self.0
    }

    pub fn get_y(&self) -> &i32 {
        &self.1
    }
}

, , .



  • GC . C# IDisposable, , , GC " ", . : , ( try-with-resources Java), , foreach … , , . , , . , DI ,
  • , 99% , .

, ( GC), ( ). : . , " ".



. , , :



. Rust 2018, . , . , .


pub struct Node {
    value: u64,
    next: Option<Box<Node>>,
    prev: Option<Box<Node>>,
}

, , .. Box<Node> , unique_ptr C++. , ,


:


pub struct Node {
    value: u64,
    next: Option<&Box<Node>>,
    prev: Option<&Box<Node>>,
}

( shared_ptr), . : - - . " , - ", dangling pointers . -, , , - " , , ".


, " ". , , , , ( Rc/Arc/Cell/RefCell), , .


: , . , , // . : GC , WeakReferences byte[] , , , . JS, , .


, " ", , . , , . , , . - , - . ownership'. , , , , .



. , , , .


,


error[E0382]: assign to part of moved value: `head`
  --> src\main.rs:23:5
   |
19 |         prev: Some(Box::new(head)),
   |                             ---- value moved here
...
23 |     head.next = Some(Box::new(next));
   |     ^^^^^^^^^ value partially assigned here after move
   |
   = note: move occurs because `head` has type `Node`, which does not implement the `Copy` trait

, , . , Copy , , - "", . , " ?".


, , compiler-driven development. , - , ", - . , . , ". , , :


fn foo<T: Copy>() {

}

fn bar<T>() {
    foo::<T>();
}

, :


error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
 --> src\main.rs:6:5
  |
6 |     foo::<T>();
  |     ^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T`
  |
  = help: consider adding a `where T: std::marker::Copy` bound
note: required by `foo`
 --> src\main.rs:1:1
  |
1 | fn foo<T: Copy>() {
  | ^^^^^^^^^^^^^^^^^

error: aborting due to previous error

where T: std::marker::Copy , , , !


, IDE , - , , / , - , IDE. - , , CI - - - . - IDE , , , . .


- , . , . , , , . .


, , . , , . . FFI ++ , . , . C# , " null", " KeyNotFoundException", " ", .. JS ( ) , .


, == . , , , . , , buffer overflow . , ( ).



— , , . . -, , , , , , , . , , , , C#/Java/Go/… , . , — . , , — .


. , , , , , , ", , !". , , . , , ( Java/C#/..., ), ( /++), , .


, , , , . , " ". , , - .

Source: https://habr.com/ru/post/fr434200/


All Articles