Rust: Difference between revisions

From bibbleWiki
Jump to navigation Jump to search
Line 316: Line 316:


= More Data Structures =
= More Data Structures =
== Slices ==
Get the first 3 elements of an array
<syntaxhighlight lang="rust">
<syntaxhighlight lang="rust">
fn use_slice(slice: &mut[i32])
{
}
fn test()
{
  let mut data = [1,2,3,4,5];
  // Passes element 1-3 to use_slice as a reference
  use_slice( &mut data[1..4]);
}
</syntaxhighlight>
== Strings ==
Two types, static string and string type
<syntaxhighlight lang="rust">
let s = "hello";
// Cannot do
// let h = s[0]
// You can iterate as a sequence using chars e.g.
for c in s.chars()
{
  println!("{}", c);
}
</syntaxhighlight>
And now the mutable string in rust essentially an vector
// Create a string
<syntaxhighlight lang="rust">
let mut letters = String::new();
</syntaxhighlight>
Add a char
<syntaxhighlight lang="rust">
let a = 'a' as u8;
letters.push(a as char);
</syntaxhighlight>
String to str
<syntaxhighlight lang="rust">
let u:%str = &letters;
</syntaxhighlight>
Concatenation
<syntaxhighlight lang="rust">
let z = lettters + &letters
</syntaxhighlight>
Other examples
<syntaxhighlight lang="rust">
let mut abc = "hello world".to_string()'
abc.remove(0);
abc.push_str("!!!");
abc.replace("ello","goodbye")
</syntaxhighlight>
== Tuples ==
Eezy peezy lemon squeezy
<syntaxhighlight lang="rust">
fn sum_and_product(x:i32,y:i32) -> (i32, i32)
{
(x+y, x*y)
}
fn main()
{
  let sp = sum_and_product(3,4);
  let (a,b) = sp;
  let sp2 = sum_and_product(4,5);
 
  // combine
  let combined = (sp, sp2);
  let ((c,d), (e,f)) = combined;
}
</syntaxhighlight>
== Pattern Matching ==
Various pattern matching
<syntaxhighlight lang="rust">
match x
{
  0 => "zero"
  1 | 2 => "one or two"
  9...1 => "lots of"
  _ if(blahh) => "something"
  _ => "all others"
}
</syntaxhighlight>
Using two dots .. with pattern matching allows you to ignore other values except those specified.
== Generics ==
Looks like templates
<syntaxhighlight lang="rust">
struct Point<T>
{
  x: T,
  y: T
}
fn generics()
{
  let a:Point<i32> = Point {x: 0, y: 4}
}
</syntaxhighlight>
</syntaxhighlight>

Revision as of 05:52, 22 June 2020

Sample program

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

Cargo

Sample file

[package]
name = "hello_world"
version = "0.0.1"
authors = [ "Iain Wiseman iwiseman@bibble.co.nz" ]

Sample commands

cargo new hello_world --bin
cargo build
cargo run

Types and Variables

Fundamental Data Types

Primitive types

Cam declare with size of type

let a:u8 = 123; // unsigned int 8 bits number immutable
let a:i8 = 123; // signed int 8 bits number immutable
let mut a:u8 = 123; // unsigned int 8 bits number mutable

Or without e.g.

let mut c = 123456789 // 32-bit signed i32
println!("c = {}", c);

Now variable based on OS e.g.

let z:isize = 123 // signed 64 bit if on 64 bit OS

Decimal

let e:f64 = 2.5 // double-precision, 8 bytes or 64-bits

Char

let x:char = 'x' // Note 4 bytes unicode

boolean

let g:bool = false; // Note 4 bytes unicode

Operators

Does not support -- and ++ but does support

a -= 2;

Remainder can be calculated using

a%3

Bitwise

let c = 1 | 2 // | OR

Shift

let two_to_10 = 1 << 10; // 1024

Logical of standard e.g.

let pi_less_4 = std::f64::consts::PI < 4.0; // true

Scope and shadowing

Curly braces keep scope

 fn test()
 {
   {
     let a = 5; 
   }
   println!("Broken {a}");
 }

Shadowing is fine though

 fn test()
 {
   let a = 5; 
   {
     let a = 10; 
     println!("10 {a}");
   }
   println!("5 {a}");
 }

Constants

Standard const

 const MEANING_OF_LIFE:u8 = 42;

Static const

 static Z:i32 = 123;

Stack and Heap

Same a c++ i.e.

 let y = Box::new(10);
 println!("y = {}", *y);

Control Flow

if statement

Same as C++ except no brackets

 if temp > 30 
 {
    println!("Blah");
 }
 else if temp < 10 
 {
    println!("Blah"); 
 }
 else
 {
    println!("Blah"); 
 }

Elvis is like

  let a = if temp > 30 {"sunny"} else {"cloud"}

While and Loop

While

Same as C++ except no brackets

 while x < 1000
 {
 }

There is support for continue and break

Loop

Loop is while true

 loop
 {
    if y == 1 << 10 { break; }
 }

For Loop

A bit like kotlin loops (I think)

 for x in 1..11
 {
    println!("x = {}",x);
 }

You can get position in series as well

 for (pos,x) in (1..11).enumerate()
 {
    println!("x = {}, pos = {}",x, pos);
 }

Match

Match can be used like case

 let country = match country_code
 {
    44 => "uk",
    46 => "sweden",
    7 => "russia"
    1...999 => "unknown" // other triple dot inclusive
    _ => "invalid" // invalid
 };

Data Structures

Structs

struct Point
{
  x: f64,
  y: f64
}

fn main()
{
  let p = Point { x: 30.0, y: 4.0 };
  println!("point is at ({},{})", p.x, p.y)
}

Enumerators

Similar to c++

enum Color {
  Red,
  Green,
  Blue
}

fn main()
{
  let c:Color = Color::Red;
  match c
  {
     Color::Red => prinln!("Color is Red");
     Color::Green => prinln!("Color is Green");
  }
}

But maybe not we can add types

enum Color {
  Red,
  Green,
  Blue,
  RgbColor(u8,u8,u8) // Tuple
  CmykColor{cyan:u8, magenta:u8, yellow:u8, black:u8,} // Struct
}

fn main()
{
  let c:Color = Color::RgbColor(10,0.0);
  match c
  {
     Color::Red => prinln!("Color is Red");
     Color::Green => prinln!("Color is Green");
     Color::RgbColor(0,0,0) => prinln!("Color is Black");
     Color::RgbColor(r,g,b) => prinln!("Color is {},{},{}", r,g,b);
  }

  let d:Color = Color::CmykColor(cyan:0, magenta:0, yellow:0, black:0);
  match d
  {
     Color::Red => prinln!("Color is Red");
     Color::Green => prinln!("Color is Green");
     Color::RgbColor(0,0,0) => prinln!("Color is Black");
     Color::CmykColor(cyan:_, magenta:_, yellow:_, black:255) => prinln!("Black");
  }
}

Option <T> and if let

Used to avoid null or invalid values

let x = 3.0
let y = 0.0 // Divide by zero

let result:Option<f64> = 
   if y != 0.0 { Some(x/y) } else { None };

// Using match
match result
{
   Some(z) => println!("Goody result"),
   None => println!("No result)
}

// Using if let
if let Some(z) = result { println!("z = {}", z); }

Arrays

Array sizes cannot grow in rust

Simple

let mut a:[i32;5] = [1,2,3,4,5];
// Or 
let mut a = [1,2,3,4,5];
// Length
 a.len()
// Assignment
 a[0] = 321
// Printing
 println!("{:?}", )
// Testing
  if a == [1,2,3,4,5]
  {
  }
// Initialise
  let b = [1,10]; // 10 array initialised to 1

Multi Dimension

Here is a two dimension array

let mtx:[[f32;3];2] =
[
  [1.0, 0.0, 0.0],
  [0.0, 2.0, 0.0],
];

Vectors

Same a c++

let mut a = Vec::new()
a.push(1);
a.push(2);
a.push(3);
// Print
println!("a[0] {}", a[0]);
// Using get returns a option
match a.get(3333)
{
...
}

// Removing, pop returns an option   
let last_elem = a.pop();

// Using the option type iterating over vector to print it
while let Some(x) = a.pop()
{
   println!("x = {}",x);
}

More Data Structures

Slices

Get the first 3 elements of an array

fn use_slice(slice: &mut[i32])
{

}

fn test()
{
  let mut data = [1,2,3,4,5];
  // Passes element 1-3 to use_slice as a reference
  use_slice( &mut data[1..4]); 
}

Strings

Two types, static string and string type

let s = "hello";
// Cannot do
// let h = s[0]
// You can iterate as a sequence using chars e.g.
for c in s.chars()
{
  println!("{}", c);
}

And now the mutable string in rust essentially an vector // Create a string

let mut letters = String::new();

Add a char

let a = 'a' as u8;
letters.push(a as char);

String to str

let u:%str = &letters;

Concatenation

let z = lettters + &letters

Other examples

let mut abc = "hello world".to_string()'
abc.remove(0);
abc.push_str("!!!");
abc.replace("ello","goodbye")

Tuples

Eezy peezy lemon squeezy

fn sum_and_product(x:i32,y:i32) -> (i32, i32)
{
 (x+y, x*y)
}

fn main()
{
  let sp = sum_and_product(3,4);
  let (a,b) = sp;
  let sp2 = sum_and_product(4,5);
   
  // combine
  let combined = (sp, sp2);
  let ((c,d), (e,f)) = combined;
}

Pattern Matching

Various pattern matching

match x
{
  0 => "zero"
  1 | 2 => "one or two"
  9...1 => "lots of"
  _ if(blahh) => "something"
  _ => "all others"
}

Using two dots .. with pattern matching allows you to ignore other values except those specified.

Generics

Looks like templates

struct Point<T>
{
  x: T,
  y: T
}

fn generics()
{
  let a:Point<i32> = Point {x: 0, y: 4}
}