Ist Rust so schrecklich wie es gemalt ist

Vor einiger Zeit begann ich zu verstehen, wie wichtig es ist, meine Programmiererfahrung ausschließlich in C # zu diversifizieren. Nach einigen Studien über verschiedene Optionen wie Haskell, Scala, Rust und einige andere fiel die Wahl auf letztere. Im Laufe der Zeit begann ich darauf zu achten, dass Rust immer mehr ausschließlich als „Systemsprache“ beworben wird, die für komplexe Compiler und überladene Systeme mit besonderen Anforderungen an Sicherheit und Multithreading sowie für Go / Python / benötigt wird. Java / ..., während ich es genossen und ziemlich erfolgreich als Ersatz für mein C # -Arbeitspferd verwendet habe.



In diesem Artikel wollte ich darüber sprechen, warum ich diesen Trend im Allgemeinen als schädlich betrachte und warum Rust eine gute Allzwecksprache ist, die für jede Art von Projekten verwendet werden kann, angefangen bei Mikrodiensten bis hin zum täglichen Routine-Scripting.


Einführung


Warum eigentlich eine neue Sprache lernen, umso komplizierter? Es scheint mir, dass die Antwort auf den Artikel „Eroberung der Mittelmäßigkeit“ der Wahrheit am nächsten kommt, nämlich:


Jeder weiß, dass das manuelle Schreiben des gesamten Programms in Maschinensprache ein Fehler ist. Es ist jedoch viel weniger wahrscheinlich, dass sie verstehen, dass es ein allgemeineres Prinzip gibt: Wenn mehrere Sprachen ausgewählt werden, ist es falsch, auf etwas anderem als dem mächtigsten zu programmieren, wenn die Auswahl nicht durch andere Gründe beeinflusst wird.

Je komplexer die Sprache ist, desto reicher sind die mit ihrer Hilfe erstellten Phrasen und desto besser kann sie den erforderlichen Themenbereich ausdrücken. Weil Konzepte werden normalerweise nur einmal studiert und wiederholt angewendet. Unter dem Gesichtspunkt, Ihre eigene Zeit zu investieren, ist es viel rentabler, alle Arten von beängstigenden Wörtern wie „monadische Transformatoren“ (und vorzugsweise auch deren Bedeutung) zu studieren, um dann Ihre mentale Stärke zu retten und sie für etwas mehr auszugeben angenehm. Und deshalb ist es sehr traurig, den Trend einiger Unternehmen zu sehen, speziell „vereinfachte“ Sprachen herzustellen. Infolgedessen ist das Vokabular dieser Sprachen viel kleiner und es ist nicht schwierig, es zu lernen, aber dann ist es sehr schwierig, die Programme „Meine eigenen Zwiebeln kaufen“ zu lesen, ganz zu schweigen von den möglichen mehrdeutigen Interpretationen.


Die Grundlagen


Wie lernt ein Anfänger normalerweise eine Programmiersprache kennen? Er googelt das beliebteste Sprachbuch, holt es heraus und beginnt zu lesen. In der Regel enthält es HelloWorld, Anweisungen zur Installation des Compilers und dann grundlegende Informationen zur Sprache mit einer allmählichen Komplikation. Im Fall von Rasta ist dies ein Bastard , und im ersten Beispiel wird eine Nummer von der Konsole gelesen und auf dem Bildschirm angezeigt. Wie würden wir es im selben C # machen? Na ja, wahrscheinlich so etwas


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/de434200/


All Articles