Lucas Vieira

  • Programming
  • Science
  • Concerts
    • Georgia Crandon
    • Jo-Jo & The Teeth
    • DRØWND
    • Meet Arthur
    • Harri Georgio
  • Sports
    • Football ⚽
      • Leicester St Andrews FC (2024/2025 Season)
  • Travel & Places
    • Brazil 🇧🇷
      • Curitiba
      • São Luís
      • São Paulo
    • Italy 🇮🇹
      • Rome
    • Poland 🇵🇱
      • Auschwitz
      • Krakow
    • Portugal 🇵🇹
      • Lisbon
      • Porto
    • Spain 🇪🇸
      • Málaga
    • UK 🇬🇧
      • England 🏴󠁧󠁢󠁥󠁮󠁧󠁿
        • Coventry
        • London
        • Leicester
        • Manchester
        • RAF Cosford
        • Watford
    • Vatican City 🇻🇦
  • Português 🇧🇷
  • About

  • Meet Arthur

    Visual Portfolio, Posts & Image Gallery for WordPress

    Meet Arthur. August 16th, 2023

    Meet Arthur at The Bedford, London. August 16th, 2023

    Meet Arthur at The Bedford, London. August 16th, 2023

    Meet Arthur at The Bedford, London. August 16th, 2023

    Meet Arthur. August 16th, 2023

    Meet Arthur. August 16th, 2023

    Meet Arthur. August 16th, 2023

    16/08/2023

  • Watford 🇬🇧

    Collection of photos taken in Watford, UK between April and July 2023

    Visual Portfolio, Posts & Image Gallery for WordPress

    Spring at Cassiobury Park

    Last days of Spring

    Cat

    Cassiobury Park

    Walk

    20/06/2023
    england, travel, uk, watford

  • Auschwitz 🇵🇱

    Some photos of a visit to the Memorial and Museum Auschwitz-Birkenau, Auschwitz, Poland 🇵🇱 in April 2023.

    Visual Portfolio, Posts & Image Gallery for WordPress

    Watch tower. Auschwitz II-Birkenau

    Barrack. Auschwitz II-Birkenau

    Freight car. Auschwitz II-Birkenau.

    Gate to Auschwitz I

    Sign. Auschwitz I.

    Gas chamber and crematorium entrance. Auschwitz I.

    28/04/2023
    Auschwitz, Birkenau, memorial, photography, poland

  • Krakow 🇵🇱

    Some photos of a work trip to Krakow, Poland 🇵🇱 in April 2023.

    Visual Portfolio, Posts & Image Gallery for WordPress

    Grunwald Bridge

    Mig-21MF at Polish Aviation Museum

    SAAB JAS-37 Viggen at Polish Aviation Museum

    27/04/2023
    krakow, poland

  • Learning together: Rust – A quick overview of Rust programming language

    Originally posted on Medium

    Once you’re familiarized with the Rust environment it’s time to get into action. Our goal today is to cover the basics of Rust syntax and some of its resources.

    Main function and Prelude

    Every executable Rust program should contain a main function. This function always acts as an entry point for our executables. From my last article, you already know how to compile your classical hello world program using the Rust compiler directly or using Cargo to build and run your program.

    Another detail that you should have noticed from the previous article is that Rust source files have the.rsextension.

    Rust also brings some types into the scope of every program. These types, traits, and functions were judged to be so commonly used that the Rust compiler implicitly imports these symbols for you. This is called the prelude. By allowing you to use this set of common types, Rust reduces the verbosity of their programs.

    Some basic formatting

    Rust brings some macros related to strings. Today we will explore some of them: println! and format!.

    The first one is the println!. This macro prints its output directly to UNIX standard output. In fact, we used this macro in the previous article to write our first program in Rust.

    Rust
    fn main() {
        println!("Hello, world!");
    }

    This will print a text on your console. We can also pass some arguments to println! macro and use placeholders to format output.

    Rust
    fn main() {
        // Printing a number using the generic placeholder
        println!("{}", 65);
    
        // Arguments passed to println! macro are positional arguments
        println!("Brazil {} - {} Germany", 1, 7);
    
        // Arguments also are indexed. For example, to invert the score of that semi-final.
        println!("Brazil {1} - {0} Germany", 1, 7);
    
        // We can also use named arguments
        println!(
            "Hello! my name is {name} and I'm from {country}",
            name = "Lucas",
            country = "Brazil"
        );
    
        // You can use special placeholders to show an specific representation of your data
        println!("Hexadecimal: {:x} | Octal: {:o} | Binary: {:b}", 16, 16, 16);
        
        // Rust also checks if you're passing the correct number of arguments
        // println!("Lets produce an error: {} {}", "passing just one argument"); // 2 positional arguments, but just 1 provided
    
        // Structs are not printable by default
        #[allow(dead_code)]
        struct MyStruct(i64);
    
        println!("My struct: {}", MyStruct(10)); // Error
    }

    The format! macro works in a similar way. But instead of printing on the console, it will return a formatted string for you.

    Rust
    fn main() {
        // format! macro
        let output = format!(
            "Hello! my name is {name} and I'm from {country}",
            name = "Lucas",
            country = "Brazil"
        );
    
        println!("{}", output);
    }

    Primitive types

    Rust brings a good set of primitives. On one hand, we have the following scalar types:

    Numeric types

    Rust supports signed integers, represented by the following types: i8, i16, i32, i64, i128 and isize.Unsigned integers are the following: u8, u16, u32, u64, u128 and usize. For floating-point numbers, Rust provides two types: f32and f64.

    Char

    The type charrepresents Unicode scalar values like ‘a’ or ‘💖’ and has 4 bytes. In C, for example, a char value uses 8 bits in most cases.

    Bool

    bool either trueor false.

    Rust
    // Rust types
    fn main() {
        // Bool
        let logic: bool = true;
    
        // Numerics
        let number: i32 = 10;
        let snd_number: f64 = 10.75;
        let another_number = 10u16; // You can use suffix annotation to define the type a numeric
    
        // arrays
        let inferred_arr = [1, 4, 5, 56.3];
        let type_annoted_arr: [i32; 3] = [1, 4, 5];
    
        // Tuples
        let inferred_tuple = (1, "H");
        let type_annoted_tuple: (u8, char, f64) = (1, "H", 34.598);
    }

    Arrays and Tuples

    Rust also has arrays and tuples as compound types. These types can be used when you need to group a set of values in the same structure. Let’s take a look at tuples.

    A tuple can receive a group of values from different types. Tuples in Rust cannot grow or shrink after its declaration. To access directly an element in a tuple using a period (.) with the index of the element you want.

    Rust
    // Tuples
    fn main() {
        
        // Accessing tuple values
        let my_tuple: (i32, f64, u8) = (65, 7.65, 1);
        let age = x.0;
        let money = x.1;
        let one = x.2;
        
        // You can also use pattern matching to destructure a tuple value
        let (x, y, z) = my_tuple;
        println!("The value of y is: {}", y);
    }

    Arrays in Rust are a little bit different from most languages. First, they have fixed lengths as in C and C++ (Not to be confused with vectors).

    Rust
    // Array
    fn main() {
        // Declaring an array
        let a = [1, 2, 3, 4, 5];
        let b: [i64, 3] = [2, 4, 8]; // type annoted
      
        // Access elements by indexes
        let first_elem = arr[0];
        let snd_elem = arr[1];
      
        // Invalid index
        let idx = 10;
        let element = a[idx]; // Will produce a runtime error
        println!("The value of element is: {}", element);
    }

    If you, for some reason, try to access a non-existent index on an array, Rust will terminate the program execution. Yep. Rust always checks if the index is greater than or equal to the array length. This is a glimpse of Rust’s safety working. In some languages, this is still a problem and you should pay attention while writing your program to keep everything ok.

    Rust also supports custom types like structs and enums which we’ll explore later.

    A curious observation about types is that an empty tuple is considered a scalar type, once it represents a simple zero-sized type, with only one value possible: ().

    Variables

    Variables in Rust are declared with letkeyword and all of them are, by default, immutable. You can’t reassign a variable after its creation. Variables in Rust can be type annotated. This means that you explicitly declare the type of variable. However, the compiler is smart enough to infer the type of a variable from context.

    Rust
    // Rust variables
    fn main() {
        
        let bool_var = true;
        let age: i32 = 49; // type annotation
    
        // Boolean variables can receive their value from an expression
        let condition: bool = 10 > 5; 
        
        bool_var = false; // Error. You can't reassign to immutable variable
    
        println!("Value: {}", bool_var);
    }

    But, of course, you can use mutable variables by adding the keyword mut on the declaration.

    Rust
    // Rust variables
    fn main() {
        
        let mut year = 2020;
    
        println!("year: {}", year);
        
        year += 1;
    
        println!("year: {}", year);
    }

    Scope

    Variables always live in a block. In Rust, a block is a collection of statements enclosed by braces.

    Rust
    // Rust variables
    fn main() {
        
        let mut year = 2020;
    
        {
            // A block defines a variable scope in Rust
            // Variable shadowing is possible too.
            let year = 2018; 
            println!("From block scope: {}", year);
        }
    
    
        println!("From outer scope: {}", year);
    }

    In Rust, you can declare a variable in a certain scope with the same name as a variable from an outer scope. This is called shadowing or masking. The outer variable is shadowed by the inner variable.

    Rust
    // Shadowing
    fn main() {
        let outer = 100;
    
        {
            let outer = 123;
            println!("Inner outer: {}", outer)
        }
    
        println!("Global outer: {}", outer)
    }

    When you use a mutable variable in a nested scope, their changes on the inner scope reflect on the outer scope.

    Rust
    fn main() {
        // Mutable variable
        let mut age = 17i32; 
    
        {
            age = age + 1;
            println!("Inner scope: {}", age); // 18
        }
        
        println!("Outer scope: {}", age); // 18
    }

    But when two variables are bound to the same name in different scopes with an immutable declaration, the variable data freezes until the immutable binding ends its scope.

    Rust
    fn main() {
        // Mutable variable
        let mut age = 17i32; 
    
        {
            // Shadowing by immutable `age`
            let age = age;
    
            // 'age' is frozen in this scope
            age = age + 1; // Error 
            
            println!("Inner scope: {}", age);
        }
        
        age = age + 5;
        println!("Outer scope: {}", age);
    }

    Casting

    Implicit type conversions between primitive types have no space in Rust. You can perform type conversion using theas keyword. There are a few examples:

    Rust
    fn main() {
        // 64-bit float
        let fnumber = 389.54647871;
    
        // Error here. Coercion is not allowed in Rust
        let intnumber: u32 = fnumber; // comment to compile
    
        // Only explicit conversions are allowed
        let intnumber = fnumber as u8;
        let chartype = intnumber as char;
    
        // Some conversions cannot be made.
        // A float variable can't be converted to a char.
        let chartype = fnumber as char; // comment to compile
    
        println!("float -> integer -> char: {} -> {} -> {}", fnumber, intnumber, chartype);
    }

    Summarizing: Integer types can be cast to float types. Float types can only be cast to integer types. Boolean values can be cast to integers type (where true will equal value one and false will equal 0). char can be cast to integer types, but only one integer type can be cast to char: u8;

    The type coercions in Rust have other nuances that deserve an article of their own. But for now, this is enough for us to keep moving;

    Rust
    fn main() {
        let floatvalue = 45.4545_f32;
        let charvalue = floatvalue as char; // Cannot be type casted
        
        // println!("float -> char: {}", charvalue);
    
        let intvalue = floatvalue as u8;
        let charvalue = intvalue as char; // Cannot be type casted
    
        println!("float -> char: {}", charvalue);
    
        // Boolean casts
        let t = true;
        let f = false;
    
        println!("bool -> int: {} {}", t as u8, f as u16);
    
        // Char to integer casts
        println!("char -> int: {}", charvalue as i64);
    }

    Functions

    Functions in Rust are defined with the fnkeyword. As you may know, they can have arguments. Functions in Rust are named using snake case. If a function doesn’t follow this convention, the compiler will show you a warning about naming conventions.

    Rust
    // Functions
    fn hello_world()
    {
        println!("Hello world");
    }
    
    fn main() {
        hello_world();
    }

    Let’s take a closer look at the anatomy of a function in Rust:

    Rust
    // Functions
    fn fibonacci(x: i64) -> i64 {
        if x < 2 {
            return x;
        }
    
        fibonacci(x - 1) + fibonacci(x - 2)
    }
    
    fn main() {
        println!("Fibonacci for {}: {}", 8, fibonacci(3));
    }

    You’re probably already familiar with the Fibonacci sequence. Our function above defines a recursive algorithm to calculate the n-th number in the sequence.

    We defined a function with the fn keyword and this function takes an argument called x type i64. Parameters are separated by a comma and their types are required. We define the return type declaring it after an arrow (->). These are the basics of functions in Rust.

    Rust
    // Functions
    // Multiple parameters
    fn add(x: i64, y: i64) -> i64 {
        x + y
    }
    
    fn main() {
        println!("Result: {}", add(45, 56));
    }

    Next steps

    Today we covered the basics of Rust’s syntax, types, and functions. From now on, we’ll see more action with Rust implementing some data structures and exploring more on arrays and vectors.

    You’re free to add comments, ask questions, or make suggestions here. I hope this explanation helped with your understanding of Rust.

    See ya!

    03/10/2020

  • Learning together: Rust – Setting up Rust environment

    Originally posted on Medium

    Some months ago I challenged myself to learn a language of my interest: Rust. In this and the following articles, I’ll be sharing my experience with the language, its philosophy, its ecosystem, and how to build something useful out of Rust.

    Rust

    Rust is a modern language born with a focus on performance and safety. Rust is memory-safe, and thread-safe by default, with a rich and powerful type system, generics, metaprogramming, and good functional programming support. It’s also very fast and memory-efficient. Rust is commonly used to build distributed systems, embedded systems, network applications, and WebAssembly applications.

    Rust is also being used in big projects like Deno and Tor.

    My background

    Mostly focused on web applications. I’ve been a backend developer for the last four years working mainly with PHP and, for a brief moment, with Ruby on Rails too.

    I’ve also had some academic experience with Python and C/C++, the latter being where I’ve acquired a taste for compiled languages.

    First Steps: Meet rustup, rustc, and Cargo

    Since programmers will look into official documentation of the language, so did I.

    Rust official website

    Of course, for most Linux distros versions, you can install Rust directly from official repositories, but if for some reason you need to keep several versions of Rust in your environment or even test the most recent features of the nightly build, you should use rustup.

    Rustup

    Rustup is a toolchain installer for Rust. With rustup, you can install and manage several versions of Rust. This tool is very easy to install and use.

    Bash
    curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

    If you proceed with the default installation, the rustup will install — in addition to itself — the latest stable version of Rust and Cargo. Once installed, you can see a list of installed toolchains:

    rustup toolchain list
    Listing installed toolchains

    To install a specific version of Rust, you’ll use the install command passing as argument the version that you want:

    rustup install 1.43.0  
    Installing a specific version of Rust

    Cargo

    Cargo is a dependency manager for Rust. With Cargo, you can also create packages for the community and make them available on crates.io. Cargo also will be used to start projects and fetch and build our project dependencies.

    Cargo commands

    Rustc

    Rustc is the Rust compiler. In most cases, we’ll build our packages, libraries, or applications by calling Cargo. But we can also call the compiler directly.

    For example, you can create a file called main.rs on some directory and compile it with rustic.

    Rust
    fn main() {
        println!("Hello, world!");
    }

    To compile:

    Bash
    rustc main.rs

    This will create an executable binary called main in the current directory. To run this program, just execute it.

    Bash
    ./main

    If everything is ok with your environment, you’ll receive a nice “Hello, world!” from your first program with Rust.

    Next steps

    We will explore much more of Rust in the following articles. The articles will intend especially to show the main features of Rust and its tools, for those already familiar with programming in general.

    For those who want to see more about Rust and the tools presented here, you can always check the book The Rust Programming Language, available on the official website.

    20/09/2020

Previous Page
  • GitHub
  • LinkedIn

Designed with WordPress