Yalu X. schrieb: > @privatfrickler: > > Die deutsche Übersetzung des Rust-Handbuchs ist uralt. Nimm besser > dieses hier > > https://doc.rust-lang.org/book/2018-edition/ > > oder – falls dir das ebenfalls nicht zusagt – such dir eins von hier > aus, das besser deinem Geschmack entspricht: > > https://hackr.io/tutorials/learn-rust @Yalu Danke für deinen Hinweis. Werde mir das mit etwas Abstand nochmals genauer betrachten. Ich bin gar nicht so extrem pingelig wie es vielleicht den Anschein weckt. Ich merke halt sehr schnell ob ein Text mich motiviert oder aber wie bei dem Geschwafel in mir das völlige Gegenteil bewirkt.
Beitrag #5517880 wurde von einem Moderator gelöscht.
Hallo, Privatfrickler schrieb: > "let y = &x[0];" > > y sei nun das erste Element des Vektors x ? ja, aber viel weitreichender, als man sich so denkt? Denn, wenn ich das richtig sehe, kann man jetzt in x[0] nicht mehr schreiben? vlg Timm
Timm R. schrieb: > ja, aber viel weitreichender, als man sich so denkt? Denn, wenn ich das > richtig sehe, kann man jetzt in x[0] nicht mehr schreiben? Es geht sogar noch weiter: Du kannst in keins der Elemente von x schreiben.
1 | fn main() { |
2 | let mut x = vec!["Hallo", "Welt"]; |
3 | let y = &x[0]; |
4 | |
5 | x[0] = "Hello"; |
6 | x[1] = "World"; |
7 | |
8 | println!("{:?}", x); |
9 | } |
1 | error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable |
2 | --> src/main.rs:5:5 |
3 | | |
4 | 3 | let y = &x[0]; |
5 | | - immutable borrow occurs here |
6 | 4 | |
7 | 5 | x[0] = "Hello"; |
8 | | ^ mutable borrow occurs here |
9 | ... |
10 | 9 | } |
11 | | - immutable borrow ends here |
12 | |
13 | error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable |
14 | --> src/main.rs:6:5 |
15 | | |
16 | 3 | let y = &x[0]; |
17 | | - immutable borrow occurs here |
18 | ... |
19 | 6 | x[1] = "World"; |
20 | | ^ mutable borrow occurs here |
21 | ... |
22 | 9 | } |
23 | | - immutable borrow ends here |
24 | |
25 | error: aborting due to 2 previous errors |
26 | |
27 | For more information about this error, try `rustc --explain E0502`. |
Was du aber machen kannst: Mittels shadowing ein neues x anlegen.
1 | fn main() { |
2 | let mut x = vec!["Hallo", "Welt"]; |
3 | let y = &x[0]; |
4 | |
5 | let mut x = vec!["Hello", x[1]]; |
6 | |
7 | println!("{:?}", x); |
8 | } |
Hmm, gut, in C++ kann man einen std::vector gar nicht mit einem structured binding verarzten, in sofern ... Aber andererseits? Wegen einem Binding gleich das ganze Objekt blockieren? Ich glaube, das gefällt mir nicht. vlg Timm
Hallo Alex, Alex G. schrieb: > Timm R. schrieb: >> Könnte sich denn vielleicht einer der Rust-kundigen und C++-kundigen >> erbarmen, mal ein minimales Beispiel mit c++ Pointer-Katastrophe zu >> zeigen und wie es in Rust besser läuft? Das wäre doch sicher für mehrere >> Rist-Unkundige interessant und erhellend? Mir fehlt da einfach die >> Vorstellungskraft. > > Hmm, du hättest bei meinem Vortrag vor ein paar Wochen über Rust dabei > sein sollen. > Dafür habe ich den Heartbleed Bug in C++ nachprogrammiert - und dann > versucht ihn auch unter Rust zu programmieren (ohne Unsafe). also, erstmal danke für das instruktive Programm. Ja, das ist ein Beispiel für einen echten Sicherheitsgewinn. Ich möchte aber doch anmerken, m.h. tat das ja schon, wenn auch etwas stoffelig, dass das kein C++ ist. Vielmehr wird ziemlich klar, dass auch in diesem Fall richtiges C++ das Problem schon gelöst hätte. Yalus Beispiel ist zwar valide. Aber auch da bin ich unschlüssig, ob den Tausch Brauchbarkeit der Features gegen eine bedingt relevante Sicherheit profitabel finde. vlg Timm
Rust ist ganz klar einschränkend - bietet aber wiederum Strukturen um solche Einschränkungen ganz kontrolliert wieder aufzuheben. Z.B. die CELL Datenstruktur. Auch wenn ich hiermit meinen Realnamen preisgebe - hier habe ich einen Blogeintrag über Rust und RustBelt geschrieben: https://blog.mi.hdm-stuttgart.de/index.php/2018/07/23/rust-safety-during-and-after-programming/ Das enthält auch eine zusammenhängende Ausführung des Grundgedanken dieser Sprache mit Beispielen,
Beitrag #5518962 wurde von einem Moderator gelöscht.
Beitrag #5518963 wurde von einem Moderator gelöscht.
Beitrag #5518964 wurde von einem Moderator gelöscht.
Beitrag #5518966 wurde von einem Moderator gelöscht.
Timm R. schrieb: > Wegen einem Binding gleich das ganze Objekt > blockieren? > > Ich glaube, das gefällt mir nicht. Es ist ja nicht (vollstaendig) blockiert. Lesen kannst du noch ohne Probleme.
1 | fn main() { |
2 | let mut x = vec!["Hallo", "Welt"]; |
3 | let y = &x[0]; |
4 | |
5 | println!("x: `{:?}`", x); |
6 | println!("y: `{:?}`", y); |
7 | } |
1 | x: `["Hallo", "Welt"]` |
2 | y: `"Hallo"` |
Ja, das Ownershipkonzept erfordert etwas umdenken, verglichen mit C und C++. Aber das Umdenken zahlt sich aus.
Beitrag #5518969 wurde von einem Moderator gelöscht.
Beitrag #5518970 wurde von einem Moderator gelöscht.
Beitrag #5518971 wurde von einem Moderator gelöscht.
Beitrag #5518973 wurde von einem Moderator gelöscht.
Beitrag #5518974 wurde von einem Moderator gelöscht.
Beitrag #5518975 wurde von einem Moderator gelöscht.
Beitrag #5518979 wurde von einem Moderator gelöscht.
Beitrag #5518980 wurde von einem Moderator gelöscht.
Beitrag #5518982 wurde von einem Moderator gelöscht.
Beitrag #5518988 wurde von einem Moderator gelöscht.
Beitrag #5518991 wurde von einem Moderator gelöscht.
Beitrag #5518994 wurde von einem Moderator gelöscht.
Beitrag #5518995 wurde von einem Moderator gelöscht.
Beitrag #5518996 wurde von einem Moderator gelöscht.
Beitrag #5518997 wurde von einem Moderator gelöscht.
Beitrag #5518998 wurde von einem Moderator gelöscht.
Beitrag #5518999 wurde von einem Moderator gelöscht.
Beitrag #5519000 wurde von einem Moderator gelöscht.
Beitrag #5519001 wurde von einem Moderator gelöscht.
Beitrag #5519003 wurde von einem Moderator gelöscht.
Beitrag #5519004 wurde von einem Moderator gelöscht.
Beitrag #5519005 wurde von einem Moderator gelöscht.
Beitrag #5519006 wurde von einem Moderator gelöscht.
Beitrag #5519007 wurde von einem Moderator gelöscht.
Beitrag #5519008 wurde von einem Moderator gelöscht.
Beitrag #5519009 wurde von einem Moderator gelöscht.
Beitrag #5519010 wurde von einem Moderator gelöscht.
Beitrag #5519011 wurde von einem Moderator gelöscht.
Beitrag #5519013 wurde von einem Moderator gelöscht.
Beitrag #5519014 wurde von einem Moderator gelöscht.
Beitrag #5519015 wurde von einem Moderator gelöscht.
Beitrag #5519016 wurde von einem Moderator gelöscht.
Beitrag #5519017 wurde von einem Moderator gelöscht.
Beitrag #5519018 wurde von einem Moderator gelöscht.
Beitrag #5519019 wurde von einem Moderator gelöscht.
Beitrag #5519020 wurde von einem Moderator gelöscht.
Beitrag #5519021 wurde von einem Moderator gelöscht.
Beitrag #5519022 wurde von einem Moderator gelöscht.
Beitrag #5519024 wurde von einem Moderator gelöscht.
Beitrag #5519026 wurde von einem Moderator gelöscht.
Beitrag #5519027 wurde von einem Moderator gelöscht.
Beitrag #5519029 wurde von einem Moderator gelöscht.
Beitrag #5519030 wurde von einem Moderator gelöscht.
Beitrag #5519031 wurde von einem Moderator gelöscht.
Beitrag #5519032 wurde von einem Moderator gelöscht.
Beitrag #5519033 wurde von einem Moderator gelöscht.
Beitrag #5519034 wurde von einem Moderator gelöscht.
Beitrag #5519035 wurde von einem Moderator gelöscht.
Beitrag #5519037 wurde von einem Moderator gelöscht.
Beitrag #5519039 wurde von einem Moderator gelöscht.
Beitrag #5519040 wurde von einem Moderator gelöscht.
Beitrag #5519041 wurde von einem Moderator gelöscht.
Beitrag #5519042 wurde von einem Moderator gelöscht.
Beitrag #5519046 wurde von einem Moderator gelöscht.
Beitrag #5519047 wurde von einem Moderator gelöscht.
Beitrag #5519048 wurde von einem Moderator gelöscht.
Beitrag #5519050 wurde von einem Moderator gelöscht.
Beitrag #5519051 wurde von einem Moderator gelöscht.
Beitrag #5519053 wurde von einem Moderator gelöscht.
Beitrag #5519054 wurde von einem Moderator gelöscht.
Beitrag #5519057 wurde von einem Moderator gelöscht.
Beitrag #5519059 wurde von einem Moderator gelöscht.
Beitrag #5519060 wurde von einem Moderator gelöscht.
Beitrag #5519061 wurde von einem Moderator gelöscht.
Beitrag #5519063 wurde von einem Moderator gelöscht.
Beitrag #5519065 wurde von einem Moderator gelöscht.
Beitrag #5519067 wurde von einem Moderator gelöscht.
Beitrag #5519069 wurde von einem Moderator gelöscht.
Beitrag #5519072 wurde von einem Moderator gelöscht.
Beitrag #5519073 wurde von einem Moderator gelöscht.
Beitrag #5519074 wurde von einem Moderator gelöscht.
Beitrag #5519075 wurde von einem Moderator gelöscht.
Beitrag #5519079 wurde von einem Moderator gelöscht.
Beitrag #5519080 wurde von einem Moderator gelöscht.
Beitrag #5519082 wurde von einem Moderator gelöscht.
Beitrag #5519083 wurde von einem Moderator gelöscht.
Beitrag #5519085 wurde von einem Moderator gelöscht.
Beitrag #5519086 wurde von einem Moderator gelöscht.
Beitrag #5519136 wurde von einem Moderator gelöscht.
Beitrag #5519137 wurde von einem Moderator gelöscht.
Beitrag #5519138 wurde von einem Moderator gelöscht.
Beitrag #5519139 wurde von einem Moderator gelöscht.
Beitrag #5519140 wurde von einem Moderator gelöscht.
Beitrag #5519142 wurde von einem Moderator gelöscht.
Beitrag #5519143 wurde von einem Moderator gelöscht.
Beitrag #5519144 wurde von einem Moderator gelöscht.
Beitrag #5519145 wurde von einem Moderator gelöscht.
Beitrag #5519146 wurde von einem Moderator gelöscht.
Beitrag #5519147 wurde von einem Moderator gelöscht.
Beitrag #5519148 wurde von einem Moderator gelöscht.
Beitrag #5519149 wurde von einem Moderator gelöscht.
Beitrag #5519150 wurde von einem Moderator gelöscht.
Beitrag #5519151 wurde von einem Moderator gelöscht.
Beitrag #5519152 wurde von einem Moderator gelöscht.
Beitrag #5519153 wurde von einem Moderator gelöscht.
Beitrag #5519155 wurde von einem Moderator gelöscht.
Beitrag #5519156 wurde von einem Moderator gelöscht.
Beitrag #5519157 wurde von einem Moderator gelöscht.
Beitrag #5519158 wurde von einem Moderator gelöscht.
Beitrag #5519159 wurde von einem Moderator gelöscht.
Beitrag #5519164 wurde von einem Moderator gelöscht.
Beitrag #5519165 wurde von einem Moderator gelöscht.
Beitrag #5519167 wurde von einem Moderator gelöscht.
Beitrag #5519168 wurde von einem Moderator gelöscht.
Beitrag #5519169 wurde von einem Moderator gelöscht.
Beitrag #5519170 wurde von einem Moderator gelöscht.
Beitrag #5519171 wurde von einem Moderator gelöscht.
Beitrag #5519172 wurde von einem Moderator gelöscht.
Beitrag #5519173 wurde von einem Moderator gelöscht.
Beitrag #5519174 wurde von einem Moderator gelöscht.
Beitrag #5519176 wurde von einem Moderator gelöscht.
Beitrag #5519177 wurde von einem Moderator gelöscht.
Beitrag #5519178 wurde von einem Moderator gelöscht.
Beitrag #5519179 wurde von einem Moderator gelöscht.
Beitrag #5519180 wurde von einem Moderator gelöscht.
Beitrag #5519181 wurde von einem Moderator gelöscht.
Beitrag #5519182 wurde von einem Moderator gelöscht.
Beitrag #5519184 wurde von einem Moderator gelöscht.
Beitrag #5519185 wurde von einem Moderator gelöscht.
Beitrag #5519186 wurde von einem Moderator gelöscht.
Beitrag #5519187 wurde von einem Moderator gelöscht.
Beitrag #5519189 wurde von einem Moderator gelöscht.
Beitrag #5519194 wurde von einem Moderator gelöscht.
Beitrag #5519203 wurde von einem Moderator gelöscht.
Beitrag #5519204 wurde von einem Moderator gelöscht.
Beitrag #5519205 wurde von einem Moderator gelöscht.
Beitrag #5519206 wurde von einem Moderator gelöscht.
Beitrag #5519207 wurde von einem Moderator gelöscht.
Beitrag #5519208 wurde von einem Moderator gelöscht.
Beitrag #5519209 wurde von einem Moderator gelöscht.
Beitrag #5519210 wurde von einem Moderator gelöscht.
Beitrag #5519211 wurde von einem Moderator gelöscht.
Beitrag #5519223 wurde von einem Moderator gelöscht.
Beitrag #5519224 wurde von einem Moderator gelöscht.
Beitrag #5519225 wurde von einem Moderator gelöscht.
Beitrag #5519226 wurde von einem Moderator gelöscht.
Beitrag #5519227 wurde von einem Moderator gelöscht.
Beitrag #5519231 wurde von einem Moderator gelöscht.
Beitrag #5519232 wurde von einem Moderator gelöscht.
Beitrag #5519233 wurde von einem Moderator gelöscht.
Beitrag #5519234 wurde von einem Moderator gelöscht.
Beitrag #5519235 wurde von einem Moderator gelöscht.
Beitrag #5519236 wurde von einem Moderator gelöscht.
Kaj schrieb: > Timm R. schrieb: >> Wegen einem Binding gleich das ganze Objekt >> blockieren? >> >> Ich glaube, das gefällt mir nicht. > Es ist ja nicht (vollstaendig) blockiert. Lesen kannst du noch ohne > Probleme. Als weiterfuehrung zu meiner vorherigen Antwort: Timm R. schrieb: > gut, in C++ kann man einen std::vector gar nicht mit einem structured > binding verarzten, in sofern ... > > Aber andererseits? Wegen einem Binding gleich das ganze Objekt > blockieren? > > Ich glaube, das gefällt mir nicht. Spiel einfach mal ein bisschen mit Rust. Theoretisch kannst du Rust 'einfach' als C/C++ mit invertierten Regeln betrachten (grob gesagt). ================================================== Beispiel 1, C/C++:
1 | void foo(void) |
2 | {
|
3 | //...
|
4 | }
|
Diese Funktion ist praktisch fuer jede andere Uebersetzungseinheit sichtbar, da sie nicht static ist (ja, es muss noch die .h-Datei eingebunden werden, ich weiss). Beispiel 1, Rust:
1 | fn foo() { |
2 | //... |
3 | } |
Diese Funktion ist nur innerhalb der Datei in der sie steht, sichtbar, da sie nicht explizit sichtbar gemacht wurde. Soll sie auch in anderen Uebersetzungseinheit sichtbar sein, dann muss das so aussehen:
1 | pub fn foo() { |
2 | //... |
3 | } |
C und C++: Sichtbarkeit muss explizit eingeschraenkt werden. Rust: Sichtbarkeit muss explizit ausgeweitet werden. ================================================== Beispiel 2, C/C++:
1 | int main(void) |
2 | {
|
3 | int a = 0; |
4 | // ...
|
5 | return 0; |
6 | }
|
Die Variable a kann beschrieben werden, da sie nicht const ist. Beispiel 2, Rust:
1 | fn main() |
2 | { |
3 | let a: i32 = 0; |
4 | // ... |
5 | return 0; |
6 | } |
Die Variable a ist read-only (aber nicht const(!)), da sie nicht mut ist. Das heisst: man kann a mittels shadowing ueberdecken. Das geht bei einer Konstanten nicht.
1 | fn main() { |
2 | const A:i32 = 42; |
3 | let A: i32 = 43; |
4 | } |
5 | |
6 | error[E0005]: refutable pattern in local binding: `_` not covered |
7 | --> src/main.rs:3:9 |
8 | | |
9 | 3 | let A: i32 = 43; |
10 | | ^ interpreted as a constant pattern, not new variable |
1 | fn main() { |
2 | const A:i32 = 42; |
3 | let mut A: i32 = 44; |
4 | } |
5 | |
6 | error[E0530]: let bindings cannot shadow constants |
7 | --> src/main.rs:3:13 |
8 | | |
9 | 2 | const A:i32 = 42; |
10 | | ----------------- a constant `A` is defined here |
11 | 3 | let mut A: i32 = 44; |
12 | | ^ cannot be named the same as a constant |
C und C++: Schreibrechte muessen explizit entzogen werden. Rust: Schreibrechte muessen explizit erteilt werden. ================================================== Und so zieht es sich immer weiter. Wenn du es eben so betrachtest, dass Rust "nur ein invertiertes C/C++" ist, dann duerfte es dir leichter fallen die Sprache zu verstehen. So geht es zumindestens mir. Und genau durch diese 'Invertierung' erreicht Rust schon eine hoehere Sicherheit. Gruesse
Hallo Karl, ja das ist soweit sehr interessant und hilfreich. Auch die Logik verstehe ich: der unaufmerksame Tipper tippt per default maximale Sicherheit. Das gefällt mir auch sehr gut. Borrowing als Alternative zu RAII erscheint mir allerdings wie die Therapie von Kopfschmerz durch Dekaputation. Da bin ich mir nicht sicher, ob das rockt. Was ja sehr heiß sein soll ist die concurrency bei Rust. Vielleicht hilft da das Borrowing auch? In c++ ist das Thema ja jetzt mit C++17 und später überhaupt erst auf dem Tapet. Viele liebe Grüße timm
Timm R. schrieb: > Was ja sehr heiß sein soll ist die concurrency bei Rust. Vielleicht > hilft da das Borrowing auch? Ja, das Ownership-System wurde eben wegen den Gefahren von nebenläufigen Code entworfen. In Rust ist es ebenso, dass ein Objekt entweder immutable ist, dann können mehrere darauf zugreifen, oder es ist mutable aber nur der Besitzer hat Schreibzugriff. Das Ownership-System garantiert das und deshalb können auch keine Raceconditions in Plain Rust auftreten. Natürlich lässt sich das mithilfe von unsafe umgehen, damit man trotzdem Semaphore und Co. in Rust umsetzen kann. Durch das Ownership-System hat Rust definitiv ein nützliches Alleinstellungsmerkmal.
Beitrag #5519813 wurde von einem Moderator gelöscht.
Beitrag #5519814 wurde von einem Moderator gelöscht.
Beitrag #5519815 wurde von einem Moderator gelöscht.
Beitrag #5519817 wurde von einem Moderator gelöscht.
Beitrag #5519821 wurde von einem Moderator gelöscht.
Beitrag #5519823 wurde von einem Moderator gelöscht.
Beitrag #5519824 wurde von einem Moderator gelöscht.
Beitrag #5519870 wurde von einem Moderator gelöscht.
Beitrag #5519877 wurde von einem Moderator gelöscht.
Beitrag #5519894 wurde von einem Moderator gelöscht.
Beitrag #5519897 wurde von einem Moderator gelöscht.
Timm R. schrieb: > Was ja sehr heiß sein soll ist die concurrency bei Rust. Vielleicht > hilft da das Borrowing auch? Lies einfach mal hier: Fearless Concurrency https://doc.rust-lang.org/book/second-edition/ch16-00-concurrency.html Using Threads to Run Code Simultaneously https://doc.rust-lang.org/book/second-edition/ch16-01-threads.html Using Message Passing to Transfer Data Between Threads https://doc.rust-lang.org/book/second-edition/ch16-02-message-passing.html Channels and Ownership Transference https://doc.rust-lang.org/book/second-edition/ch16-02-message-passing.html#channels-and-ownership-transference
1 | The ownership rules play a vital role in message sending because they |
2 | help you write safe, concurrent code. Preventing errors in concurrent |
3 | programming is the advantage of thinking about ownership throughout |
4 | your Rust programs. |
Kaj G. schrieb: > Using Message Passing to Transfer Data Between Threads Das ist übrigens ganz generell ein Entwurfsmuster das es auch in andern Sprachen sehr entspannt und angstfrei macht mit vielen Threads zu arbeiten ohne in die Bredouille zu kommen. Alles was man braucht ist eine threadsichere Queue.
:
Bearbeitet durch User
Beitrag #5520001 wurde von einem Moderator gelöscht.
Beitrag #5520005 wurde von einem Moderator gelöscht.
Beitrag #5520006 wurde von einem Moderator gelöscht.
Beitrag #5520008 wurde von einem Moderator gelöscht.
RalfW schrieb im Beitrag #5520008:
> Warum tut man sich das freiwillig an?
Einmal hätte doch gereicht.
Also, WARUM ?
Es ist vielen C-Programmierern seit geraumer Zeit klar, daß die Sprache
C für die heutigen Bedürfnisse nicht mehr wirklich ausreicht und daß sie
nicht mehr renovierungsfähig ist. Sie ist dafür bereits seit langem zu
verkalkt.
Deshalb sinnieren viele C-Programmierer seit ebenso geraumer Zeit über
neue Sprachentwürfe nach, mit denen sie all die uralten Geburtsfehler
von C endlich hinter sich lassen können.
Dummerweise haben eben gerade die Programmierer, denen eine Nachfolge
für C durchaus am Herzen liegt, "ihr" C so tief verinnerlicht, daß sie
unfreiwillig bei jedem neuen Versuch einer neuen Programmiersprache
sofort wieder in ihre eingefahrenen Denk-Gleise zurückfallen.
Deswegen kommt bei jeder neu erfundenen Programmiersprache im Grunde
wieder nur C heraus, bloß hie und da mit irgendwelchen zusätzlichen
Kringeln versehen, die die praktische Anwendung regelmäßig verhindern.
Kurzum, die Leute kommen einfach nicht aus ihrem Tunnelblick heraus,
egal wie sie es anstellen.
Das ist das Tragische daran.
W.S.
:
Wiederhergestellt durch Moderator
@W.S. Du willst aber damit hoffentlich nicht ausdrücken dass das auch für Rust gelten würde, oder?
W.S. schrieb: > Deswegen kommt bei jeder neu erfundenen Programmiersprache im Grunde > wieder nur C heraus, bloß hie und da mit irgendwelchen zusätzlichen > Kringeln versehen, die die praktische Anwendung regelmäßig verhindern. Mein Gott, wie kann man nur so wenig Ahnung haben und trotzdem so penetrant sein. Aber mach nur, mach dich weiter lächerlich, das steht dir so gut. ;) Zu glauben Rust wäre wie C, weil es syntaktische Ähnlichkeiten hat, großartig. Das in etwa das Niveau von Moby...
Alex G. schrieb: > Du willst aber damit hoffentlich nicht ausdrücken dass das auch für Rust > gelten würde, oder? Doch, leider. Ist mir auch so ziemlich als erstes aufgefallen: Diese unsäglichen geschweiften Klammern zum Einfassen einer Funktion oder Anweisung. Gleichzeitig benutzen sie es noch als Platzhalter. Das C-typische = für Zuweisungen, == für Vergleiche. Ahhh. Nach zig Jahren if x = y sollte man es doch mal verstanden haben, dass das Bullshit ist. Vielleicht könnte Rust das bessere C sein, aber es ist halt doch zuviel C.
Karl K. schrieb: > Diese unsäglichen geschweiften Klammern zum Einfassen einer Funktion > oder Anweisung. Gleichzeitig benutzen sie es noch als Platzhalter. Siehe hier: TriHexagon schrieb: > Zu glauben Rust wäre wie C, weil es syntaktische Ähnlichkeiten hat, > großartig. Das in etwa das Niveau von Moby... Karl K. schrieb: > Das C-typische = für Zuweisungen, == für Vergleiche. Ahhh. Nach zig > Jahren if x = y sollte man es doch mal verstanden haben, dass das > Bullshit ist. Da ist in Python oder Haskell auch so. Ist deswegen Python==Haskell==C? Nein. Und auch Rust ist – bis auf diese beiden minimalen syntaktischen Ähnlichenkeiten – völlig verschieden von C.
Karl K. schrieb: > Nach zig > Jahren if x = y sollte man es doch mal verstanden haben Was faselst Du? Hast Du auch mal ausprobiert was Du da frech gelogen unterstellst oder schwallst Du einfach nur so aus Langeweile dumm daher damit irgendwas gesagt ist, ganz egal was?
Karl K. schrieb: > Alex G. schrieb: >> Du willst aber damit hoffentlich nicht ausdrücken dass das auch für Rust >> gelten würde, oder? > > Doch, leider. Ist mir auch so ziemlich als erstes aufgefallen: > > Diese unsäglichen geschweiften Klammern zum Einfassen einer Funktion > oder Anweisung. Gleichzeitig benutzen sie es noch als Platzhalter. > > Das C-typische = für Zuweisungen, == für Vergleiche. Ahhh. Nach zig > Jahren if x = y sollte man es doch mal verstanden haben, dass das > Bullshit ist. > > Vielleicht könnte Rust das bessere C sein, aber es ist halt doch zuviel > C. Bei der Zuweisung gebe ich dir recht, da wäre ein := besser. Aber immer noch besser als = == === in JavaScript ;-) Die {} finde ich zum Einfassen von Blöcken nach wie vor besser leserlich als das unsägliche Einrücken in Python. Einmal die Quelle mit den falschen Einstellungen im Editor geladen und schon verhagelt es einem die Funktion des Programms. Da ist mir eine Sprache mit geschweiften Klammern lieber. Der Compiler weiß dann auch was zu tun ist, wenn irgendwelche Whitespaces durch andere ersetzt/optimiert wurden. Auf Rust bin ich erst durch diesen Thread aufmerksam geworden und habe mich am Wochenende genauer damit beschäftigt. Bis jetzt finde ich die Sprache sehr interessant. Ich programmiere seit über 20 Jahren im embedded Bereich in C (nicht nur Projekte bei welchen zwei LEDs blinken ;-)) und sehne mich nach einer Sprache, welche ähnlich für die Systemprogrammierung geeignet ist, mich vor Memory-Leaks, übergelaufenen Arrays etc. bewahrt, nativ und nicht in einer VM ausgeführt wird und keinen riesigen Overhead besitzt (z.B. Garbage Collector, fettes Exception-Handling ... hat hier schon jemand C++ unter den Rock geschaut ... brrrr). Rust hat mich positiv überrascht, sogar Inline-Assembler ist möglich. Gruß {}
W.S. schrieb: > die die praktische Anwendung regelmäßig verhindern. Dann zeig doch bitte die "Kringel" die die Anwendung von Rust verhindern. W.S. schrieb: > Kurzum, die Leute kommen einfach nicht aus ihrem Tunnelblick heraus, > egal wie sie es anstellen. Sagt ja der richtige... Karl K. schrieb: > Vielleicht könnte Rust das bessere C sein, aber es ist halt doch zuviel > C. Doof nur das Rust nicht viel mit C gemein hat, ausser etwas Syntax. Karl K. schrieb: > Das C-typische = für Zuweisungen, == für Vergleiche. Ahhh. Nach zig > Jahren if x = y sollte man es doch mal verstanden haben, dass das > Bullshit ist. Auch du hast dich null mit Rust beschaeftigt. 1. Das was du da schreibst compiliert in Rust gar nicht.
1 | fn main() { |
2 | let mut x = 5; |
3 | let mut y = 7; |
4 | |
5 | if x = y { |
6 | // ... |
7 | } |
8 | } |
9 | |
10 | error[E0308]: mismatched types |
11 | --> src/main.rs:5:8 |
12 | | |
13 | 5 | if x = y { |
14 | | ^^^^^ |
15 | | | |
16 | | expected bool, found () |
17 | | help: try comparing for equality: `x == y` |
18 | | |
19 | = note: expected type `bool` |
20 | found type `()` |
Wer glaubt, dass nur an den Typen von x und y liegt:
1 | fn main() { |
2 | let x = true; |
3 | let y = false; |
4 | |
5 | if x = y { |
6 | // ... |
7 | } |
8 | } |
9 | |
10 | error[E0308]: mismatched types |
11 | --> src/main.rs:5:8 |
12 | | |
13 | 5 | if x = y { |
14 | | ^^^^^ |
15 | | | |
16 | | expected bool, found () |
17 | | help: try comparing for equality: `x == y` |
18 | | |
19 | = note: expected type `bool` |
20 | found type `()` |
Eine Zuweisung liefert keinen bool. 2. In Rust muessen alle Ausdruecke bei einem if ein bool liefern, und nicht etwas, das wie ein bool interpretiert werden koennte. Was in C/C++ geht
1 | if (x) { |
2 | |
3 | }
|
compiliert in Rust ebefalls nicht
1 | fn main() { |
2 | let x = 5; |
3 | |
4 | if x { |
5 | // ... |
6 | } |
7 | } |
8 | |
9 | error[E0308]: mismatched types |
10 | --> src/main.rs:5:8 |
11 | | |
12 | 5 | if x { |
13 | | ^ expected bool, found integral variable |
14 | | |
15 | = note: expected type `bool` |
16 | found type `{integer}` |
Auch sowas geht nicht:
1 | fn main() { |
2 | let x = 5; |
3 | |
4 | if x & 5 { |
5 | // ... |
6 | } |
7 | } |
8 | |
9 | error[E0308]: mismatched types |
10 | --> src/main.rs:4:8 |
11 | | |
12 | 4 | if x & 5 { |
13 | | ^^^^^ expected bool, found integral variable |
14 | | |
15 | = note: expected type `bool` |
16 | found type `{integer}` |
Es compiliert erst, wenn ein bool rauskommt:
1 | fn main() { |
2 | let x = 5; |
3 | |
4 | if x & 5 == 5 { |
5 | // ... |
6 | } |
7 | } |
Wenn man keine Ahnung hat...
Karl K. schrieb: > Diese unsäglichen geschweiften Klammern zum Einfassen einer Funktion > oder Anweisung. Gleichzeitig benutzen sie es noch als Platzhalter. Wo ist denn das Problem? Weil man statt geschweiften Klammern alles mit begin und end zu bombt? Ohne Syntax-Highlighting ist die Lesbarkeit mit begin/end allerdings schlecht. Passiert wenn man den Code mit cat oder diff ausgibt. Karl K. schrieb: > Das C-typische = für Zuweisungen, == für Vergleiche. Ahhh. Nach zig > Jahren if x = y sollte man es doch mal verstanden haben, dass das > Bullshit ist. Ist kein Bullshit, weil man damit elegant gleichzeitig Zuweisen und Vergleichen kann. Gerade in Schleifenköpfe ist das praktisch. Karl K. schrieb: > Vielleicht könnte Rust das bessere C sein, aber es ist halt doch zuviel > C. Das ist reine Geschmacksache. Ich bevorzuge den Stil von C, aber deswegen Kotze ich mich bei VHDL doch nicht aus... . Daran bemisst sich ganz sicher nicht die Qualität von Rust, auch wenn es sich ein paar Ewiggestrigene wünschen, die immer noch um Pascal trauern.
brackets schrieb: > Aber immer > noch besser als = == === in JavaScript ;-) Das gibt es auch in PHP ;)
TriHexagon schrieb: > Karl K. schrieb: >> Das C-typische = für Zuweisungen, == für Vergleiche. Ahhh. Nach zig >> Jahren if x = y sollte man es doch mal verstanden haben, dass das >> Bullshit ist. > > Ist kein Bullshit, weil man damit elegant gleichzeitig Zuweisen und > Vergleichen kann. Gerade in Schleifenköpfe ist das praktisch. Und das ist in Rust nicht einmal möglich, wie Kaj G. schon zeigte.
x = y = z; hätte auch keinen Sinn, selbst wenn es gehen würde wenn man bedenkt was der = Operator macht, je nachdem ob z copy ist oder nicht. Deshalb braucht keiner sowas wie das was da oben steht und käme auch nie auf die Idee sowas zu schreiben oder haben zu wollen. Deshalb evaluiert eine Zuweisung immer zu (). Und () ist nicht bool. Also hat Rust auch dieses Problem elegant über die Bande gespielt allein mit dem Typsystem nachhaltig aus der Welt geschafft ohne irgendwelche altgewohnte Syntax ändern zu müssen.
Ja ok, ich sehe schon, Rust hat hier genauso arschlöchrige Fanboys wie C. Damit ist die Diskussion hinfällig.
brackets schrieb: > Die {} finde ich zum Einfassen von Blöcken nach wie vor besser leserlich > als das unsägliche Einrücken in Python. Wer sagt denn das es das Einrücken sein muß. Es gibt auch andere Möglichkeiten Blöcke zusammenzufassen bzw. zu kennzeichnen. Es soll ja Programmiersprachen geben die den Anfang und das Ende eines Blockes im Klartext hinschreiben. Das empfinde ich als sehr angenehm, weil gut lesbar ist. Wenn dann noch dazu sinnvoll eingerückt wird ist es eigentlich optimal lesbar. Ich kann auch mit der geschweiften Klammer leben - ist allemal besser als das Einrückungsprinzip in Python. Einen Vorteil hat allerdings das Pythonverfahren: Es zwingt zu einem sauberen Aufschreiben des Quelltextes.
Warum zum Geier muss ich bei Rust immer an diesen komischen Kremelflieger denken? Bin ich etwa anders als andere?
TriHexagon schrieb: > weil man damit elegant gleichzeitig Zuweisen und > Vergleichen kann. Gerade in Schleifenköpfe ist das praktisch. Das ist eine ganz böse Falle, weil das auch mal richtig nach hinten los gehen kann. Im Übrigen ist dieses Verhalten nicht vom verwendeten Zuweisungs-/Vergleichsoperator abhängig. Das könnte man mit jeder beliebigen Zuweisungs-/Vergleichsoperatorkombination realisieren, weil das letztendlich vom Compiler abhängt. Es hat aber schon gute Gründe, das es Compiler gibt die so etwas nicht zu lassen. Zuweisen ist halt etwas anderes als Vergleichen.
Karl K. schrieb: > Ja ok, ich sehe schon, Rust hat hier genauso arschlöchrige Fanboys wie > C. Damit ist die Diskussion hinfällig. Sich zuerst überheblich an solchen Kleinigkeiten aufhängen, dann sich eine blutige Nasse holen und gleich beleidigt abhauen. So ist recht. Aber gut, eigentlich sollte es darum gar nicht gehen. Ich habe vor einem Jahr einen einfachen Assembler in Rust geschrieben. Und muss sagen, dass mir Rust sehr gut gefällt. Natürlich muss man sich ein bisschen mehr Gedanken durch das Ownership-System machen, man wird aber belohnt. Ich hatte allerdings noch nicht die Möglichkeit ein komplexeres Programm zu schreiben mit vielen Datenstrukturen. Da wäre interessant wie gut das geht. Auch gefällt mir die Fehlerbehandlung in Rust durch nullable-Types mit Verzicht auf Exceptions. Durchs Patternmatching lässt sich das auch relativ elegant behandeln. Überhaupt sind diese mächtigen Enums wirklich genial. Wollte mir in nächster Zeit mal mit Rust auf einem ARM Cortex beschäftigen, da sehe ich wirklich Potential.
Was hier im Forum ja auch ganz gerne an C/C++ bemaengelt wird: die Endlosschleife. In C/C++:
1 | while (1) { |
2 | |
3 | }
|
4 | |
5 | for (;;) { |
6 | |
7 | }
|
Da wird ja auch gerne gemotzt, dass man das doch besser mit goto (oder sonst wie) machen sollte, weil alles andere ja eine zweckentfremdung der Schleife waere... Auch das macht Rust ganz einfach:
1 | loop { |
2 | |
3 | } |
Rust hat dazu auch noch Schleifen-Lables: https://doc.rust-lang.org/rust-by-example/flow_control/loop/nested.html
1 | #![allow(unreachable_code)] |
2 | |
3 | fn main() { |
4 | 'outer: loop { |
5 | println!("Entered the outer loop"); |
6 | |
7 | 'inner: loop { |
8 | println!("Entered the inner loop"); |
9 | |
10 | // This would break only the inner loop |
11 | //break; |
12 | |
13 | // This breaks the outer loop |
14 | break 'outer; |
15 | } |
16 | |
17 | println!("This point will never be reached"); |
18 | } |
19 | |
20 | println!("Exited the outer loop"); |
21 | } |
Wie goto, nur deutlich weniger fehleranfaellig. Was ich ebefalls schoen finde:
1 | fn main() { |
2 | let cond = true; |
3 | |
4 | let x = if cond { |
5 | 5 |
6 | } else { |
7 | 6 |
8 | }; |
9 | } |
In C/C++ muss man dazu x erstmal anlege und laesst es uninitialisiert oder belegt es erstmal mit einen dummy Wert, der dann wieder ueberschrieben werden muss. Auf uninitialisierte Variablen kann in Rust nicht lesend zugegriffen werden:
1 | fn main() { |
2 | let x: i32; |
3 | let y = x; |
4 | } |
5 | |
6 | error[E0381]: use of possibly uninitialized variable: `x` |
7 | --> src/main.rs:4:9 |
8 | | |
9 | 4 | let y = x; |
10 | | ^ use of possibly uninitialized `x` |
Boom: Wieder ein typisches Problem von C und C++ einfach so aus dem Weg geraeumt. Wer hier immernoch die Meinung vertritt, das Rust wie C ist, der moege doch bitte die Klappe halten. Ihr muesst es nicht nutzen, aber lasst uns doch unseren Spass an dieser Sprache. Nicht jeder moechte stehen bleiben, und Sprachen mit Konzepten (bzw. eher ohne Konzepten) von vor ueber 20 Jahren nutzen. Rust unterstuetzt den Entwickler besser als die meisten anderen Sprachen (besonders besser als C und C++), um fehlerfreien/fehlerarmen Code zu schreiben. Und der Entwickler muss sich weniger Gedanken um Dinge wie undefined behavior machen, und kann sich mehr auf die eigentliche Aufgabe konzentrieren, ohne dabei auf die Performance von C/C++ verzichten zu muessen.
TriHexagon schrieb: > Ich > hatte allerdings noch nicht die Möglichkeit ein komplexeres Programm zu > schreiben mit vielen Datenstrukturen. Da wäre interessant wie gut das > geht. Wenn du ein grosses Projekt suchst, das in Rust geschrieben wird: Sequoia-PGP https://sequoia-pgp.org/
Zeno schrieb: > TriHexagon schrieb: >> weil man damit elegant gleichzeitig Zuweisen und >> Vergleichen kann. Gerade in Schleifenköpfe ist das praktisch. > > Das ist eine ganz böse Falle, weil das auch mal richtig nach hinten los > gehen kann. > Im Übrigen ist dieses Verhalten nicht vom verwendeten > Zuweisungs-/Vergleichsoperator abhängig. Das könnte man mit jeder > beliebigen Zuweisungs-/Vergleichsoperatorkombination realisieren, weil > das letztendlich vom Compiler abhängt. Es hat aber schon gute Gründe, > das es Compiler gibt die so etwas nicht zu lassen. Zuweisen ist halt > etwas anderes als Vergleichen. Da hast du recht und ich kann total verstehen, dass man das verbieten sollte. Aber die damalige Designentscheidung ist allerdings zumindest nachvollziehbar und kein "Bullshit", auch wenns zu einem weiteren Fallstrick führt.
Karl K. schrieb: > Ja ok, ich sehe schon, Rust hat hier genauso arschlöchrige > Fanboys wie C. Damit ist die Diskussion hinfällig. Welche Sprache wäre denn deiner Meinung nach ein würdiger Nachfolger von C? Jetzt sag aber bitte nicht C++ oder Assembler.
Apropos Enums: Option und Result, wer fühlt sich bei diesen beiden Enums nicht sofort an Haskell's Maybe und Either Monaden erinnert? Auch das Auspacken in einem Pattern-Matching Konstrukt funktioniert genauso, ein Datentyp der mehrere "Formen" mit komplett unterschiedlichen Strukturen und Inhalten annehmen kann [wie ein union aber doch wieder irgendwie ganz anders, mächtiger und sicherer], zum Beispiel der Typ std::net::IpAddr ist ein Enum das entweder V4 oder V6 sein kann und je nachdem komplett unterschiedliche Datenfelder hat, jedoch ist es vollkommen unmöglich Code zu schreiben der versehentlich auf die jeweils falschen Felder zugreift wenn man gerade ein Exemplar der einen oder der anderen Sorte vorliegen hat. Mit der selben Kraft des Enums kann man versehentliche Nullpointer-Dereferenzierung unmöglich machen. Ich glaube die Enums wurden in diesem Thread noch nicht ausreichend gewürdigt, ich finde dieses Konzept mindestens genauso genial wie das Ownership-System (wenngleich es auch schon etwas älter ist und in anderen Sprachen ebenfalls vorkommt), allein die Enums und das Pattern-Matching machen die Sprache schon extrem mächtig und nützlich. Irgendjemand hat auch mal Rust als Einstiegsdroge für Haskell bezeichnet, ich weiß zu wenig über Haskell um das kommentieren zu können aber mein Bauch sagt mir daß da zumindest teilweise was dran sein könnte.
:
Bearbeitet durch User
Hallo Bernd, schenk uns doch bitte mal ein MWE dazu, das wäre interessant(er). vlg Timm
Timm R. schrieb: > schenk uns doch bitte mal ein MWE dazu, das wäre interessant(er). Was ist ein "MWE"?
:
Bearbeitet durch User
S. R. schrieb: > Welche Sprache wäre denn deiner Meinung nach ein würdiger Nachfolger von > C? Jetzt sag aber bitte nicht C++ oder Assembler. Wer sagt, dass c einen Nachfolger hat oder braucht? Und wenn es einen braucht, was spricht gegen c++? Kaj G. schrieb: > Wie goto, nur deutlich weniger fehleranfaellig. Warum ist es weniger fehleranfällig? Wenn man goto nur in dieser Situation einsetzt, ist es das gleiche (das label steht an einer anderen Stelle). Kaj G. schrieb: > Was ich ebefalls schoen finde:fn main() {
1 | let cond = true; |
2 | |
3 | let x = if cond { |
4 | 5 |
5 | } else { |
6 | 6 |
7 | }; |
8 | } |
> In C/C++ muss man dazu x erstmal anlege und laesst es uninitialisiert > oder belegt es erstmal mit einen dummy Wert, der dann wieder > ueberschrieben werden muss. Ja, in einigen Fällen kann man so ohne uninitialisierte Variable auskommen, wo man sie in c++ nicht vermeiden kann. In den meisten Fällen kann man uninitialisierte Variablen aber leicht umgehen. Für dein Beispiel sieht das dann so aus:
1 | auto x = 6; |
2 | if(cond) { |
3 | x = 5; |
4 | }
|
Der Compiler erzeugt vermutlich identischen Code. Bei komplizierternen Fällen sollte man sich fragen, warum es so kompliziert ist und es vereinfachen. Dein Beispiel ist meiner Meinung nach ziemlich schlecht lesbar. Eine Variablen wird über 5 Zeilen initialisiert. Ich muss 5 Zeilen lesen bis ich weiß, welchen Wert und Typ x hat. If als Ausdruck mit Wert, macht die Definition der Sprache vllt. einfacher und eleganter, aber für mich nicht leichter lesbar. Genauso unübersichtlich sind Funktionen mit Rückgabewert aber ohne return. Kaj G. schrieb: > Boom: Wieder ein typisches Problem von C und C++ einfach so aus dem Weg > geraeumt. Ich kann mich nicht daran erinnern, dass das für mich in c oder c++ im letzten Jahrzehnt ein Problem gewesen ist. Nachdem ich den Fehler ein paar mal gemacht habe, habe ich mir ganz schnell angewöhnt Variablen zu initialisieren und Klassen so du designen, dass sie nur initialisiert existieren können. Davon abgesehen warnt mich mein Compiler vor uninitialiserten Variablen (bzw die ide während ich tippe). Kaj G. schrieb: > use of possibly uninitialized `x` Vor allem dieses "possibly" stört mich. Ich habe häufiger Variablen, bei denen der Compiler nicht wissen kann, ob sie initialisiert sind oder nicht. Und nein, es ist kein Sicherheitsrisiko, wenn man es sorgfältig macht.