Rust (programming language): Difference between revisions

Content deleted Content added
apply rust syntax highlighting to type name u8
probably this change should be applied globally (with a few selected exceptions)
Line 137:
 
=== Variables ===
[[Variable (computer science)|Variables]] in Rust are defined through the {{rust|let}} keyword.{{sfn|Klabnik|Nichols|2023|p=32}} The example below assigns a value to the variable with name {{coderust|foo}} and outputs its value.
 
<syntaxhighlight lang="rust">
Line 146:
</syntaxhighlight>
 
Variables are [[Immutable object|immutable]] by default, but adding the {{rust|mut}} keyword allows the variable to be mutated.{{sfn|Klabnik|Nichols|2023|pp=32-33}} The following example uses {{coderust|//}}, which denotes the start of a [[Comment (computer programming)|comment]].{{sfn|Klabnik|Nichols|2023|pp=49-50}}
 
<syntaxhighlight lang="rust">
Line 158:
</syntaxhighlight>
 
Multiple {{coderust|let}} expressions can define multiple variables with the same name, known as [[variable shadowing]]. Variable shadowing allows transforming variables without having to name the variables differently.{{sfn|Klabnik|Nichols|2023|pp=34-36}} The example below declares a new variable with the same name that is double the original value:
 
<syntaxhighlight lang="rust">
Line 202:
</syntaxhighlight>
 
==== {{coderust|if}} expressions ====
 
An {{rust|if}} [[conditional expression]] executes code based on whether the given value is {{coderust|true}}. {{rust|else}} can be used for when the value evaluates to {{coderust|false}}, and {{rust|else if}} can be used for combining multiple expressions.{{sfn|Klabnik|Nichols|2023|pp=50-53}}
 
<syntaxhighlight lang="rust">
Line 233:
</syntaxhighlight>
 
==== {{coderust|while}} loops ====
<code>[[While loop|while]]</code> can be used to repeat a block of code while a condition is met.{{sfn|Klabnik|Nichols|2023|p=56}}
 
Line 247:
</syntaxhighlight>
 
==== {{coderust|for}} loops and iterators ====
 
[[For loop]]s in Rust loop over elements of a collection.{{sfn|Klabnik|Nichols|2023|pp=57-58}}
Line 270:
</syntaxhighlight>
 
==== {{coderust|loop}} and {{coderust|break}} statements ====
 
More generally, the {{rust|loop}} keyword allows repeating a portion of code until a {{rust|break}} occurs. {{rust|break}} may optionally exit the loop with a value. In the case of nested loops, labels denoted by {{rust|'label_name}} can be used to break an outer loop rather than the innermost loop.{{sfn|Klabnik|Nichols|2023|pp=54-56}}
Line 379:
</syntaxhighlight>
 
The function {{coderust|print_string}} takes ownership over the {{rust|String}} value passed in; Alternatively, {{coderust|&}} can be used to indicate a [[Reference (computer science)|reference]] type (in {{coderust|&String}}) and to create a reference (in {{coderust|&s}}):{{sfn|Klabnik|Nichols|2023|pp=71–72}}
 
<syntaxhighlight lang="rust">
Line 396:
Because of these ownership rules, Rust types are known as ''[[linear types|linear]]'' or ''affine'' types, meaning each value can be used exactly once. This enforces a form of [[software fault isolation]] as the owner of a value is solely responsible for its correctness and deallocation.<ref name="BeyondSafety">{{Cite book |last1=Balasubramanian |first1=Abhiram |last2=Baranowski |first2=Marek S. |last3=Burtsev |first3=Anton |last4=Panda |first4=Aurojit |last5=Rakamarić |first5=Zvonimir |last6=Ryzhyk |first6=Leonid |title=Proceedings of the 16th Workshop on Hot Topics in Operating Systems |chapter=System Programming in Rust |date=2017-05-07 |chapter-url=https://doi.org/10.1145/3102980.3103006 |series=HotOS '17 |___location=New York, NY, US |publisher=Association for Computing Machinery |pages=156–161 |doi=10.1145/3102980.3103006 |isbn=978-1-4503-5068-6 |s2cid=24100599 |access-date=June 1, 2022 |archive-date=June 11, 2022 |archive-url=https://web.archive.org/web/20220611034046/https://dl.acm.org/doi/10.1145/3102980.3103006 |url-status=live}}</ref>
 
When a value goes out of scope, it is ''dropped'' by running its [[Destructor (computer programming)|destructor]]. The destructor may be programmatically defined through implementing the {{coderust|Drop}} [[#Traits|trait]]. This helps manage resources such as file handles, network sockets, and [[Lock (computer science)|locks]], since when objects are dropped, the resources associated with them are closed or released automatically.{{sfn|Klabnik|Nichols|2023|pp=327-30}}
 
==== Lifetimes ====
 
[[Object lifetime]] refers to the period of time during which a reference is valid; that is, the time between the object creation and destruction.<ref>{{Cite web |title=Lifetimes |url=https://doc.rust-lang.org/rust-by-example/scope/lifetime.html |access-date=2024-10-29 |website=Rust by Example |archive-date=2024-11-16 |archive-url=https://web.archive.org/web/20241116192422/https://doc.rust-lang.org/rust-by-example/scope/lifetime.html |url-status=live }}</ref> These ''lifetimes'' are implicitly associated with all Rust reference types. While often inferred, they can also be indicated explicitly with named lifetime parameters (often denoted {{coderust|'a}}, {{coderust|'b}}, and so on).<ref>{{Cite web |title=Explicit annotation |url=https://doc.rust-lang.org/rust-by-example/scope/lifetime/explicit.html |access-date=2024-10-29 |website=Rust by Example}}</ref>
 
Lifetimes in Rust can be thought of as [[Scope (computer science)|lexically scoped]], meaning that the duration of an object lifetime is inferred from the set of locations in the source code (i.e., function, line, and column numbers) for which a variable is valid.{{sfn|Klabnik|Nichols|2019|p=194}} For example, a reference to a local variable has a lifetime corresponding to the block it is defined in:{{sfn|Klabnik|Nichols|2019|p=194}}
Line 416:
</syntaxhighlight>
 
The borrow checker in the Rust compiler then enforces that references are only used in the locations of the source code where the associated lifetime is valid.{{sfn|Klabnik|Nichols|2019|pp=75,134}}<ref>{{Cite web |last=Shamrell-Harrington |first=Nell |date=2022-04-15 |title=The Rust Borrow Checker – a Deep Dive |url=https://www.infoq.com/presentations/rust-borrow-checker/ |access-date=2022-06-25 |website=InfoQ |language=en |archive-date=2022-06-25 |archive-url=https://web.archive.org/web/20220625140128/https://www.infoq.com/presentations/rust-borrow-checker/ |url-status=live }}</ref> In the example above, storing a reference to variable {{coderust|x}} in {{coderust|r}} is valid, as variable {{coderust|x}} has a longer lifetime ({{coderust|'a}}) than variable {{coderust|r}} ({{coderust|'b}}). However, when {{coderust|x}} has a shorter lifetime, the borrow checker would reject the program:
 
<syntaxhighlight lang="rust">
Line 431:
</syntaxhighlight>
 
Since the lifetime of the referenced variable ({{coderust|'b}}) is shorter than the lifetime of the variable holding the reference ({{coderust|'a}}), the borrow checker errors, preventing {{coderust|x}} from being used from outside its scope.{{sfn|Klabnik|Nichols|2019|pp=194-195}}
 
Lifetimes can be indicated using explicit ''lifetime parameters'' on function arguments. For example, the following code specifies that the reference returned by the function has the same lifetime as {{coderust|original}} (and ''not'' necessarily the same lifetime as {{coderust|prefix}}):{{sfn|Klabnik|Nichols|2023|pp=208–12}}
 
<syntaxhighlight lang="rust">
Line 453:
==== Standard library ====
 
The Rust [[standard library]] defines and implements many widely used custom data types, including core data structures such as {{coderust|Vec}}, {{coderust|Option}}, and {{coderust|HashMap}}, as well as [[smart pointer]] types. Rust also provides a way to exclude most of the standard library using the attribute {{rust|#![no_std]}}, for applications such as embedded devices. Internally, the standard library is divided into three parts, {{coderust|core}}, {{coderust|alloc}}, and {{coderust|std}}, where {{coderust|std}} and {{Coderust|alloc}} are excluded by {{rust|#![no_std]}}.{{sfn|Gjengset|2021|pp=213-215}}
 
Rust uses [[Option type|<code>Option</code>]] to define optional values, which can be matched using <code>if let</code> or <code>match</code> to access the inner value:{{sfn|Klabnik|Nichols|2023|pp=108-110,113-114,116-117}}
Line 482:
 
=== Polymorphism ===
Rust supports [[bounded parametric polymorphism]] through [[Trait (computer programming)|traits]] and [[generic function]]s.{{sfn|Klabnik|Nichols|2023|p=378}} Common behavior between types may be declared using traits and {{coderust|impl}}s:{{sfn|Klabnik|Nichols|2023|pp=192-198}}
 
<syntaxhighlight lang="rust">
Line 504:
</syntaxhighlight>
 
The example above also includes a method {{coderust|is_zero}} which provides a default implementation that is not required when implementing the trait.{{sfn|Klabnik|Nichols|2023|pp=192-198}}
 
A function can then be made generic by adding type parameters inside angle brackets ({{coderust|<Num>}}), which only allow types that implement the trait:
 
<syntaxhighlight lang="rust">
Line 521:
</syntaxhighlight>
 
In the examples above, {{coderust|Num: Zero}} as well as {{coderust|where Self: PartialEq}} are trait bounds that constrain the type to only allow types that implement {{coderust|Zero}} or {{coderust|PartialEq}}.{{sfn|Klabnik|Nichols|2023|pp=192-198}} Within a trait or impl, {{coderust|Self}} refers to the type that the code is implementing.{{sfn|Klabnik|Nichols|2023|p=98}}
 
Generics can be used in functions to allow implementing a behavior for different types without repeating the same code. Generic functions can be written in relation to other generics, without knowing the actual type.{{sfn|Klabnik|Nichols|2019|pp=171–172,205}}
Line 556:
=== Unsafe ===
 
Rust's memory safety checks may be circumvented through the use of {{coderust|unsafe}} blocks. This allows programmers to deference arbitrary raw pointers, call external code, or perform other low-level functionality not allowed by safe Rust.{{sfn|Klabnik|Nichols|2023|pp=420-429}} Some low-level functionality enabled in this way includes [[Volatile (computer programming)|volatile memory access]], architecture-specific intrinsics, [[type punning]], and inline assembly.{{sfn|McNamara|2021|p=139, 376–379, 395}}
 
Unsafe code is sometimes needed to implement complex data structures.<ref name="UnsafeRustUse">{{Cite journal |last1=Astrauskas |first1=Vytautas |last2=Matheja |first2=Christoph |last3=Poli |first3=Federico |last4=Müller |first4=Peter |last5=Summers |first5=Alexander J. |date=2020-11-13 |title=How do programmers use unsafe rust? |url=https://dl.acm.org/doi/10.1145/3428204 |journal=Proceedings of the ACM on Programming Languages |language=en |volume=4 |issue=OOPSLA |pages=1–27 |doi=10.1145/3428204 |issn=2475-1421|hdl=20.500.11850/465785 |hdl-access=free}}</ref> A frequently cited example is that it is difficult or impossible to implement [[doubly linked list]]s in safe Rust.<ref>{{Cite journal |last=Lattuada |first=Andrea |last2=Hance |first2=Travis |last3=Cho |first3=Chanhee |last4=Brun |first4=Matthias |last5=Subasinghe |first5=Isitha |last6=Zhou |first6=Yi |last7=Howell |first7=Jon |last8=Parno |first8=Bryan |last9=Hawblitzel |first9=Chris |date=2023-04-06 |title=Verus: Verifying Rust Programs using Linear Ghost Types |url=https://dl.acm.org/doi/10.1145/3586037 |journal=Software Artifact (virtual machine, pre-built distributions) for "Verus: Verifying Rust Programs using Linear Ghost Types" |volume=7 |issue=OOPSLA1 |pages=85:286–85:315 |doi=10.1145/3586037}}</ref><ref>{{Cite journal |last=Milano |first=Mae |last2=Turcotti |first2=Julia |last3=Myers |first3=Andrew C. |date=2022-06-09 |title=A flexible type system for fearless concurrency |url=https://dl.acm.org/doi/10.1145/3519939.3523443 |journal=Proceedings of the 43rd ACM SIGPLAN International Conference on Programming Language Design and Implementation |series=PLDI 2022 |___location=New York, NY, USA |publisher=Association for Computing Machinery |pages=458–473 |doi=10.1145/3519939.3523443 |isbn=978-1-4503-9265-5}}</ref><ref>{{Cite web |title=Introduction - Learning Rust With Entirely Too Many Linked Lists |url=https://rust-unofficial.github.io/too-many-lists/ |access-date=2025-08-06 |website=rust-unofficial.github.io}}</ref><ref>{{Cite journal |last=Noble |first=James |last2=Mackay |first2=Julian |last3=Wrigstad |first3=Tobias |date=2023-10-16 |title=Rusty Links in Local Chains✱ |url=https://doi.org/10.1145/3611096.3611097 |journal=Proceedings of the 24th ACM International Workshop on Formal Techniques for Java-like Programs |series=FTfJP '22 |___location=New York, NY, USA |publisher=Association for Computing Machinery |pages=1–3 |doi=10.1145/3611096.3611097 |isbn=979-8-4007-0784-1}}</ref>
Line 607:
</syntaxhighlight>
 
The {{rust|#[repr(C)]}} attribute enables deterministic memory layouts for {{rust|struct}}s and {{rust|enum}}s for use across FFI boundaries.{{sfn|Gjengset|2021|pp=193-209}} External libraries such as {{coderust|bindgen}} and {{coderust|cxx}} can generate Rust bindings for C/C++.{{sfn|Gjengset|2021|pp=193-209}}<ref>{{Cite web|title=Safe Interoperability between Rust and C++ with CXX|url=https://www.infoq.com/news/2020/12/cpp-rust-interop-cxx/|date=2020-12-06|access-date=2021-01-03|website=InfoQ|language=en|archive-date=January 22, 2021|archive-url=https://web.archive.org/web/20210122142035/https://www.infoq.com/news/2020/12/cpp-rust-interop-cxx/|url-status=live}}</ref>
 
== Ecosystem ==
Line 637:
Following Rust 1.0, new features are developed in ''nightly'' versions which are released daily. During each six-week release cycle, changes to nightly versions are released to beta, while changes from the previous beta version are released to a new stable version.<ref name="Rust Book G">{{harvnb|Klabnik|Nichols|2019|loc=Appendix G – How Rust is Made and "Nightly Rust"}}</ref>
 
Every two or three years, a new "edition" is produced. Editions are released to allow making limited [[breaking changes]], such as promoting {{coderust|await}} to a keyword to support [[async/await]] features. Crates targeting different editions can interoperate with each other, so a crate can upgrade to a new edition even if its callers or its dependencies still target older editions. Migration to a new edition can be assisted with automated tooling.{{sfn|Blandy|Orendorff|Tindall|2021|pp=176–177}}
 
=== IDE support ===