Defination
Roles
Why Rust use is more powerful than Java import
How to store data in key-value pair using hashmap
How to convert no into string
Python list ≈ Rust Vec ≈ Java ArrayList
Storing Different Data Types in Rust (Separate variables with strong typing)
How to Store Mixed Data Types in Rust (Tuple: fixed-size mixed types)
Storing Multiple Data Types in One Vector in Rust (Enum + Vec: Python-like list)
Working with Heterogeneous Collections in Rust.
Bring a long name into scope so we can write shorter code.
The use declaration can be used to bind a full path to a new name, for easier access.
Defination
The use declaration creates a local shortcut for a long module path, allowing code to be written in a simpler and more readable form.
2️⃣
use brings an item (module, function, type, or trait) into the current scope so it can be accessed without writing its full path every time.
3️⃣
In Rust, the use keyword maps a fully qualified path to a shorter name, reducing repetition and improving code clarity.
4️⃣
The use declaration acts as a name-binding mechanism that associates a complex path with a convenient identifier within a given scope.
5️⃣
Rust’s use statement allows developers to reference deeply nested items using concise names while preserving the original module structure.
Roles
“use creates a shortcut for a long path”
Rust
use std::collections::HashSet;
fn main() {
let mut ids = HashSet::new();
ids.insert(10);
ids.insert(20);
println!("{:?}", ids.contains(&10));
}
Output
true
Java (same idea)
import java.util.HashSet;
public class Main {
public static void main(String[] args) {
HashSet<Integer> ids = new HashSet<>();
ids.add(10);
ids.add(20);
System.out.println(ids.contains(10));
}
}
Output
true
“use brings an item into scope so you can call it directly”
Rust (import function)
use std::cmp::min;
fn main() {
println!("{}", min(9, 4));
}
Output
4
Java (closest equivalent)
Java cannot import a static method like Rust without special syntax, so you usually write:
public class Main {
public static void main(String[] args) {
System.out.println(Math.min(9, 4));
}
}
Output
4
✅ Rust can import functions directly; Java typically uses Class.method().
3) “use maps a full path to a shorter name (alias)”
Rust (as alias)
use std::cmp::max as maximum;
fn main() {
println!("{}", maximum(5, 99));
}
Output
99
Java (no alias in import)
Java doesn’t support renaming imports, so we simulate with a helper method:
public class Main {
static int maximum(int a, int b) {
return Math.max(a, b);
}
public static void main(String[] args) {
System.out.println(maximum(5, 99));
}
}
Output
99
✅ Rust supports aliasing imports; Java does not.
4) “use binds a complex path to a convenient identifier within a scope”
Rust (block-scoped use)
fn greet() {
println!("Outer greet()");
}
mod deep {
pub fn greet() {
println!("Deep greet()");
}
}
fn main() {
greet();
{
use crate::deep::greet; // only inside this block
greet(); // calls deep::greet
}
greet(); // back to outer greet
}
Output
Outer greet()
Deep greet()
Outer greet()
Java (imports are not block-scoped)
Java cannot “import inside a block”. You must call using the class/namespace structure.
public class Main {
static void greet() {
System.out.println("Outer greet()");
}
static class Deep {
static void greet() {
System.out.println("Deep greet()");
}
}
public static void main(String[] args) {
greet();
{
// no block import possible, so call explicitly:
Deep.greet();
}
greet();
}
}
Output
Outer greet()
Deep greet()
Outer greet()
✅ Rust use can be scoped to a block; Java cannot.
5) “use keeps module structure but lets you use short names”
Rust (import module + item)
use std::fs;
use std::fs::File;
fn main() {
let _ = File::create("demo.txt").unwrap();
let size = fs::metadata("demo.txt").unwrap().len();
println!("{}", size);
}
Output
0
Java (similar)
import java.io.File;
public class Main {
public static void main(String[] args) throws Exception {
File file = new File("demo.txt");
file.createNewFile();
System.out.println(file.length());
}
}
Output
0
Why Rust use is more powerful than Java import
At a high level:
Java import only shortens class names (file-level).
Rust use controls names, scope, traits, enums, macros, and even public API design.
Let’s see this with code, not theory.
1️⃣ Block-scoped imports (Rust ✅ | Java ❌)
Rust example (block-level use)
fn greet() {
println!("Hello from greet()");
}
fn main() {
println!("Before block");
{
use crate::greet;
greet(); // available only inside this block
}
println!("After block");
// greet(); ❌ not in scope here
}
Output
Before block
Hello from greet()
After block
fn add(a: i32, b: i32) -> i32 {
a + b
}
fn main() {
println!("Before block");
{
use crate::add;
println!("{}", add(2, 3));
}
println!("After block");
}
Output
Before block
5
After block
Java (NOT possible)
// Java imports are file-level only
Java (not possible directly)
public class Main {
static int add(int a, int b) {
return a + b;
}
public static void main(String[] args) {
System.out.println("Before block");
System.out.println(add(2, 3));
System.out.println("After block");
}
}
wrong :error in java
✅ Rust advantage: fine-grained scope control
❌ Java limitation: imports apply to the entire file
2️⃣ Import aliasing (as) to avoid name conflicts
Rust example
use std::cmp::max as maximum;
fn main() {
println!("{}", maximum(10, 20));
}
Output
20
Java (no import aliasing)
public class Main {
static int maximum(int a, int b) {
return Math.max(a, b);
}
public static void main(String[] args) {
System.out.println(maximum(10, 20));
}
}
❌ Java cannot rename imports
✅ Rust can rename any imported item
3️⃣ Importing functions, not just classes
Rust example
use std::cmp::min;
fn main() {
println!("{}", min(5, 3));
}
Output
3
Java equivalent
public class Main {
public static void main(String[] args) {
System.out.println(Math.min(5, 3));
}
}
❌ Java must always prefix with class name
✅ Rust imports functions directly
4️⃣ Trait imports enable methods (BIGGEST DIFFERENCE)
Rust example (method works only if trait is imported)
use std::io::Write;
fn main() {
let mut buffer = Vec::new();
buffer.write_all(b"Hi").unwrap();
println!("{:?}", buffer);
}
Output
[72, 105]
👉 Without use std::io::Write, write_all() will not compile.
Java (no equivalent concept)
// Interfaces do not require imports for methods to work
✅ Rust advantage: explicit capability control
❌ Java: methods always available once class is known
5️⃣ Enum variant imports (clean match syntax)
Rust example
use std::cmp::Ordering::*;
fn main() {
match 5.cmp(&10) {
Less => println!("Less"),
Greater => println!("Greater"),
Equal => println!("Equal"),
}
}
Output
Less
Java equivalent
public class Main {
enum Ordering { LESS, GREATER, EQUAL }
public static void main(String[] args) {
Ordering result = Ordering.LESS;
switch (result) {
case LESS -> System.out.println("Less");
case GREATER -> System.out.println("Greater");
case EQUAL -> System.out.println("Equal");
}
}
}
❌ Java cannot import enum variants directly
✅ Rust allows variant-level imports
6️⃣ Grouped imports (cleaner & safer)
Rust example
use std::{fs::File, io::Read};
fn main() {
let mut file = File::open("test.txt").unwrap();
let mut contents = String::new();
file.read_to_string(&mut contents).unwrap();
println!("{}", contents);
}
Java equivalent
import java.io.File;
import java.nio.file.Files;
public class Main {
public static void main(String[] args) throws Exception {
File file = new File("test.txt");
System.out.println(Files.readString(file.toPath()));
}
}
✅ Rust supports nested grouping
❌ Java requires multiple lines
7️⃣ pub use for API design (re-exporting)
Rust example
mod math {
pub fn add(a: i32, b: i32) -> i32 {
a + b
}
}
// re-export
pub use math::add;
fn main() {
println!("{}", add(2, 3));
}
Output
5
Java (no true equivalent)
// Java cannot re-export members from another class
How to store data in key-value pair using hashmap
What is a HashMap?
A HashMap is a data structure used to store key → value pairs.
You give a key
You get a value
Lookup is very fast (average O(1))
🦀 Rust: HashMap
In Rust, HashMap comes from std::collections.
✅ Purpose in Rust
Store data as key → value
Fast lookup, insert, update, delete
Keys must be unique
Values can be of any type
Ownership & borrowing rules apply
Example (Rust)
use std::collections::HashMap;
fn main() {
let mut scores = HashMap::new();
scores.insert("Alice", 10);
scores.insert("Bob", 20);
println!("{:?}", scores);
}
Rust output
{"Alice": 10, "Bob": 20}
use std::collections::HashMap;
fn main() {
let mut marks = HashMap::new();
marks.insert("Math", 90);
marks.insert("Science", 85);
println!("Math marks: {:?}", marks.get("Math"));
}
Output
Math marks: Some(90)
Python Equivalent: dict
Purpose in Python
Python’s dictionary (dict) is the direct equivalent of Rust’s HashMap.
Key → value storage
Very fast access
Keys must be unique
Dynamic & easy to use
Example (Python)
marks = {}
marks["Math"] = 90
marks["Science"] = 85
print("Math marks:", marks.get("Math"))
Output
Math marks: 90
Java code
import java.util.HashMap;
public class Main {
public static void main(String[] args) {
HashMap<String, Integer> scores = new HashMap<>();
scores.put("Alice", 10);
scores.put("Bob", 20);
System.out.println(scores);
}
}
Java output
{Alice=10, Bob=20}
How to convert no into string
use std::string::ToString;
fn main() {
let num = 100;
let s = num.to_string();
println!("{}", s);
}
Output
100
Python list ≈ Rust Vec ≈ Java ArrayList
Purpose
Store ordered, resizable collections
Python: list
numbers = [10, 20, 30]
numbers.append(40)
print(numbers)
Output
[10, 20, 30, 40]
Rust: Vec (most common)
fn main() {
let mut numbers = vec![10, 20, 30];
numbers.push(40);
println!("{:?}", numbers);
}
Output
[10, 20, 30, 40]
Java: ArrayList
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
ArrayList<Integer> numbers = new ArrayList<>();
numbers.add(10);
numbers.add(20);
numbers.add(30);
numbers.add(40);
System.out.println(numbers);
}
}
Output
[10, 20, 30, 40]
Storing Different Data Types in Rust (Separate variables with strong typing)
fn main() {
let age: i32 = 1;
let name: String = "hello".to_string();
let price: f64 = 3.5;
let is_active: bool = true;
println!("age = {}", age);
println!("name = {}", name);
println!("price = {}", price);
println!("is_active = {}", is_active);
}
Output
age = 1
name = hello
price = 3.5
is_active = true
2)
How to Store Mixed Data Types in Rust (Tuple: fixed-size mixed types)
fn main() {
let data: (i32, &str, f64, bool) = (1, "hello", 3.5, true);
println!("Tuple = {:?}", data);
// Extract values
let (a, b, c, d) = data;
println!("a = {}", a);
println!("b = {}", b);
println!("c = {}", c);
println!("d = {}", d);
}
Output
Tuple = (1, "hello", 3.5, true)
a = 1
b = hello
c = 3.5
d = true
3)
Storing Multiple Data Types in One Vector in Rust (Enum + Vec: Python-like list)
Code
#[derive(Debug)]
enum Value {
Int(i32),
Text(String),
Float(f64),
Bool(bool),
}
fn main() {
let data = vec![
Value::Int(1),
Value::Text("hello".to_string()),
Value::Float(3.5),
Value::Bool(true),
];
println!("Vector = {:?}", data);
// Extract values safely using match
for item in data {
match item {
Value::Int(v) => println!("Int = {}", v),
Value::Text(v) => println!("Text = {}", v),
Value::Float(v) => println!("Float = {}", v),
Value::Bool(v) => println!("Bool = {}", v),
}
}
}
Output
Vector = [Int(1), Text("hello"), Float(3.5), Bool(true)]
Int = 1
Text = hello
Float = 3.5
Bool = true
4)
Working with Heterogeneous Collections in Rust (Trait object: Box)
This is the closest to Python dynamic storage, but extraction is runtime-based.
Code
use std::any::Any;
fn main() {
let data: Vec<Box<dyn Any>> = vec![
Box::new(1_i32),
Box::new(String::from("hello")),
Box::new(3.5_f64),
Box::new(true),
];
// Print each by checking its real type at runtime
for item in data.iter() {
if let Some(v) = item.downcast_ref::<i32>() {
println!("Int = {}", v);
} else if let Some(v) = item.downcast_ref::<String>() {
println!("Text = {}", v);
} else if let Some(v) = item.downcast_ref::<f64>() {
println!("Float = {}", v);
} else if let Some(v) = item.downcast_ref::<bool>() {
println!("Bool = {}", v);
} else {
println!("Unknown type");
}
}
}
Output
Int = 1
Text = hello
Float = 3.5
Bool = true
Top comments (0)