Rust syntax: Difference between revisions

Content deleted Content added
Cewbot (talk | contribs)
Tag: Redirect target changed
 
(13 intermediate revisions by 7 users not shown)
Line 1:
{{Short description|Set of rules defining correctly structured programs for the Rust programming language}}
#REDIRECT [[Rust_(programming_language)#Syntax and semantics]] {{Redirect category shell|
[[File:Screen1 2.png|thumb|A snippet of Rust code]]
{{R to section}}
 
The '''syntax of Rust''' is [[syntax|the set of rules]] defining how a [[Rust (programming language)|Rust]] program is written and compiled.
 
Rust's [[Syntax (programming languages)|syntax]] is similar to that of [[C (programming language)|C]] and [[C++]],<ref>{{Cite news |last=Proven |first=Liam |date=2019-11-27 |title=Rebecca Rumbul named new CEO of The Rust Foundation |url=https://www.theregister.com/2021/11/19/rust_foundation_ceo/ |access-date=2022-07-14 |website=[[The Register]] |language=en |quote="Both are curly bracket languages, with C-like syntax that makes them unintimidating for C programmers." |archive-date=2022-07-14 |archive-url=https://web.archive.org/web/20220714110957/https://www.theregister.com/2021/11/19/rust_foundation_ceo/ |url-status=live }}</ref><ref name=":4">{{Cite web |last=Vigliarolo |first=Brandon |date=2021-02-10 |title=The Rust programming language now has its own independent foundation |url=https://www.techrepublic.com/article/the-rust-programming-language-now-has-its-own-independent-foundation/ |archive-url=https://web.archive.org/web/20230320172900/https://www.techrepublic.com/article/the-rust-programming-language-now-has-its-own-independent-foundation/ |archive-date=2023-03-20 |access-date=2022-07-14 |website=[[TechRepublic]] |language=en-US}}</ref> although many of its features were influenced by [[functional programming]] languages such as [[OCaml]].{{sfn|Klabnik|Nichols|2019|p=263}}
 
== Basics ==
Although Rust syntax is heavily influenced by the syntaxes of C and C++, the syntax of Rust is far more distinct from [[C++ syntax]] than [[Java (programming language)|Java]] or [[C Sharp (programming language)|C#]], as those languages have more C-style declarations, primitive names, and keywords.
 
Below is a [["Hello, World!" program]] in Rust. The {{Rust|fn}} keyword denotes a [[Function (computer programming)|function]], and the {{Rust|println!}} [[Macro (computer science)|macro]] (see {{Section link|2=Macros|nopage=y}}) prints the message to [[standard output]].{{sfn|Klabnik|Nichols|2019|pp=5–6}} [[Statement (computer science)|Statements]] in Rust are separated by [[Semicolon#Programming|semicolons]].
<syntaxhighlight lang="rust">
fn main() {
println!("Hello, World!");
}
</syntaxhighlight>
 
=== Reserved words ===
==== Keywords ====
The following words are [[reserved word|reserved]], and may not be used as identifiers:
 
{{div col|colwidth=15em}}
* <code>as</code>
* <code>async</code>
* <code>await</code>
* <code>break</code>
* <code>const</code>
* <code>continue</code>
* <code>crate</code>
* <code>dyn</code>
* <code>else</code>
* <code>enum</code>
* <code>extern</code>
* <code>false</code>
* <code>fn</code>
* <code>for</code>
* <code>if</code>
* <code>impl</code>
* <code>in</code>
* <code>let</code>
* <code>loop</code>
* <code>match</code>
* <code>mod</code>
* <code>move</code>
* <code>mut</code>
* <code>pub</code>
* <code>ref</code>
* <code>return</code>
* <code>Self</code>
* <code>self</code>
* <code>static</code>
* <code>struct</code>
* <code>super</code>
* <code>trait</code>
* <code>true</code>
* <code>type</code>
* <code>union</code>
* <code>unsafe</code>
* <code>use</code>
* <code>where</code>
* <code>while</code>
{{div col end}}
 
==== Unused words ====
The following words are reserved as keywords, but currently have no use or purpose.
 
{{div col|colwidth=15em}}
* <code>abstract</code>
* <code>become</code>
* <code>box</code>
* <code>do</code>
* <code>final</code>
* <code>gen</code>
* <code>macro</code>
* <code>override</code>
* <code>priv</code>
* <code>try</code>
* <code>typeof</code>
* <code>unsized</code>
* <code>virtual</code>
* <code>yield</code>
{{div col end}}
 
=== 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 {{code|foo}} and outputs its value.
 
<syntaxhighlight lang="rust">
fn main() {
let foo: i32 = 10;
println!("The value of foo is {foo}");
}
</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 {{code|//}}, which denotes the start of a [[Comment (computer programming)|comment]].{{sfn|Klabnik|Nichols|2023|pp=49-50}}
 
<syntaxhighlight lang="rust">
fn main() {
// This code would not compile without adding "mut".
let mut foo: i32 = 10;
println!("The value of foo is {foo}");
foo = 20;
println!("The value of foo is {foo}");
}
</syntaxhighlight>
 
Multiple {{code|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">
fn main() {
let foo: i32 = 10;
// This will output "The value of foo is 10"
println!("The value of foo is {foo}");
let foo: i32 = foo * 2;
// This will output "The value of foo is 20"
println!("The value of foo is {foo}");
}
</syntaxhighlight>
 
Variable shadowing is also possible for values of different types. For example, going from a string to its length:
 
<syntaxhighlight lang="rust">
fn main() {
let letters: str = "abc";
let letters: usize = letters.len();
}
</syntaxhighlight>
 
=== Block expressions and control flow ===
 
A ''block expression'' is delimited by [[Bracket#Curly brackets|curly brackets]]. When the last expression inside a block does not end with a semicolon, the block evaluates to the value of that trailing expression:{{sfn|Klabnik|Nichols|2023|pp=6,47,53}}
 
<syntaxhighlight lang="rust">
fn main() {
let x: i32 = {
println!("this is inside the block");
1 + 2
};
println!("1 + 2 = {x}");
}
</syntaxhighlight>
 
Trailing expressions of function bodies are used as the return value:{{sfn|Klabnik|Nichols|2023|pp=47-48}}
 
<syntaxhighlight lang="rust">
fn add_two(x: i32) -> i32 {
x + 2
}
</syntaxhighlight>
 
==== {{code|if}} expressions ====
 
An {{rust|if}} [[conditional expression]] executes code based on whether the given value is {{code|true}}. {{rust|else}} can be used for when the value evaluates to {{code|false}}, and {{rust|else if}} can be used for combining multiple expressions.{{sfn|Klabnik|Nichols|2023|pp=50-53}}
 
<syntaxhighlight lang="rust">
fn main() {
let x: i32 = 10;
if x > 5 {
println!("value is greater than five");
}
 
if x % 7 == 0 {
println!("value is divisible by 7");
} else if x % 5 == 0 {
println!("value is divisible by 5");
} else {
println!("value is not divisible by 7 or 5");
}
}
</syntaxhighlight>
 
{{rust|if}} and {{rust|else}} blocks can evaluate to a value, which can then be assigned to a variable:{{sfn|Klabnik|Nichols|2023|pp=50-53}}
 
<syntaxhighlight lang="rust">
fn main() {
let x: i32 = 10;
let new_x: i32 = if x % 2 == 0 { x / 2 } else { 3 * x + 1 };
println!("{new_x}");
}
</syntaxhighlight>
 
==== {{code|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}}
 
<syntaxhighlight lang="rust">
fn main() {
// Iterate over all integers from 4 to 10
let mut value: i32 = 4;
while value <= 10 {
println!("value = {value}");
value += 1;
}
}
</syntaxhighlight>
 
==== {{code|for}} loops and iterators ====
 
[[For loop]]s in Rust loop over elements of a collection.{{sfn|Klabnik|Nichols|2023|pp=57-58}}
{{rust|for}} expressions work over any [[iterator]] type.
 
<syntaxhighlight lang="rust">
fn main() {
// Using `for` with range syntax for the same functionality as above
// The syntax 4..=10 means the range from 4 to 10, up to and including 10.
for value in 4..=10 {
println!("value = {value}");
}
}
</syntaxhighlight>
 
In the above code, {{rust|1=4..=10}} is a value of type {{rust|Range}} which implements the {{rust|Iterator}} trait. The code within the curly braces is applied to each element returned by the iterator.
 
Iterators can be combined with functions over iterators like {{rust|map}}, {{rust|filter}}, and {{rust|sum}}. For example, the following adds up all numbers between 1 and 100 that are multiples of 3:
 
<syntaxhighlight lang="rust">
(1..=100).filter(|&x: i8| -> bool x % 3 == 0).sum()
</syntaxhighlight>
 
==== {{code|loop}} and {{code|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}}
 
<syntaxhighlight lang="rust">
fn main() {
let value: i32 = 456;
let mut x: i32 = 1;
let y = loop {
x *= 10;
if x > value {
break x / 10;
}
};
println!("largest power of ten that is smaller than or equal to value: {y}");
 
let mut up: i32 = 1;
'outer: loop {
let mut down: i32 = 120;
loop {
if up > 100 {
break 'outer;
}
 
if down < 4 {
break;
}
 
down /= 2;
up += 1;
println!("up: {up}, down: {down}");
}
up *= 2;
}
}
</syntaxhighlight>
 
=== Pattern matching ===
The {{rust|match}} and {{rust|if let}} expressions can be used for [[pattern matching]]. For example, {{rust|match}} can be used to double an optional integer value if present, and return zero otherwise:{{sfn|Klabnik|Nichols|2019|pp=104–109}}
 
<syntaxhighlight lang="rust">
fn double(x: Option<u64>) -> u64 {
match x {
Some(y) => y * 2,
None => 0,
}
}
</syntaxhighlight>
 
Equivalently, this can be written with {{rust|if let}} and {{rust|else}}:
 
<syntaxhighlight lang="rust">
fn double(x: Option<u64>) -> u64 {
if let Some(y) = x {
y * 2
} else {
0
}
}
</syntaxhighlight>
 
== Types ==
Rust is [[strongly typed]] and [[statically typed]], meaning that the types of all variables must be known at compilation time. Assigning a value of a particular type to a differently typed variable causes a [[compilation error]]. [[Type inference]] is used to determine the type of variables if unspecified.{{sfn|Klabnik|Nichols|2019|pp=24}}
 
The type <code>()</code>, called the "unit type" in Rust, is a concrete type that has exactly one value. It occupies no memory (as it represents the absence of value). All functions that do not have an indicated return type implicitly return <code>()</code>. It is similar to {{cpp|void}} in other C-style languages, however {{cpp|void}} denotes the absence of a type and cannot have any value.
 
The default integer type is {{rust|i32}}, and the default [[floating point]] type is {{rust|f64}}. If the type of a [[Literal (computer programming)|literal]] number is not explicitly provided, it is either inferred from the context or the default type is used.{{sfn|Klabnik|Nichols|2019|pp=36–38}}
 
=== Primitive types ===
[[Integer type]]s in Rust are named based on the [[signedness]] and the number of bits the type takes. For example, {{rust|i32}} is a signed integer that takes 32 bits of storage, whereas {{code|u8}} is unsigned and only takes 8 bits of storage. {{rust|isize}} and {{rust|usize}} take storage depending on the architecture of the computer that runs the code, for example, on computers with [[32-bit architecture]]s, both types will take up 32 bits of space.
 
By default, integer literals are in base-10, but different [[radix|radices]] are supported with prefixes, for example, {{rust|0b11}} for [[binary number]]s, {{rust|0o567}} for [[octal]]s, and {{rust|0xDB}} for [[hexadecimal]]s. By default, integer literals default to {{rust|i32}} as its type. Suffixes such as {{rust|4u32}} can be used to explicitly set the type of a literal.{{sfn|Klabnik|Nichols|2023|pp=36-38}} Byte literals such as {{rust|b'X'}} are available to represent the [[ASCII]] value (as a {{rust|u8}}) of a specific character.{{sfn|Klabnik|Nichols|2023|p=502}}
 
The [[Boolean type]] is referred to as {{rust|bool}} which can take a value of either {{rust|true}} or {{rust|false}}. A {{rust|char}} takes up 32 bits of space and represents a Unicode scalar value: a [[Unicode codepoint]] that is not a [[Universal Character Set characters#Surrogates|surrogate]].<ref>{{Cite web |title=Glossary of Unicode Terms |url=https://www.unicode.org/glossary/ |access-date=2024-07-30 |website=[[Unicode Consortium]] |archive-date=2018-09-24 |archive-url=https://web.archive.org/web/20180924092749/http://www.unicode.org/glossary/ |url-status=live }}</ref> [[IEEE 754]] floating point numbers are supported with {{rust|f32}} for [[single precision float]]s and {{rust|f64}} for [[double precision float]]s.{{sfn|Klabnik|Nichols|2019|pp=38–40}}
 
=== Compound types ===
 
Compound types can contain multiple values. Tuples are fixed-size lists that can contain values whose types can be different. Arrays are fixed-size lists whose values are of the same type. Expressions of the tuple and array types can be written through listing the values, and can be accessed with {{rust|.index}} or {{rust|[index]}}:{{sfn|Klabnik|Nichols|2023|pp=40-42}}
 
<syntaxhighlight lang="rust">
let tuple: (u32, i64) = (3, -3);
let array: [i8; 5] = [1, 2, 3, 4, 5];
let value: bool = tuple.1; // -3
let value: i8 = array[2]; // 3
</syntaxhighlight>
 
Arrays can also be constructed through copying a single value a number of times:{{sfn|Klabnik|Nichols|2023|p=42}}
 
<syntaxhighlight lang="rust">
let array2: [char; 10] = [' '; 10];
</syntaxhighlight>
 
<!-- todo str, and ! -->
 
== Ownership and references ==
 
Rust's ownership system consists of rules that ensure memory safety without using a garbage collector. At compile time, each value must be attached to a variable called the ''owner'' of that value, and every value must have exactly one owner.{{sfn|Klabnik|Nichols|2019|pp=59–61}} Values are moved between different owners through assignment or passing a value as a function parameter. Values can also be ''borrowed,'' meaning they are temporarily passed to a different function before being returned to the owner.{{sfn|Klabnik|Nichols|2019|pp=63–68}} With these rules, Rust can prevent the creation and use of [[dangling pointers]]:{{sfn|Klabnik|Nichols|2019|pp=63–68}}{{sfn|Klabnik|Nichols|2019|pp=74–75}}
 
<syntaxhighlight lang="rust">
fn print_string(s: String) {
println!("{}", s);
}
 
fn main() {
let s: String = String::from("Hello, World");
print_string(s); // s consumed by print_string
// s has been moved, so cannot be used any more
// another print_string(s); would result in a compile error
}
</syntaxhighlight>
 
The function {{code|print_string}} takes ownership over the {{rust|String}} value passed in; Alternatively, {{code|&}} can be used to indicate a [[Reference (computer science)|reference]] type (in {{code|&String}}) and to create a reference (in {{code|&s}}):{{sfn|Klabnik|Nichols|2023|pp=71–72}}
 
<syntaxhighlight lang="rust">
fn print_string(s: &String) {
println!("{}", s);
}
 
fn main() {
let s: String = String::from("Hello, World");
print_string(&s); // s borrowed by print_string
print_string(&s); // s has not been consumed; we can call the function many times
}
</syntaxhighlight>
 
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 {{code|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 {{code|'a}}, {{code|'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}}
 
<syntaxhighlight lang="rust">
fn main() {
let x: i32 = 5; // ------------------+- Lifetime 'a
// |
let r: &i32 = &x; // -+-- Lifetime 'b |
// | |
println!("r: {}", r); // | |
// | |
// -+ |
} // ------------------+
</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 {{code|x}} in {{code|r}} is valid, as variable {{code|x}} has a longer lifetime ({{code|'a}}) than variable {{code|r}} ({{code|'b}}). However, when {{code|x}} has a shorter lifetime, the borrow checker would reject the program:
 
<syntaxhighlight lang="rust">
fn main() {
let r: &i32; // ------------------+- Lifetime 'a
// |
{ // |
let x: i32 = 5; // -+-- Lifetime 'b |
r = &x; // ERROR: x does | |
} // not live long -| |
// enough |
println!("r: {}", r); // |
} // ------------------+
</syntaxhighlight>
 
Since the lifetime of the referenced variable ({{code|'b}}) is shorter than the lifetime of the variable holding the reference ({{code|'a}}), the borrow checker errors, preventing {{code|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 {{code|original}} (and ''not'' necessarily the same lifetime as {{code|prefix}}):{{sfn|Klabnik|Nichols|2023|pp=208–12}}
 
<syntaxhighlight lang="rust">
fn remove_prefix<'a>(mut original: &'a str, prefix: &str) -> &'a str {
if original.starts_with(prefix) {
original = original[prefix.len()..];
}
original
}
</syntaxhighlight>
 
In the compiler, ownership and lifetimes work together to prevent memory safety issues such as dangling pointers.{{sfn|Klabnik|Nichols|2023|loc=[https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html 4.2. References and Borrowing]}}<ref name="Pearce">{{cite journal |last1=Pearce |first1=David |title=A Lightweight Formalism for Reference Lifetimes and Borrowing in Rust |url=https://dl.acm.org/doi/10.1145/3443420 |journal=ACM Transactions on Programming Languages and Systems |access-date=11 December 2024 |archive-url=https://web.archive.org/web/20240415053627/https://dl.acm.org/doi/10.1145/3443420 |archive-date=15 April 2024 |doi=10.1145/3443420 |date=17 April 2021 |volume=43 |pages=1–73 |url-status=live}}</ref>
 
== User-defined types ==
User-defined types are created with the {{rust|struct}} or {{rust|enum}} keywords. The {{rust|struct}} keyword is used to denote a [[Record (computer science)|record type]] that groups multiple related values.{{sfn|Klabnik|Nichols|2019|p=83}} {{rust|enum}}s can take on different variants at runtime, with its capabilities similar to [[algebraic data types]] found in functional programming languages.{{sfn|Klabnik|Nichols|2019|p=97}} Both records and enum variants can contain [[Field (computer science)|fields]] with different types.{{sfn|Klabnik|Nichols|2019|pp=98–101}} Alternative names, or aliases, for the same type can be defined with the {{rust|type}} keyword.{{sfn|Klabnik|Nichols|2019|pp=438–440}}
 
The {{rust|impl}} keyword can define methods for a user-defined type. Data and functions are defined separately. Implementations fulfill a role similar to that of [[Class (computer programming)|classes]] within other languages.{{sfn|Klabnik|Nichols|2019|pp=93}}
 
=== Standard library ===
{| class="wikitable"
|+Summary of Rust's types in the [[standard library]]
!Type
!Description
!Examples
|-
|{{Rust|String}}
|UTF-8-encoded strings (dynamic)
|{{plainlist|
* {{Rust|String::new()}}
* {{Rust|String::from("Hello")}}
* {{Rust|"🦀🦀🦀".to_string()}}
}}
|-
|{{plainlist|
* {{Rust|OsStr}}
* {{Rust|OsString}}
}}
|Platform-native strings<ref group="note" name="OsString">On Unix systems, this is often UTF-8 strings without an internal 0 byte. On Windows, this is [[UTF-16]] strings without an internal 0 byte. Unlike these, {{Rust|str}} and {{Rust|String}} are always valid UTF-8 and can contain internal zeros.</ref> (borrowed<ref>{{Cite web |title=OsStr in std::ffi |url=https://doc.rust-lang.org/beta/std/ffi/struct.OsStr.html |access-date=2023-10-02 |website=The Rust Standard Library documentation |archive-date=2023-06-23 |archive-url=https://web.archive.org/web/20230623184907/https://doc.rust-lang.org/beta/std/ffi/struct.OsStr.html |url-status=live }}</ref> and dynamic<ref>{{Cite web |title=OsString in std::ffi |url=https://doc.rust-lang.org/beta/std/ffi/struct.OsString.html |access-date=2023-10-02 |website=The Rust Standard Library documentation |archive-date=2023-06-24 |archive-url=https://web.archive.org/web/20230624103428/https://doc.rust-lang.org/beta/std/ffi/struct.OsString.html |url-status=live }}</ref>)
|{{plainlist|
* {{Rust|OsStr::new("Hello")}}
* {{Rust|OsString::from("world")}}
}}
|-
|{{plainlist|
* {{Rust|Path}}
* {{Rust|PathBuf}}
}}
|[[Path (computing)|Paths]] (borrowed<ref>{{Cite web |title=Path in std::path |url=https://doc.rust-lang.org/beta/std/path/struct.Path.html |access-date=2023-10-02 |website=The Rust Standard Library documentation |archive-date=2023-06-24 |archive-url=https://web.archive.org/web/20230624103428/https://doc.rust-lang.org/beta/std/path/struct.Path.html |url-status=live }}</ref> and dynamic<ref>{{Cite web |title=PathBuf in std::path |url=https://doc.rust-lang.org/beta/std/path/struct.PathBuf.html |access-date=2023-10-02 |website=The Rust Standard Library documentation |archive-date=2023-06-27 |archive-url=https://web.archive.org/web/20230627034115/https://doc.rust-lang.org/beta/std/path/struct.PathBuf.html |url-status=live }}</ref>)
|{{plainlist|
* {{Rust|Path::new("./path/to")}}
* {{Rust|PathBuf::from(r"C:.\path\to")}}
}}
|-
|{{plainlist|
* {{Rust|CStr}}
* {{Rust|CString}}
}}
|[[C (programming language)|C]]-compatible, [[null-terminated string]]s (borrowed<ref name="std::boxed">{{Cite web |title=std::boxed |url=https://doc.rust-lang.org/std/boxed/index.html |access-date=2023-06-23 |website=The Rust Standard Library documentation |archive-date=2023-06-23 |archive-url=https://web.archive.org/web/20230623184904/https://doc.rust-lang.org/std/boxed/index.html |url-status=live }}</ref> and dynamic<ref name="std::boxed"/>)
|{{plainlist|
* {{Rust|c"Hello"}}
* {{Rust|CStr::from_bytes_with_nul(b"Hello\0").unwrap()}}
* {{Rust|CString::new("world").unwrap()}}
}}
|-
|{{Rust|Vec<T>}}
|[[Dynamic array]]s
|{{plainlist|
* {{Rust|Vec::new()}}
* {{Rust|vec![1, 2, 3, 4, 5]}}
}}
|-
|{{Rust|Option<T>}}
|[[Option type]]
|{{plainlist|
* {{Rust|None}}
* {{Rust|Some(3)}}
* {{Rust|Some("hello")}}
}}
|-
|{{Rust|Result<T, E>}}
|[[Exception handling|Error handling]] using a [[result type]]
|{{plainlist|
* {{Rust|Ok(3)}}
* {{Rust|Err("something went wrong")}}
}}
|-
|{{Rust|Box<T>}}
|A pointer to a [[Heap (programming)|heap]]-allocated value.<ref name="std::boxed"/> Similar to C++'s [https://en.cppreference.com/w/cpp/memory/unique_ptr std::unique_ptr].
| <syntaxhighlight lang="rust">
let boxed: Box<u8> = Box::new(5);
let val: u8 = *boxed;
</syntaxhighlight>
|-
|{{Rust|Rc<T>}}
|[[Reference counting]] pointer<ref>{{Cite web |title=Rc in std::rc |url=https://doc.rust-lang.org/beta/std/rc/struct.Rc.html |access-date=2023-06-24 |website=The Rust Standard Library documentation |archive-date=2023-06-24 |archive-url=https://web.archive.org/web/20230624080501/https://doc.rust-lang.org/beta/std/rc/struct.Rc.html |url-status=live }}</ref>
|<syntaxhighlight lang="rust">
let five: Rc<u8> = Rc::new(5);
let also_five: Rc<u8> = five.clone();
</syntaxhighlight>
|-
|{{Rust|Arc<T>}}
|[[Linearizability|Atomic]], [[Thread safety|thread-safe]] reference counting pointer<ref>{{Cite web |title=Arc in std::sync |url=https://doc.rust-lang.org/beta/std/sync/struct.Arc.html |access-date=2023-06-24 |website=The Rust Standard Library documentation |archive-date=2023-06-24 |archive-url=https://web.archive.org/web/20230624080503/https://doc.rust-lang.org/beta/std/sync/struct.Arc.html |url-status=live }}</ref>
|<syntaxhighlight lang="rust">
let foo: Arc<Vec<f32>> = Arc::new(vec![1.0, 2.0]);
let a: Arc<Vec<f32>> = foo.clone(); // a can be sent to another thread
</syntaxhighlight>
|-
|{{Rust|Cell<T>}}
|A mutable memory ___location<ref>{{Cite web |title=Cell in std::cell |url=https://doc.rust-lang.org/beta/std/cell/struct.Cell.html |access-date=2023-06-24 |website=The Rust Standard Library documentation |archive-date=2023-06-24 |archive-url=https://web.archive.org/web/20230624080506/https://doc.rust-lang.org/beta/std/cell/struct.Cell.html |url-status=live }}</ref>
|<syntaxhighlight lang="rust">
let c: Cell<u8> = Cell::new(5);
c.set(10);
</syntaxhighlight>
|-
|<code>Mutex<T></code>
|A [[Lock (computer science)|mutex lock]] for shared data contained within.<ref>{{Cite web |title=Mutex in std::sync |url=https://doc.rust-lang.org/beta/std/sync/struct.Mutex.html |access-date=2023-06-24 |website=The Rust Standard Library documentation |archive-date=2023-06-24 |archive-url=https://web.archive.org/web/20230624080502/https://doc.rust-lang.org/beta/std/sync/struct.Mutex.html |url-status=live }}</ref>
|<syntaxhighlight lang="rust">
let mutex: Mutex<u32> = Mutex::new(0_u32);
let _guard: LockResult<MutexGuard<'_, u32>> = mutex.lock();
</syntaxhighlight>
|-
|{{Rust|RwLock<T>}}
|[[Readers–writer lock]]<ref>{{Cite web |title=RwLock in std::sync |url=https://doc.rust-lang.org/beta/std/sync/struct.RwLock.html |access-date=2023-06-24 |website=The Rust Standard Library documentation |archive-date=2023-06-24 |archive-url=https://web.archive.org/web/20230624080503/https://doc.rust-lang.org/beta/std/sync/struct.RwLock.html |url-status=live }}</ref>
|<syntaxhighlight lang="rust">
let lock: RwLock<u8> = RwLock::new(5);
let r1: u8 = lock.read().unwrap();
</syntaxhighlight>
|-
|{{Rust|Condvar}}
|A [[Monitor (synchronization)|conditional monitor]] for shared data<ref>{{Cite web |title=Condvar in std::sync |url=https://doc.rust-lang.org/beta/std/sync/struct.Condvar.html |access-date=2023-06-24 |website=The Rust Standard Library documentation |archive-date=2023-06-24 |archive-url=https://web.archive.org/web/20230624080504/https://doc.rust-lang.org/beta/std/sync/struct.Condvar.html |url-status=live }}</ref>
|<syntaxhighlight lang="rust">
let (lock, cvar): (Mutex<bool>, Condvar) = (Mutex::new(true), Condvar::new());
// As long as the value inside the `Mutex<bool>` is `true`, we wait.
let _guard: Mutex<bool> = cvar.wait_while(lock.lock().unwrap(), |pending| { *pending }).unwrap();
 
</syntaxhighlight>
|-
|{{Rust|Duration}}
|Type that represents a span of time<ref>{{Cite web |title=Duration in std::time |url=https://doc.rust-lang.org/beta/std/time/struct.Duration.html |access-date=2023-06-24 |website=The Rust Standard Library documentation |archive-date=2023-06-24 |archive-url=https://web.archive.org/web/20230624080503/https://doc.rust-lang.org/beta/std/time/struct.Duration.html |url-status=live }}</ref>
|<syntaxhighlight lang="rust">
Duration::from_millis(1) // 1ms
</syntaxhighlight>
|-
|{{Rust|1=HashMap<K, V>}}
|[[Hash table]]<ref>{{Cite web |title=HashMap in std::collections |url=https://doc.rust-lang.org/beta/std/collections/struct.HashMap.html |access-date=2023-06-24 |website=The Rust Standard Library documentation |archive-date=2023-06-24 |archive-url=https://web.archive.org/web/20230624080505/https://doc.rust-lang.org/beta/std/collections/struct.HashMap.html |url-status=live }}</ref>
|<syntaxhighlight lang="rust">
let mut player_stats: HashMap<String, u32> = HashMap::new();
player_stats.insert("damage", 1);
player_stats.entry("health").or_insert(100);
</syntaxhighlight>
|-
|{{Rust|1=BTreeMap<K, V>}}
|[[B-tree]]<ref>{{Cite web |title=BTreeMap in std::collections |url=https://doc.rust-lang.org/beta/std/collections/struct.BTreeMap.html |access-date=2023-06-24 |website=The Rust Standard Library documentation |archive-date=2023-06-24 |archive-url=https://web.archive.org/web/20230624080503/https://doc.rust-lang.org/beta/std/collections/struct.BTreeMap.html |url-status=live }}</ref>
|<syntaxhighlight lang="rust">
let mut solar_distance: BTreeMap<String, f32> = BTreeMap::from([
("Mercury", 0.4),
("Venus", 0.7),
]);
solar_distance.entry("Earth").or_insert(1.0);
 
</syntaxhighlight>
|}
 
[[Option type|<code>Option</code>]] values are handled using [[syntactic sugar]], such as the <code>if let</code> construction, to access the inner value (in this case, a string):{{sfn|McNamara|2021}}
 
<syntaxhighlight lang="rust">
fn main() {
let name1: Option<&str> = None;
// In this case, nothing will be printed out
if let Some(name) = name1 {
println!("{name}");
}
 
let name2: Option<&str> = Some("Matthew");
// In this case, the word "Matthew" will be printed out
if let Some(name) = name2 {
println!("{name}");
}
}
</syntaxhighlight>
 
== Pointers ==
{| class="wikitable"
|+Summary of Rust's [[Pointer (computer programming)|pointer]] and [[Reference (computer science)|reference]] primitive types
!Type
!Description
!Examples
|-
|{{plainlist|
* {{Rust|&T}}
* {{Rust|&mut T}}
}}
|[[Reference (computer science)|References]] (immutable and mutable)
|{{plainlist|
* {{Rust|let x_ref: &T {{=}} {{not a typo|&x;}}}}
* {{Rust|let x_ref: &mut T {{=}} &mut x;}}
}}
|-
|{{plainlist|
* {{Rust|Option<&T>}}
* {{Rust|Option<&mut T>}}
}}
|{{plainlist|
* Option wrapped reference
* Possibly null reference
}}
|{{plainlist|
* {{Rust|None}}
* {{Rust|let x_ref: Option<&T> {{=}} Some(&x);}}
* {{Rust|let x_ref: Option<&mut T> {{=}} Some(&mut x);}}
}}
|-
|{{Plain list|* {{Rust|Box<T>}}
* {{Rust|Option<Box<T>>}}}}
|A pointer to heap-allocated value
(or possibly null pointer if wrapped in option)<ref name="std::boxed"/>
|{{Plain list|* {{Rust|let boxed: Box<u8> {{=}} Box::new(0);}}
* {{Rust|let boxed: Option<Box<String>> {{=}} Some(Box::new("Hello World"));}}}}
|-
|{{Plainlist|
* {{Rust|*const T}}
* {{Rust|*mut T}}
}}
|{{Plainlist|
* Raw pointers (immutable and mutable)
* Possibly [[Null pointer|null]]; {{Rust|unsafe}} to [[dereference]]
}}
|{{Plainlist|
* {{Rust|let x_ptr: *const T {{=}} &x as *const T;}}
* {{Rust|let x_ptr: *mut T {{=}} &mut x as *mut T;}}
}}
|}
 
To prevent the use of [[null pointer]]s and their [[Null pointer#Null dereferencing|dereferencing]], the basic <code>&</code> and <code>&mut</code> references are guaranteed to not be null. Rust instead uses <code>Option</code> for this purpose: <code>Some(T)</code> indicates that a value is present, and <code>None</code> is analogous to the null pointer.{{sfn|Klabnik|Nichols|2019|pp=101–104}} <code>Option</code> implements a "null pointer optimization", avoiding any spatial overhead for types that cannot have a null value (references or the <code>NonZero</code> types, for example).<ref>{{Cite web |title=std::option |url=https://doc.rust-lang.org/std/option/index.html#representation |access-date=2023-11-12 |website=The Rust Standard Library documentation}}</ref> Though null pointers are idiomatically avoided, the null pointer constant in Rust is represented by <code>std::ptr::null()</code>.
 
Rust also supports raw pointer types <code>*const</code> and <code>*mut</code>, which may be null; however, it is impossible to dereference them unless the code is explicitly declared unsafe through the use of an <code>unsafe</code> block. Unlike dereferencing, the creation of raw pointers is allowed inside of safe Rust code.{{sfn|Klabnik|Nichols|2019|pp=418–427}}
 
== Type conversion ==
{{excerpt|Type conversion|Rust}}
 
[[File:Rust 101.webm|thumb|A presentation on Rust by Emily Dunham from [[Mozilla]]'s Rust team ([[linux.conf.au]] conference, Hobart, 2017)]]
 
== Polymorphism ==
=== Generics ===
Rust's more advanced features include the use of [[generic function]]s. A generic function is given [[Generic programming|generic]] [[Parameter (computer programming)|parameters]], which allow the same function to be applied to different variable types. This capability reduces [[duplicate code]]{{sfn|Klabnik|Nichols|2019|pp=171–172}} and is known as [[parametric polymorphism]].
 
The following program calculates the sum of two things, for which addition is implemented using a generic function:
 
<syntaxhighlight lang="rust">
use std::ops::Add;
 
// sum is a generic function with one type parameter, T
fn sum<T>(num1: T, num2: T) -> T
where
T: Add<Output = T>, // T must implement the Add trait where addition returns another T
{
num1 + num2 // num1 + num2 is syntactic sugar for num1.add(num2) provided by the Add trait
}
 
fn main() {
let result1: i32 = sum(10, 20);
println!("Sum is: {}", result1); // Sum is: 30
 
let result2: f32 = sum(10.23, 20.45);
println!("Sum is: {}", result2); // Sum is: 30.68
}
</syntaxhighlight>
 
At compile time, polymorphic functions like <code>sum</code> are [[Instance (computer science)|instantiated]] with the specific types the code requires; in this case, sum of integers and sum of floats.
 
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}}
 
=== Traits ===
[[File:UML class diagram Rust stdio.svg|thumb|Excerpt from {{Mono|std::io}}]]
Rust's type system supports a mechanism called traits, inspired by [[type class]]es in the [[Haskell]] language,<ref name="influences"/> to define shared behavior between different types. For example, the <code>Add</code> trait can be implemented for floats and integers, which can be added; and the <code>Display</code> or <code>Debug</code> traits can be implemented for any type that can be converted to a string. Traits can be used to provide a set of common behavior for different types without knowing the actual type. This facility is known as [[ad hoc polymorphism]].
 
Generic functions can constrain the generic type to implement a particular trait or traits; for example, an <code>add_one</code> function might require the type to implement <code>Add</code>. This means that a generic function can be type-checked as soon as it is defined. The implementation of generics is similar to the typical implementation of C++ templates: a separate copy of the code is generated for each instantiation. This is called [[monomorphization]] and contrasts with the [[type erasure]] scheme typically used in Java and Haskell. Type erasure is also available via the keyword <code>dyn</code> (short for dynamic).{{sfn|Klabnik|Nichols|2019|pp=181,182}} Because monomorphization duplicates the code for each type used, it can result in more optimized code for specific-use cases, but compile time and size of the output binary are also increased.{{sfn|Gjengset|2021|p=25}}
 
In addition to defining methods for a user-defined type, the <code>impl</code> keyword can be used to implement a trait for a type.{{sfn|Klabnik|Nichols|2019|pp=93}} Traits can provide additional derived methods when implemented.{{sfn|Klabnik|Nichols|2019|pp=182–184}} For example, the trait <code>Iterator</code> requires that the <code>next</code> method be defined for the type. Once the <code>next</code> method is defined, the trait can provide common functional helper methods over the iterator, such as <code>map</code> or <code>filter</code>.{{sfn|Klabnik|Nichols|2019|pp=281–283}}
 
=== Trait objects ===
Rust traits are implemented using [[static dispatch]], meaning that the type of all values is known at compile time; however, Rust also uses a feature known as ''trait objects'' to accomplish [[dynamic dispatch]], a type of polymorphism where the implementation of a polymorphic operation is chosen at [[Runtime (program lifecycle phase)|runtime]]. This allows for behavior similar to [[duck typing]], where all data types that implement a given trait can be treated as functionally equivalent.{{sfn|Klabnik|Nichols|2023|loc=[https://doc.rust-lang.org/book/ch18-02-trait-objects.html 18.2. Using Trait Objects That Allow for Values of Different Types]}} Trait objects are declared using the syntax <code>dyn Tr</code> where <code>Tr</code> is a trait. Trait objects are dynamically sized, therefore they must be put behind a pointer, such as <code>Box</code>.{{sfn|Klabnik|Nichols|2019|pp=441–442}} The following example creates a list of objects where each object can be printed out using the <code>Display</code> trait:
 
<syntaxhighlight lang="Rust">
use std::fmt::Display;
 
let v: Vec<Box<dyn Display>> = vec![
Box::new(3),
Box::new(5.0),
Box::new("hi"),
];
 
for x in v {
println!("{x}");
}
</syntaxhighlight>
 
If an element in the list does not implement the <code>Display</code> trait, it will cause a compile-time error.{{sfn|Klabnik|Nichols|2019|pp=379–380}}
 
== Memory safety ==
Rust is designed to be [[memory safe]]. It does not permit null pointers, [[dangling pointer]]s, or [[data race]]s.<ref name="cnet">{{cite web |url=http://reviews.cnet.com/8301-3514_7-57577639/samsung-joins-mozillas-quest-for-rust/ |title=Samsung joins Mozilla's quest for Rust |last=Rosenblatt |first=Seth |date=2013-04-03 |publisher=[[CNET]] |access-date=2013-04-05 |archive-date=2013-04-04 |archive-url=https://web.archive.org/web/20130404142333/http://reviews.cnet.com/8301-3514_7-57577639/samsung-joins-mozillas-quest-for-rust/ |url-status=live}}</ref><ref name="lwn">{{cite web |last=Brown |first=Neil |date=2013-04-17 |title=A taste of Rust |url=https://lwn.net/Articles/547145/ |url-status=live |archive-url=https://web.archive.org/web/20130426010754/http://lwn.net/Articles/547145/ |archive-date=2013-04-26 |access-date=2013-04-25 |website=[[LWN.net]]}}</ref><ref name="The Rustonomicon">{{Cite web|url=https://doc.rust-lang.org/nomicon/races.html|title=Races|website=The Rustonomicon|access-date=2017-07-03|archive-date=2017-07-10|archive-url=https://web.archive.org/web/20170710194643/https://doc.rust-lang.org/nomicon/races.html|url-status=live}}</ref><ref name="Sensors">{{cite journal |last1=Vandervelden |first1=Thibaut |last2=De Smet |first2=Ruben |last3=Deac |first3=Diana |last4=Steenhaut |first4=Kris |last5=Braeken |first5=An |title=Overview of Embedded Rust Operating Systems and Frameworks |journal= Sensors|doi=10.3390/s24175818 |date=7 September 2024 |volume=24 |issue=17 |page=5818 |doi-access=free |pmid=39275729 |pmc=11398098 |bibcode=2024Senso..24.5818V }}</ref> Data values can be initialized only through a fixed set of forms, all of which require their inputs to be already initialized.<ref name="lang-faq">{{cite web |title=The Rust Language FAQ |publisher=The Rust Programming Language |url=http://static.rust-lang.org/doc/master/complement-lang-faq.html |url-status=dead |archive-url=https://web.archive.org/web/20150420104147/http://static.rust-lang.org/doc/master/complement-lang-faq.html |archive-date=2015-04-20 |year=2015 |access-date=2017-04-24}}</ref>
 
Unsafe code can subvert some of these restrictions, using the <code>unsafe</code> keyword.{{sfn|Klabnik|Nichols|2019|pp=418–427}} Unsafe code may also be used for low-level functionality, such as [[Volatile (computer programming)|volatile memory access]], architecture-specific intrinsics, [[type punning]], and inline assembly.{{sfn|McNamara|2021|p=139, 376–379, 395}}
 
== Memory management ==
Rust does not use [[garbage collection (computer science)|garbage collection]]. Memory and other resources are instead managed through the "resource acquisition is initialization" convention,<ref>{{Cite web|title=RAII|url=https://doc.rust-lang.org/rust-by-example/scope/raii.html|access-date=2020-11-22|website=Rust by Example|archive-date=2019-04-21|archive-url=https://web.archive.org/web/20190421131142/https://doc.rust-lang.org/rust-by-example/scope/raii.html|url-status=live}}</ref> with optional [[reference counting]]. Rust provides deterministic management of resources, with very low [[Overhead (computing)|overhead]].<ref>{{Cite web|url=https://blog.rust-lang.org/2015/05/11/traits.html|title=Abstraction without overhead: traits in Rust|website=Rust Blog|access-date=October 19, 2021|archive-date=September 23, 2021|archive-url=https://web.archive.org/web/20210923101530/https://blog.rust-lang.org/2015/05/11/traits.html|url-status=live}}</ref> Values are [[Stack-based memory allocation|allocated on the stack]] by default, and all [[dynamic allocation]]s must be explicit.<ref>{{Cite web |title=Box, stack and heap |url=https://doc.rust-lang.org/stable/rust-by-example/std/box.html |access-date=2022-06-13 |website=Rust by Example |archive-date=2022-05-31 |archive-url=https://web.archive.org/web/20220531114141/https://doc.rust-lang.org/stable/rust-by-example/std/box.html |url-status=live }}</ref>
 
The built-in reference types using the <code>&</code> symbol do not involve run-time reference counting. The safety and validity of the underlying pointers is verified at compile time, preventing [[dangling pointers]] and other forms of [[undefined behavior]].{{sfn|Klabnik|Nichols|2019|pp=70–75}} Rust's type system separates shared, [[Immutable object|immutable]] references of the form <code>&T</code> from unique, mutable references of the form <code>&mut T</code>. A mutable reference can be coerced to an immutable reference, but not vice versa.{{sfn|Klabnik|Nichols|2019|p=323}}
<!--
 
== Closures ==
 
-->
 
== Macros ==
Macros allow generation and transformation of Rust code to reduce repetition. Macros come in two forms, with ''declarative macros'' defined through <code>macro_rules!</code>, and ''procedural macros'', which are defined in separate crates.{{sfn|Klabnik|Nichols|2023|pp=449–455}}{{sfn|Gjengset|2021|pp=101-102}}
 
=== Declarative macros ===
A declarative macro (also called a "macro by example") is a macro, defined using the <code>macro_rules!</code> keyword, that uses pattern matching to determine its expansion.<ref name="Rust Ref. – Macros By Example">{{cite web |title=Macros By Example |url=https://doc.rust-lang.org/reference/macros-by-example.html |website=The Rust Reference |access-date=21 April 2023 |archive-date=2023-04-21 |archive-url=https://web.archive.org/web/20230421052332/https://doc.rust-lang.org/reference/macros-by-example.html |url-status=live }}</ref>{{sfn|Klabnik|Nichols|2019|pp=446–448}} Below is an example that sums over all its arguments:
 
<syntaxhighlight lang="rust">
macro_rules! sum {
( $initial:expr $(, $expr:expr )* $(,)? ) => {
$initial $(+ $expr)*
}
}
 
fn main() {
let x: i32 = sum!(1, 2, 3);
println!("{x}"); // prints 6
}
</syntaxhighlight>
<!-- TODO explain -->
=== Procedural macros ===
Procedural macros are Rust functions that run and modify the compiler's input [[Token (parser)|token]] stream, before any other components are compiled. They are generally more flexible than declarative macros, but are more difficult to maintain due to their complexity.<ref name="rust-procedural-macros">{{cite web |url=https://doc.rust-lang.org/reference/procedural-macros.html |title=Procedural Macros |website=The Rust Programming Language Reference |access-date=23 Mar 2021 |archive-date=7 November 2020 |archive-url=https://web.archive.org/web/20201107233444/https://doc.rust-lang.org/reference/procedural-macros.html |url-status=live}}</ref>{{sfn|Klabnik|Nichols|2019|pp=449–455}}
 
Procedural macros come in three flavors:
* Function-like macros <code>custom!(...)</code>
* Derive macros <code>#[derive(CustomDerive)]</code>
* Attribute macros <code>#[custom_attribute]</code>
<!-- TODO example -->
 
== Interface with C and C++ ==
Rust has a [[foreign function interface]] (FFI) that can be used both to call code written in languages such as [[C (programming language)|C]] from Rust and to call Rust code from those languages. {{As of|2024}}, an external library called CXX exists for calling to or from C++.<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> Rust and C differ in how they lay out structs in memory, so Rust structs may be given a <code>#[repr(C)]</code> attribute, forcing the same layout as the equivalent C struct.<ref name="Type layout">{{cite web |title=Type layout |url=https://doc.rust-lang.org/reference/type-layout.html#the-c-representation |website=The Rust Reference |access-date=15 July 2022 |archive-date=2022-07-16 |archive-url=https://web.archive.org/web/20220716021840/https://doc.rust-lang.org/reference/type-layout.html#the-c-representation |url-status=live }}</ref>
 
== See also ==
* [[C syntax]]
* [[C++ syntax]]
* [[Java syntax]]
* [[C Sharp syntax|C# syntax]]
 
== Notes ==
{{Reflist|group=note}}
 
== References ==
<!-- Inline citations added to your article will automatically display here. See en.wikipedia.org/wiki/WP:REFB for instructions on how to add citations. -->
{{reflist|refs=
<ref name="influences">{{cite web |title=Influences |url=https://doc.rust-lang.org/reference/influences.html |website=The Rust Reference |access-date=December 31, 2023 |archive-date=November 26, 2023 |archive-url=https://web.archive.org/web/20231126231034/https://doc.rust-lang.org/reference/influences.html |url-status=live}}</ref>
}}
 
== Sources ==
{{refbegin}}
* {{Cite book |last=Gjengset |first=Jon |title=Rust for Rustaceans |date=2021 |publisher=No Starch Press |isbn=9781718501850 |edition=1st |oclc=1277511986 |language=en}}
* {{Cite book|last1=Klabnik|first1=Steve|url=https://books.google.com/books?id=0Vv6DwAAQBAJ|title=The Rust Programming Language (Covers Rust 2018)|last2=Nichols|first2=Carol|date=2019-08-12|publisher=No Starch Press|isbn=978-1-7185-0044-0|language=en}}
* {{Cite book |last1=Klabnik |first1=Steve |last2=Nichols |first2=Carol |title=The Rust programming language |date=2023 |publisher=No Starch Press |isbn=978-1-7185-0310-6 |edition=2nd |oclc=1363816350}}
* {{Cite book|last1=McNamara|first1=Tim|title=Rust in Action|oclc=1153044639|date=2021|publisher=Manning Publications|isbn=978-1-6172-9455-6|language=en}}
{{refend}}
 
[[Category:Rust (programming language)]]
[[Category:Programming language syntax]]