Safe Way to access private fields in Rust

Do you want your fields to be private but got stuck in accessing them from other module. Then this blog let you know the ways to access the private fields as well as which one is safer way.

There are two approaches :

  • with getter and setter
  • without getter and setter

[A] with getter and setter

You can create a public struct with private fields. For example: lets have employee as a struct which has employee code , employee name as public fields and employee salary as private field. src/model.rs:

#[derive(Default)]
pub struct Employee {
    pub emp_code: i32,
    pub emp_name: String,
    emp_salary: f64,
}

To access the employee salary, we can have getter and setter in its impl. For example:src/model.rs:

impl Employee {
    pub fn new() -> Employee {
        Employee {
            emp_code: 101,
            emp_name: "Amita".to_string(),
            emp_salary: 0.0
        }
    }

    pub fn salary(self) -> f64 {
        self.emp_salary
    }

    pub fn set_salary(&mut self,emp_salary: f64) {
        self.emp_salary = emp_salary
    }
}

In above example, new() can be treated as default constructor. You don’t require to use get in method’s name for getter as mentioned in API guidelines. salary() is used to get employee’s salary and set_salary() is used to set the employee’s salary. src/main.rs:

pub mod model;
use model::Employee;

fn main() {
    let employee: Employee= Employee::new();
    println!("Salary!{}",employee.salary());
    let mut employee: Employee= Employee::new();
    employee.set_salary(5000.50);
    println!("Salary!{}",employee.salary());
}

[B] without getter and setter

First, define a new struct that has the same layout as the one you wish to expose but with a private field. Then you use std::mem::transmute to convert to the new struct. Now the field is accessible. For example,

src/main.rs:

use crate::model::Employee;

mod model {
    #[derive(Default)]
    pub struct Employee {
        pub emp_code: i32,
        pub emp_name: String,
        emp_salary: f64,
    }

    impl Employee {
        pub fn new() -> Employee {
            Employee {
                emp_code: 101,
                emp_name: "Amita".to_string(),
                emp_salary: 3000.0
            }
        }
    }
}

struct MyEmployee {
    pub emp_code: i32,
    pub emp_name: String,
    pub emp_salary:f64,
}

fn main() {
    let emp: Employee= model::Employee::new();

    // this will not compile:
    // let salary: f64 = emp.emp_salary;

    let emp_exposed: MyEmployee = unsafe {
        std::mem::transmute(emp)
    };
    let salary: f64 = emp_exposed.emp_salary;
    println!("salary {}", salary);
}

In the above example, transmute reinterprets the bits of a value of one type as another type. It is an unsafe function and equivalents to C’s ‘memcpy‘.

Conclusion:

getter & setter is the best approach to access private fields in safer manner as comparison to the mem:: transmute.

I hope this blog covers all your doubts about how to access private fields of any struct in rust as compared to other programming languages. This article was first published on the Knoldus blog


Knoldus-blog-footer-image

Written by 

Amita Yadav is a Software Consultant Trainee at Knoldus Software INC, currently working on RUST, system programming language. She is self-determined at what she has to do. She likes to learn trending technologies. She is familiar with languages such as C++, C, Java, Scala and technologies like lagom, Play, Akka, Kafka, spark, and databases like Cassandra, MySql, Sqlite, Slick. She loves to create amazing videos mashup.

1 thought on “Safe Way to access private fields in Rust

Leave a Reply

Knoldus Pune Careers - Hiring Freshers

Get a head start on your career at Knoldus. Join us!

%d bloggers like this: