Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Rust Programming By Example

You're reading from   Rust Programming By Example Enter the world of Rust by building engaging, concurrent, reactive, and robust applications

Arrow left icon
Product type Paperback
Published in Jan 2018
Publisher Packt
ISBN-13 9781788390637
Length 454 pages
Edition 1st Edition
Languages
Tools
Arrow right icon
Authors (2):
Arrow left icon
Antoni Boucher Antoni Boucher
Author Profile Icon Antoni Boucher
Antoni Boucher
Guillaume Gomez Guillaume Gomez
Author Profile Icon Guillaume Gomez
Guillaume Gomez
Arrow right icon
View More author details
Toc

Table of Contents (13) Chapters Close

Preface 1. Basics of Rust 2. Starting with SDL FREE CHAPTER 3. Events and Basic Game Mechanisms 4. Adding All Game Mechanisms 5. Creating a Music Player 6. Implementing the Engine of the Music Player 7. Music Player in a More Rusty Way with Relm 8. Understanding FTP 9. Implementing an Asynchronous FTP Server 10. Implementing Asynchronous File Transfer 11. Rust Best Practices 12. Other Books You May Enjoy

Methods

We can add methods on custom types. Let's write a method to compute the distance of a point to the origin:

impl Point {
    fn dist_from_origin(&self) -> f64 {
        let sum_of_squares = self.x.pow(2) + self.y.pow(2);
        (sum_of_squares as f64).sqrt()
    }
}

There are a lot of new syntaxes here (impl Point, as, and .method()), so let's explain all of them. First of all, methods of a type are declared within the impl Type {} construct. This method takes a special parameter: &self. This parameter is the instance the method is called on, like this in other programming languages. The & operator before self means that the instance is passed by immutable reference. As we can see, it is possible to call methods on basic types in Rust—self.x.pow(2) computes the power of two of the x field. We can find this method, and many others, in the documentation, at https://doc.rust-lang.org/stable/std/primitive.i32.html#method.pow . In the last expression of the method, we cast the sum_of_squares integer to f64 before computing its square root, because the sqrt() method is defined only on floating points.

Let's create a method that will update the fields of the structure:

impl Point {
    fn translate(&mut self, dx: i32, dy: i32) {
        self.x += dx;
        self.y += dy;
    }
}

The difference with the previous method is that self is now a mutable reference, &mut.

Constructors

Rust does not provide constructors, but a common idiom is to create a new() static method, also called an associated function:

impl Point {
    fn new(x: i32, y: i32) -> Self {
        Self { x: x, y: y }
    }
}

The difference with a normal method is that it does not take &self (or one of its variations) as a parameter.

Self is the type of the self value; we could have used Point instead of Self.

When the field name is the same as the value assigned, it is possible to omit the value, as a shorthand:

fn new(x: i32, y: i32) -> Self {
    Self { x, y }
}

When we create an instance of Point with the call to its constructor (let point = Point::new();), this will allocate the value on the stack.

We can provide multiple constructors:

impl Point {
    fn origin() -> Self {
        Point { x: 0, y: 0 }
    }
}
lock icon The rest of the chapter is locked
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime