Software-update: Rust 1.80.0

Rust logo (79 pix)Rust is een programmeertaal bedacht door Graydon Hoare en oorspronkelijk ontwikkeld door Mozilla. Het is deels geïnspireerd op de programmeertaal C, maar kent syntactische en semantische verschillen. Het focust op veiligheid en beoogt moderne computersystemen efficiënter te benutten. Het wordt ingezet door onder andere Cloudflare, OVH, Mozilla, Deliveroo, Coursera, AppSignal en Threema. Versie 1.80 is uitgebracht en de releasenotes voor die uitgave kunnen hieronder worden gevonden.

LazyCell and LazyLock

These "lazy" types delay the initialization of their data until first access. They are similar to the OnceCell and OnceLock types stabilized in 1.70, but with the initialization function included in the cell. This completes the stabilization of functionality adopted into the standard library from the popular lazy_static and once_cell crates.

LazyLock is the thread-safe option, making it suitable for places like static values. For example, both the spawn thread and the main scope will see the exact same duration below, since LAZY_TIME will be initialized once, by whichever ends up accessing the static first. Neither use has to know how to initialize it, unlike they would with OnceLock::get_or_init().

LazyCell does the same thing without thread synchronization, so it doesn't implement Sync, which is needed for static, but it can still be used in thread_local! statics (with distinct initialization per thread). Either type can also be used in other data structures as well, depending on thread-safety needs, so lazy initialization is available everywhere!

Checked cfg names and values

In 1.79, rustc stabilized a --check-cfg flag, and now Cargo 1.80 is enabling those checks for all cfg names and values that it knows (in addition to the well known names and values from rustc). This includes feature names from Cargo.toml as well as new cargo::rustc-check-cfg output from build scripts.

Unexpected cfgs are reported by the warn-by-default unexpected_cfgs lint, which is meant to catch typos or other misconfiguration. For example, in a project with an optional rayon dependency, this code is configured for the wrong feature value. The same warning is reported regardless of whether the actual rayon feature is enabled or not.

The [lints] table in the Cargo.toml manifest can also be used to extend the list of known names and values for custom cfg. rustc automatically provides the syntax to use in the warning.

[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(foo, values("bar"))'] }

You can read more about this feature in a previous blog post announcing the availability of the feature on nightly.

Exclusive ranges in patterns

Rust ranged patterns can now use exclusive endpoints, written a..b or ..b similar to the Range and RangeTo expression types. For example, the following patterns can now use the same constants for the end of one pattern and the start of the next:

Previously, only inclusive (a..=b or ..=b) or open (a..) ranges were allowed in patterns, so code like this would require separate constants for inclusive endpoints like K - 1.

Exclusive ranges have been implemented as an unstable feature for a long time, but the blocking concern was that they might add confusion and increase the chance of off-by-one errors in patterns. To that end, exhaustiveness checking has been enhanced to better detect gaps in pattern matching, and new lints non_contiguous_range_endpoints and overlapping_range_endpoints will help detect cases where you might want to switch exclusive patterns to inclusive, or vice versa.

Stabilized APIs

These APIs are now stable in const contexts:

Other changes

Check out everything that changed in Rust, Cargo, and Clippy.

Rust

Versienummer 1.80.0
Releasestatus Final
Website The Rust Programming Language Blog
Download https://www.rust-lang.org/install.html
Licentietype Voorwaarden (GNU/BSD/etc.)

Door Bart van Klaveren

Downloads en Best Buy Guide

26-07-2024 • 08:00

8

Submitter: danmark_ori

Bron: The Rust Programming Language Blog

Update-historie

09-08 Rust 1.89.0 1
27-06 Rust 1.88.0 8
16-05 Rust 1.87.0 1
04-04 Rust 1.86.0 0
21-02 Rust 1.85.0 0
31-01 Rust 1.84.1 0
10-01 Rust 1.84.0 0
11-'24 Rust 1.83.0 5
09-'24 Rust 1.81.0 1
07-'24 Rust 1.80.0 8
Meer historie

Reacties (8)

8
8
8
0
0
0
Wijzig sortering
Als ik de screenshot bekijk, lijkt Rust me meer geïnspireerd op C++ dan op C, het is iig object georiënteerd.

Correctie: Het is niet helemaal een echte OOP taal lees ik op hun site, maar het heeft wat karakteristieken van een OOP

[Reactie gewijzigd door Dann74 op 26 juli 2024 08:39]

Het is dan ook bedoeld als vervanging voor C++. Mozilla gebruikt het voor heel veel onderdelen van hun browser Firefox.

Het grote voordeel van Rust is dat je niet zomaar iets fout of onveilig kan doen en dat het dan alsnog kan compilen. Is iets niet goed? Dan krijg je een foutmelding bij compilatie en weigert de compiler verder te gaan. (Dit kun je zoals hieronder wel weer omzeilen).

In principe betekent een succesvolle compilatie ook veilige en daarnaast thread-safe code.

Ook bestaat er in Rust standaard maar heel weinig "undefined behavior". In principe wordt undefined behavior ook gewoon opgepakt als compilatiefout als er geen "unsafe"-tag bij staat.

In C++ heb je dat dus niet zo snel. Je kan van alles fout doen maar alsnog een werkende applicatie hebben die zo lek als een mandje is.

[Reactie gewijzigd door MrFax op 26 juli 2024 08:45]

T is idd een soort mengsel. Volgens mij heb je geen inheritance bijv.
OO als definitie is los genoeg dat je kunt stellen dat je het toepast ook in verder functionele/procedurele talen zoals Rust of Go (of Ocaml of Zig). Maar echt object georienteerde talen, wat Rust absoluut niet is, die werken op basis van classes en inheritance.

Rust trekt meer inspiratie uit Ocaml, overigens.

Ik ben zelf meer naar Go toegegroeid vanuit een Java historie maar heb ook eerst een woeste poging gedaan met Rust. Ik spreek uit ervaring dat het een lastige taak is om het OO-juk los te laten voordat je code schrijft zoals het volgens die taal bedoeld is. Als je Java, C# of C++ gewend was dan ga je bij bijna elke regel code de Rust borrow checker boos maken wegens "lomp" gebruik van variabelen.
Het hangt er helemaal vanaf wat je als OOP beschouwt.
Als class inheritance de kern is van OOP dan is Rust gelukkig niet OOP; ervaring toont aan dat class inheritance er in eerste instantie handig uitziet ("want dan kunnen classes code delen!") maar het devolueert nogal snel tot een onbegrijpelijk rommeltje met diepe inheritance hierarchies, en classes die code delen die dat helemaal niet zouden moeten doen.

War Rust wel aanbiedt is ad-hoc polymorphism in de vorm van traits, dat wordt vaak ook als onderdeel beschouwd van OOP hoewel het eigenlijk een breder inzetbare techniek is.

Verder zou ik zeggen dat Rust veel meer DNA erft van een hoop PLs waar de meeste mensen nog nooit van hebben gehoord. Denk daarbij aan het ownership system en hoe borrowing werkt, pattern matching, functional programming support, de macro systemen (die o.a. embedded DSLs mogelijk maken), de trait en type systemen, etc.
De vergelijking met C++ is vooral qua inzetbaarheid (zelfde target niches), en ziet het er natuurlijk in syntactische termen uit als een telg uit de C familie, net als C++. Maar datzelfde geldt ook voor bv Java, Kotlin, Groovy, Zig, etc.

[Reactie gewijzigd door Jeanpaul145 op 26 juli 2024 16:46]

In het kader van indeling van computer talen naar generatie was Assembler echt een eerste generatie taal. En waren Pascal (de pure, dus niet turbo pascal of zo) en Modula2 echte 3e generatie talen: Functioneel/Procedureel). De taal C was formeel niet te plaatsen en viel tussen 2 en 3 in. De taal C++ was ook weer niet echt 4e generatie (Object oriented of zo). Als je dan op C en C++ een andere taal gaat baseren dan is die ongetwijfeld ook niet perfect in te delen.

Overigens is gebleken dat juist die tussen talen vaak gebruikt worden voor de serieuze zaken zoals kernels en drivers en dergelijke. Niet dat het de bedoeling is maar het werkt zo makkelijk. Wie heeft er ooit een driver in Modula2 geschreven?
Het typische overervingprobleem bij meervoudige overerving, the diamond problem komt niet voor bij Rust omdat ze de ontwerpprincipe composition over inheritance gekozen hebben.
Verder is mijn ervaring dat het in Rust inderdaad langer duurt voordat je je programma succesvol compileert, simpelweg omdat je veel eerder met al je datatype fouten geconfronteerd wordt. Maar de beloning is dat je vrijwel nooit meer fouten hebt die niet reproduceerbaar zijn (je kunt nog steeds een algoritme verkeert implementeren of een out-of-array verzoek doen, waarna je programma stopt). Dus uiteindelijk bereikt je sneller een hogere codekwaliteit, zeker omdat je aangemoedigd wordt om testbenches te schrijven.

[Reactie gewijzigd door scholtnp op 26 juli 2024 15:23]

Het diamond problem is een beetje een red herring in het OOP verhaal. Daarmee bedoel ik, ja het probleem waar het over gaat is echt, maar geen hond doet dat meer sinds de mid 90s.

De echte problemen met OOP zijn onlosmakelijk verbonden met class inheritance als concept, en zijn veel venijniger (lees: je hebt een significante code base van makkelijk 10+ KSLOC tegen de tijd dat je echt tegen die issues aanloopt) en dus niet makkelijk om vanaf te komen.
Denk daarbij aan code sharing tussen classes die dat niet zouden moeten doen (maar dat wel doen want "dat is makkelijk"; nevermind dat het je architectuur om zeep helpt), en diepe hiërarchieën die het lastig maken om uit te vogelen wat het totaal nou exact doet, te meer omdat daar dan allerlei andere shenanigans tussenin worden gebruikt.

Is het werkbaar te krijgen? Ja met veel discipline, net als bij malloc/free in C. En net als bij malloc/free wordt die discipline in verreweg de meeste gevallen niet afdoende toegepast, met voorspelbare gevolgen.

En Rust vervolgens lost dat probleem inderdaad op door struct/class inheritance helemaal weg te laten, en effectief alleen traits, een (flink complexere) doorontwikkeling van wat Java interfaces noemt, te gebruiken.

De complexiteit van traits vervolgens verandert de inzetbaarheid echt volledig overigens: iets als een collection trait maken zoals Java heeft gedaan is compleet zinloos in Rust, bijvoorbeeld. In feite hebben de standaard datastructuren helemaal geen traits voor hun basic APIs.

Op dit item kan niet meer gereageerd worden.