Thursday, May 20, 2021

Encapsulation in Rust

Encapsulation is wrapping of data and information together in a single unit called Class. But since there is no Class implementation in Rust, so how can we achieve encapsulation in Rust.

In Rust, we can implement by using structs. Struct have an extra level of visibility with their fields. The visibility defaults to private, and can be overridden with the pub modifier. This visibility only matters when a struct is accessed from outside the module where it is defined, and has the goal of hiding information (encapsulation).



mod module {
    // A public struct with a public field of generic type `T`
    pub struct OpenDoor<T> {
        pub status: T,
    }

    // A public struct with a private field of generic type `T`
    #[allow(dead_code)]
    pub struct ClosedDoor<T> {
        status: T,
    }

    impl<T> ClosedDoor<T> {
        // A public constructor method
        pub fn new(status: T) -> ClosedDoor<T> {
            ClosedDoor { status: status }
        }
    }
}

fn main() {
    // Public structs with public fields can be constructed as usual
    let open_box = module::OpenDoor {
        status: "public information -- Door is opened",
    };

    // and their fields can be normally accessed.
    println!("The open door status : {}", open_box.status);

    // Public structs with private fields cannot be constructed using field names.
    // Error! `ClosedDoor` has private fields
    // let closed_door = module::ClosedDoor { door: "classified information --      // Door is closed" };
    // TODO ^ Try uncommenting this line

    // However, structs with private fields can be created using
    // public constructors
    let _closed_door = module::ClosedDoor::new("classified information -- Door is closed");

    // and the private fields of a public struct cannot be accessed.
    // Error! The `status` field is private
    // println!("The closed door contains: {}", _closed_door.status);
    // TODO ^ Try uncommenting this line
}


you may run by compiling with cargo build and cargo run. Result shown as below 




Thank you




Wednesday, May 19, 2021

Implementing Traits in Rust


What are traits in Rust 

A trait is a collection or group of methods defined for an unknown type: Self. They can access other methods declared in the same trait. Trait similar to abstract classes in C++. 


 Implementing a trait

A trait is implemented similarly to an inherent implementation except that a trait name and the for keyword follow the impl keyword before the type name. Let’s implement an built-in trait called ToString on a Person struct:



struct Person {
    name: String,
    age: u32,
    address: String,
}

// Implementing an in-built trait ToString on the Person struct
impl ToString for Person {
    fn to_string(&self) -> String {
        return format!(
            "{} is  {} years old and live in {}.",
            self.name, self.age, self.address
        );
    }
}

fn main() {
    let person = Person {
        name: "Addies".to_string(),
        age: 17,
        address: "Jakarta".to_string(),
    };
    println!("{}", person.to_string());
}


you may run by compiling with cargo build and cargo run. Result shown as below      






Monday, May 17, 2021

Defining and Creating a New Instance in Rust

Let say we want to allow the user to create a new draft of post with Post::new , then we want to allow the user to add some text into content by using method set_content and get the text from the get method by using get_content

We need a public Post struct that holds some content of string, so let's start with the definition of the struct and associated public new method to create an instance of Post.

In the Post::new method, we set the content field to a new using String::new. We will define a public method named set_content and pass it a &str that's then added to the text content and we will implement a public method named get_content and will return &str so that the user will able to get the content.



pub struct Post {
    content: String,
}

impl Post {
    pub fn new() -> Post {
        Post {
            content: String::new(),
        }
    }

    pub fn get_content(&self) -> &str {
        &self.content
    }

    pub fn set_content(&mut self, text: &str) {
        self.content.push_str(text);
    }
}

fn main() {
    let mut post = Post::new();

    post.set_content("Implementing an Object-Oriented Design Pattern");
    println!("{}", post.get_content());
}


From terminal run  cargo build  to compile and cargo run to see the result. Finally, you will see text content Implementing an Object-Oriented Design Pattern.



Thank you







Thursday, May 6, 2021

Inheritance in Rust

Inheritance is a mechanism whereby an object can inherit from another object’s definition, thus gaining the parent object’s data and behavior without you having to define them again. 

In Rust, there is no concept of "inheriting" the properties of a struct. Instead, when you are designing the relationship between objects do it in a way that one's functionality is defined by an interface (a trait in Rust).


Traits Inheritance example


trait Cat {
    fn get_sound(&self) -> String;
}

// CatPersia inherits from Cat trait
trait CatPersia : Cat { 
  fn number_of_feet(&self) -> i32;
}

// CatSphynx inherits from CatPersia and Cat traits
trait CatSphynx : CatPersia + Cat { 
  fn number_of_tail(&self) -> i32;
}




Let's see another example code below


trait A {
    fn shown_a(&self);
}

//B inherits from A trait
trait B: A {        
    fn shown_b(&self);
}

//C inherits from A and B traits
trait C: A + B {    
    fn shown_c(&self);
}

struct D {}

impl A for D {
    fn shown_a(&self) {
        println!("Implement A");
    }
}

impl B for D {
    fn shown_b(&self) {
        println!("Implement B");
    }
}

impl C for D {
    fn shown_c(&self) {
        println!("Implement C");
    }
}

fn main() {
    let d = D {};
    d.shown_a();
    d.shown_b();
    d.shown_c();
}



Result shown as below:



Thank you




Wednesday, May 5, 2021

Polymorphism in Rust

Polymorphism is the ability of an object to take on many forms, the same function has a different implementation. Polymorphism is achieved by operator overloading (compile-time) and method overriding (run-time)Rust takes a different approach to achieve polymorphism by using trait.




pub trait Shape {
    fn area(&self) -> f32;
}

pub struct Rectangle {
    pub length: f32,
    pub width: f32,
}

impl Shape for Rectangle {
    fn area(&self) -> f32 {
        self.length * self.width
    }
}

pub struct Square {
    side: f32,
}

impl Shape for Square {
    fn area(&self) -> f32 {
        self.side * self.side
    }
}

fn main() {
    let rectangle = Rectangle {
        length: 20.50,
        width: 10.50,
    };
    println!("Area of Rectangle = {}", rectangle.area());
    let square = Square { side: 8.50 };
    println!("Area of Square = {}", square.area());
}



Result shown as below



Thank you



Monday, May 3, 2021

How to Debug Rust in Visual Studio Code (Guide)

 

 

 


 

Assume that you have installed Rust in your computer. If you need guidance on how to install and configure Rust, you can find it here and of course Visual Studio Code installed as well.

Configuring Visual Studio Code for Rust development isn't difficult. Hopefully this guidance is useful to help you in Rust development. Let's start.


 Install Visual Studio Code Extension

1. You need to install extension according to you platform
             - C/C++  (for Windows)
             - CodeLLDB (for MacOS/Linux)

   since I used Ubuntu Linux then I installed CodeLLDB as shown as below

                      


2. Install Rust (rls) - For Auto Complete



 

 3. Install Rust Analyzer

 


 

 

Debugging The Code

 Now, you can use VS Code for Rust development. Let's try by creating new project via console

❯ cargo new helloworld
Created binary (application) `helloworld` package

Modify main.rs code by typing

fn perkalian(x: i32)-> i32 {
    x * x
}
fn main() {
    println!("Hello, world!");
    let number:i32 = 4;
    println!("Result = {}", perkalian(number));
}

You can watch variable number by right clicking then add to watch Create your a launch.json using lldb by pressing Ctrl+Shift+P and select Debug: Open launch.json Just copy and paste the script line below

{
      "version": "0.2.0",
      "configurations": [
      {
              "type": "lldb",
              "request": "launch",
              "name": "helloworld",
              "args": [],
              "program": "${workspaceFolder}/target/debug/helloworld",
              "windows": {
                    "program": "${workspaceFolder}/target/debug/helloworld.exe"
              },
              "cwd": "${workspaceFolder}",
              "stopOnEntry": false,
              "sourceLanguages": [
                    "rust"
              ]
        }
      ]
}


Now, you have to build and run with lldb debugger attached.

    • To build: Press Ctrl + Shift + B
    • Toggle breakpoints: F9
    • To debug: Press F5


 

 That's all. Thank you