Rust (programming language)

From Bauman National Library
This page was last modified on 8 June 2016, at 14:46.
Rust
144px
Paradigm Multi-paradigm: compiled, concurrent, functional, imperative, structured
Designed by Originally Graydon Hoare, then Rust Project Developers
Developer Rust Project Developers
Stable release 1.8[1] / Template:Release date and age
Typing discipline static, strong, inferred, nominal, linear
Implementation language Rust
OS Linux, OS X, Windows, FreeBSD, Android, iOS (partial)[2]
License Apache License 2.0 or MIT License[3]
Website www.rust-lang.org
Influenced by
Ada,[4]Template:Better source Alef,[5] C#,[5] C++,[5] Cyclone,[5][6] Erlang,[5] Haskell,[5] Hermes,[5] Limbo,[5] Newsqueak,[5] NIL,[5] OCaml,[5] Ruby,[5] Scheme,[5] Standard ML,[5] Swift[5][7]
Influenced
C# 7,[8] Elm,[9] Idris,[10] Swift[11]

Rust is a general-purpose, multi-paradigm, compiled programming language developed by Mozilla Research. It is designed to be a "safe, concurrent, practical language", supporting pure-functional, concurrent-actor, imperative-procedural, and object-oriented styles.

The language grew out of a personal project by Mozilla employee Graydon Hoare. Mozilla began sponsoring the project in 2009 and announced it in 2010. The first numbered pre-alpha release of the Rust compiler occurred in January 2012. Rust 1.0, the first stable release, was released on May 15, 2015. Although its development is sponsored by Mozilla, it is an open community project. The language takes its name from the rust family of fungi.

Design

The goal of Rust is to be a good language for creating highly concurrent and highly safe systems. This has led to a feature set with an emphasis on safety, control of memory layout, and concurrency. Performance of safe code is expected to be slower than C++. However, performance is comparable to C++ code that manually takes precautions.

The system is designed to be memory safe, and it does not permit null pointers. A system of pointer lifetimes and freezing allows the compiler to prevent many types of errors that are possible to write in C++, even when using its smart pointers.

The type system supports a mechanism similar to type classes, called 'traits', inspired directly by the Haskell language. This is a facility for ad-hoc polymorphism, achieved by adding constraints to type variable declarations. Other features from Haskell, such as higher-kinded polymorphism, are not yet supported.

Syntax

The syntax of Rust is similar to C and C++, with blocks of code delimited by curly brackets, and control flow keywords such as if,else, while, and for. Not all C or C++ keywords are present, however, while others (such as the match keyword for multi-directional branching, similar to switch in other languages) will be less familiar to programmers coming from these languages. Despite the syntactic resemblance, Rust is semantically very different from C and C++.

Set operators in Rust: arithmetic (* - multiplication / - division,% - modulo + - addition - subtraction and unary prefix operator - to change the sign) bit (>>, <<, &, | u), comparison operators ( == ,! =, <,>, <=,> =), logic (and, or and or && or ||). To cast in Rust used a binary operator as.

Variable Bindings

Virtually every non-'Hello World’ Rust program uses variable bindings. They look like this:

fn main() {
    let x = 5;
}

In many languages, this is called a variable, but Rust’s variable bindings have a few tricks up their sleeves. For example the left-hand side of a let expression is a ‘pattern’, not just a variable name. This means we can do things like:

let (x, y) = (1, 2);

Rust is a statically typed language, which means that we specify our types up front, and they’re checked at compile time. We can add the type if we want to, though. Types come after a colon (:):

let x: i32 = 5;

If you want a binding to be mutable, you can use mut:

let mut x = 5; // mut x: i32
x = 10;

Rust variable bindings have one more aspect that differs from other languages: bindings are required to be initialized with a value before you're allowed to use them. Rust warns us that we never use the variable binding, but since we never use it, no harm, no foul. Rust will not let us use a value that has not been initialized.

Functions

Every Rust program has at least one function, the main function:

fn main() {
}

This is the simplest possible function declaration. fn says ‘this is a function’, followed by the name, some parentheses because this function takes no arguments, and then some curly braces to indicate the body.

Here’s a function that adds one to an integer:

fn add_one(x: i32) -> i32 {
    x + 1
}

Rust functions return exactly one value, and you declare the type after an ‘arrow’, which is a dash (-) followed by a greater-than sign (>). The last line of a function determines what it returns. You’ll note the lack of a semicolon here.

Rust does have a keyword for early return, return:

fn foo(x: i32) -> i32 {
    return x;

    // we never run this code!
    x + 1
}

Primitive Types

The Rust language has a number of types that are considered ‘primitive’. This means that they’re built-in to the language. Rust is structured in such a way that the standard library also provides a number of useful types built on top of these ones, as well, but these are the most primitive.

Booleans

Rust has a built in boolean type, named bool. It has two values, true and false:

let x = true;
let y: bool = false;

Char

The char type represents a single Unicode scalar value. You can create chars with a single tick: (')

let x = 'x';
let two_hearts = '💕';

Unlike some other languages, this means that Rust’s char is not a single byte, but four.

Numeric types

Rust has a variety of numeric types in a few categories: signed and unsigned, fixed and variable, floating-point and integer.

These types consist of two parts: the category, and the size. For example, u16 is an unsigned type with sixteen bits of size. More bits lets you have bigger numbers.

If a number literal has nothing to cause its type to be inferred, it defaults:

let x = 42; // x has type i32
let y = 1.0; // y has type f64

Here’s a list of the different numeric types:

  • i8
  • i16
  • i32
  • i64
  • u8
  • u16
  • u32
  • u64
  • isize
  • usize
  • f32
  • f64

Arrays

Like many programming languages, Rust has list types to represent a sequence of things. The most basic is the array, a fixed-size list of elements of the same type. By default, arrays are immutable.

let a = [1, 2, 3]; // a: [i32; 3]
let mut m = [1, 2, 3]; // m: [i32; 3]

Arrays have type [T; N]. The N is a compile-time constant, for the length of the array. You can get the number of elements in an array a with a.len():

let a = [1, 2, 3];
println!("a has {} elements", a.len());

You can access a particular element of an array with subscript notation:

let names = ["Graydon", "Brian", "Niko"]; // names: [&amp;str; 3]
println!("The second name is: {}", names[1]);

Subscripts start at zero, like in most programming languages, so the first name is names[0] and the second name is names[1].Slices

A ‘slice’ is a reference to (or “view” into) another data structure. They are useful for allowing safe, efficient access to a portion of an array without copying. For example, you might want to reference just one line of a file read into memory. By nature, a slice is not created directly, but from an existing variable. Slices have a length, can be mutable or not, and in many ways behave like arrays:

let a = [0, 1, 2, 3, 4];
let middle = &amp;a[1..4]; // A slice of a: just the elements 1, 2, and 3
let complete = &amp;a[..]; // A slice containing all of the elements in a

Slices have type &[T].

Str

Rust’s str type is the most primitive string type. As an unsized type, it’s not very useful by itself, but becomes useful when placed behind a reference, like &str.

Tuples

A tuple is an ordered list of fixed size. Like this:

let x = (1, "hello");

The parentheses and commas form this two-length tuple. Here’s the same code, but with the type annotated:

let x: (i32, &amp;str) = (1, "hello");

As you can see, the type of a tuple looks just like the tuple, but with each position having a type name rather than the value. Careful readers will also note that tuples are heterogeneous: we have an i32 and a&str in this tuple. In systems programming languages, strings are a bit more complex than in other languages.

Memory management

In Rust implemented "smart" memory model that supports efficient data structures and safe patterns of parallel execution, as well as completely prohibiting invalid memory access, which is usually a source of critical errors segmentation in other programming languages. Lack null-pointers, control over the use of uninitialized variables and deinitialized; the impossibility of sharing the tasks shared by several states; static analysis lifetime pointers.

In Rust, there are several types of pointers are subject to different rules:

Immutable (& T) and mutable (&mut T) links

This is a pointer to the memory that belongs to some other value. Immutable admit the existence of one or more links to read. Variable admit the existence of a link to read and write. Universal signs, having the opportunity to indicate any type of object: a stack placed in the local exchange or the heap. Mainly used to write generic code that works with data in functions, when the type of the object is not important. Creating links in Rust called borrowing, that is, an object reference borrows from the owner.

Box (Box<T>)

Points to the data placed in a pile; in a single-time access to an object can only address one pointer.

Managed pointers with counter links (Rc <T>) and atomic links with counter (Arc <T>)

Points to the data placed in a pile; Managed several of pointers can address the same subject. Arc allows thread-write access to the divided object.

Raw pointers immutable (* const T) and mutable (* mut T)

Pointers without security guarantees. It is not recommended to use them. Bindings are immutable by default, and to declare a variable variable, you need keyword mut.

Examples:

let x = 80;    // binding of the owner x with the value 80
let mut y = 50;    // immutablebinding
let z = &amp;x;    // immutable reference to an immutable binding
let w = &amp;mut y;    // immutable reference to the mutable binding

*w = 90    // y = 90
*z = 30    // error: attempt to change through a link to an immutable binding

let n = Box::new(42);    // box
let m = Rc::new(55);    // counter links
let data = Arc::new("test_string")    // atomic links with counter

Object system

In Rust object system based on facial features (traits) and data structures. Description determine the types and the corresponding methods and implementation. Description may include the implementation of methods, the default. Implementation designated keyword impl.

Rust supports generalized types. In addition to the functions in the generalized Rust can be complex data types, structures, and enumerations. Rust compiler compiles generalized function very effectively using them monomorphism (generating a separate copy of each generalized function directly at each call it). Thus, the copy can be adapted for specific types of the arguments, and hence optimized for these types. In this respect, the generalized function Rust comparable in performance with patterns (templates) language C ++.

Parallel computing

In earlier versions of the language supported by lightweight threads, but then they were rejected in favor of the native operating system threads. This recommended method of data exchange between threads is to send messages and do not use shared memory. To achieve high performance is not possible to send data by copying and using its own indicators (Box <T>). They ensure only one owner.

Compare with other languages

  • Principles of memory Rust significantly different both from the languages with full access to memory, and from the languages with full control over the memory by the garbage collector. Rust memory model is built in such a way that, on the one hand, provides developers with the ability to control where to place the data, introducing the separation of the types of indexes and providing control over their use at compile time. C on the other hand, reference counting mechanism.
  • Rust tries to issue compilation errors in those cases in which the use of other languages leads to run-time errors or program crashes.
  • Rust allows you to declare functions and code blocks as "unsafe". In the field of such unsafe code does not apply most of the restrictions that are just doing Rust safe language.

References

  1. Rust documentation
  2. The Rust Programming Language
    1. "Announcing Rust 1.8". blog.rust-lang.org. Retrieved 15 April 2016. 
    2. "Doc building for ios". GitHub. Retrieved 4 January 2015. 
    3. "COPYRIGHT". Rust compiler source repository. Retrieved 2015-11-09. 
    4. "Ada pragmas". 2012-02-15. Retrieved 2016-02-18. 
    5. 5.00 5.01 5.02 5.03 5.04 5.05 5.06 5.07 5.08 5.09 5.10 5.11 5.12 5.13 5.14 "The Rust Reference: Appendix: Influences". Retrieved March 25, 2015. Rust is not a particularly original language, with design elements coming from a wide range of sources. Some of these are listed below (including elements that have since been removed): SML, OCaml [...] C++ [...] ML Kit, Cyclone [...] Haskell [...] Newsqueak, Alef, Limbo [...] Erlang [...] Swift [...] Scheme [...] C# [...] Ruby [...] NIL, Hermes 
    6. "Note Research: Type System". 2015-02-01. Retrieved 2015-03-25. Papers that have had more or less influence on Rust, or which one might want to consult for inspiration or to understand Rust's background. [...] Region based memory management in Cyclone [...] Safe memory management in Cyclone 
    7. "RFC for `if let` expression". Retrieved December 4, 2014. The `if let` construct is based on the precedent set by Swift, which introduced its own `if let` statement. 
    8. "Discussion - Patterns and Records". 2015-03-25. Retrieved 2015-03-25. Sources of Inspiration: [...] Rust 
    9. "Command Optimizations?". 2014-06-26. Retrieved 2014-12-10. I just added the outline of a Result library that lets you use richer error messages. It's like Either except the names are more helpful. The names are inspired by Rust's Result library. 
    10. "Uniqueness Types". 2014-08-22. Archived from the original on December 25, 2014. Retrieved 2014-10-27. They are inspired by linear types, Uniqueness Types in the Clean programming language, and ownership types and borrowed pointers in the Rust programming language. 
    11. Lattner, Chris (2014-06-03). "Chris Lattner's Homepage". Chris Lattner. Retrieved 2014-06-03. The Swift language is the product of tireless effort from a team of language experts, documentation gurus, compiler optimization ninjas, and an incredibly important internal dogfooding group who provided feedback to help refine and battle-test ideas. Of course, it also greatly benefited from the experiences hard-won by many other languages in the field, drawing ideas from Objective-C, Rust, Haskell, Ruby, Python, C#, CLU, and far too many others to list.