More is to compare the differences between the two languages from the perspective of a front-end developer to facilitate easier entry.
Basic Types (DataType)#
In most cases, basic types directly represent the lowest level of language implementation.
JavaScript is weakly typed, and there are 7 basic data types:
- String
- Number
- BigInt
- Boolean
- Symbol (added in ECMAScript 2016)
- null
- undefined
Rust is a statically typed language, which means that the type of every variable must be known at compile time. Each value belongs to a data type, which tells Rust what kind of data it is and how to handle it. They can be divided into two subsets: scalar and compound.
Integer
Bit Length | Signed | Unsigned |
---|---|---|
8-bit | i8 | u8 |
16-bit | i16 | u16 |
32-bit | i32 | u32 |
64-bit | i64 | u64 |
128-bit | i128 | u128 |
arch | isize | usize |
Each signed variant can store numbers from $-(2^{n-1})$ to $2^{n-1}-1$, where $n$ is the number of bits used by the variant. So i8
can store numbers from $-(2^7)$ to $2^7-1$, which is from $-128$ to $127$. Unsigned variants can store numbers from $0$ to $2^n-1$, so u8
can store numbers from $0$ to $2^8-1$, which is from $0$ to $255$.
Note: You can write numeric literals in any of the forms shown in the table below. Note that numeric literals can have type suffixes, such as 57u8
to specify the type, and can also use underscores as separators for readability, such as 1_000
, which has the same value as 1000
.
Representation of Integers
Base | Example |
---|---|
Decimal | 98_222 |
Hexadecimal | 0xff |
Octal | 0o77 |
Binary | 0b1111_0000 |
Byte (only for u8 type) | b'A' |
Floating-Point Number
A floating-point number is a number with a decimal point. Rust's floating-point number types are f32
and f64
, which occupy 32 bits and 64 bits respectively. The default type is f64
, which has almost the same speed as f32
in modern CPUs, but with higher precision. All floating-point types are signed.
Bool
Identifier: bool
- true
- false
Char
A single quote is used to represent the character type (char), and double quotes are used to declare strings (str).
The char
type in Rust has a size of four bytes and represents a Unicode scalar value, which means it can represent more than just ASCII characters. In Rust, accented letters, Chinese, Japanese, Korean characters, emojis, and zero-width whitespace characters are all valid char
values. Unicode scalar values range from U+0000
to U+D7FF
and U+E000
to U+10FFFF
. However, "character" is not a concept in Unicode, so the intuitive notion of "character" may not match Rust's char
.
Compound Types
Rust has two native compound types: tuples and arrays.
- Tuples are a primary way to group together multiple values of different types.
- Tuples have a fixed length: once declared, their length cannot be increased or decreased.
- Each element in an array must have the same type.
- Arrays in Rust have a fixed length.
Others
- Vector (
Vec<T>
)- Variable-length array
- A vector allows us to store more than one value in a single data structure, with all the values arranged adjacent to each other in memory.
- String
- A string is a collection of bytes with some methods implemented.
- The type called
String
is provided by the standard library and is not part of the core language. It is a growable, mutable, owned, UTF-8 encoded string type.
- Map (
HashMap<K, V>
)- It implements mapping by using a hashing function to determine how keys and values are placed in memory. Many programming languages support this data structure, but it is often called by different names, such as hash, map, object, hash table, or associative array, etc.
- Hash maps can be used in situations where any type can be used as a key to look up data, unlike vectors, which require indexing.
Variables#
var code = 123; // In older specifications, only the var keyword is required for declaration
let firstName = "kaby"; // After ES6, let represents a variable that can be modified
const lastName = "Zhao"; // After ES6, const represents a constant that cannot be modified
firstName = "bike"; // Normal
lastName = "Hu"; // Error - Uncaught TypeError: Assignment to constant variable
// By default, all variables in Rust are not allowed to be modified, such as
let code = 123;
println!("The value of code is: {code}"); // Normal
code = 456; // Error - cannot assign twice to immutable variable `code`
// Declare a mutable variable
let mut name = "lulu";
println!("The name is: {name}"); // Output lulu
name = "jack";
println!("The name is: {name}"); // Output jack
// The same keywords can be used to declare constants
// Constants cannot be used with mut
// Constants cannot be changed by default
const WAIT_SEC:u32 = 30;
// Variable shadowing
fn main() {
let x = 5;
let x = x + 1;
{
let x = x * 2;
// 12
println!("The value of x in the inner scope is: {x}");
}
// 6
println!("The value of x is: {x}");
}
Functions & Logic#
// Function declaration
function getName() {
return "jack";
}
// Using variables
let getInfo = function() {
return {
"age": 18
}
}
// The above can also be expressed using arrows
let getInfo = () => ({ "age": 18 })
// Logic
// Conditional statements if / switch
if (getName() == "jack") {
return "lose";
} else if (getName() == "lose") {
return "moth";
} else {
return "";
}
// Loops for...in / for...of / while
let arr = [1, 2, 3];
for(let i = 0; i < arr.length; i++) {
console.info(i);
}
// As JavaScript is a weakly typed language, it automatically infers and converts variable types
// So for some comparisons and judgments, it is relatively simple, just use == directly
// However, unexpected situations may also occur, such as
// "5" == 5 evaluates to true, so you need to be careful and use "5" === 5 to solve it.
// You can also directly compare strings for equality
// "abc" == "cde"
// Functions
fn main() {
println!("hello world");
another_function();
// print_labeled_measurement
print_labeled_measurement(5, 'h');
// plus_one
let po = plus_one(8);
// po == 9
println!("The result of the calculation is {}", po);
// do logic_info function
logic_info("abc", 12);
// loop
loop_info();
}
// another_function
fn another_function() {
println!("another_function");
}
// Function with parameters
fn print_labeled_measurement(value: i32, unit_label: char) {
println!("The measurement is: {value}{unit_label}");
}
// If a function has a return value, you also need to define the return type
fn plus_one(x: i32) -> i32 {
return x + 1;
}
// Logic
fn logic_info(name: &str, age: i32) {
println!("{}'s age is {}", name, age);
// For numeric types, you can use if for comparison directly
if age > 12 {
println!("Over 12 years old, need to buy a ticket");
} else if age < 12 {
println!("Ride for free");
} else {
println!("12 years old, need to buy a ticket");
}
// String comparison
if name == "lulu" {
println!("Hello, {}", name);
} else {
println!("Name does not match");
}
}
// Loops
fn loop_info() {
// while loop
let mut number = 3;
while number != 0 {
println!("{number}!");
number -= 1;
}
println!("LIFTOFF!!!");
// for loop
let a = [10, 20, 30, 40, 50];
for element in a {
println!("the value is: {element}");
}
// loop loop
// Note that the loop loop does not automatically terminate, you need to manually break
let mut counter = 0;
let result = loop {
counter += 1;
if counter == 10 {
break counter * 2;
}
};
println!("The result of the loop loop is: {result}");
}
// You can view the specific code here
// https://play.rust-lang.org/?gist=e87ef95f861dbc22bf8f23722e40aa34
—EOF—