Aula 21 Go e Rust

Julia correções

+ - * e == em arrays fazem as operacoes nos arryas como um todo Em particular * é o produto de matrizes, == é a igualdade de vetores

.* .==fazem as operaçoes elemento por elemento

julia> [1,2,3]==[1,2,8]
false

julia> [1,2,3].==[1,2,8]
3-element BitVector:
 1
 1
 0

julia> [1 2; 3 4] * [5 6; 7 8]
2×2 Matrix{Int64}:
 19  22
 43  50

julia> [1 2; 3 4] .* [5 6; 7 8]
2×2 Matrix{Int64}:
  5  12
 21  32

+ e .+ sao equivalentes!!

linguagens de baixo nivel (system programming languages)

GO

https://go.dev site do Go

https://go.dev/play/ Go online

https://gobyexample.com fonte

https://go.dev/tour/list tour com exemplos executaveis

Caracteristicas

var foo int = 10 

ou

foo := 10

var para declarar variaveis mutavies, val para declarar variaveis imutaveis

Arrays

há dois conceitos relacionados com array

um array é de tamanho fixo e o tamanho é parte to tipo

um slice é definido apenas pelo tipo interno e nao o tamanho. Ele se refere a um trecho de um array.

Slices sao criados por make . Arrays sao definidos em declaracoes de variavies

var a [5]int   <-- array

b := make([]int, 5)  <-- slice

slices vs arrays https://go.dev/blog/slices-intro

Dicionarios

chamados de map

tipados

m := make(map[string]int)

Chamada de funcoes go

go funcao(a,b) executa a funcao em paralelo gorotines

as funcoes em paralelo podem se comunicar via canais (tipo chan)

c <- ... envia para o canal

.. <- c recebe de um canal

Defer

defer funcao(a,b) coloca a chamada numa pilha e elas serao executadas quando a funcao envolvente acabar

Resumo Go

RUST

https://www.rust-lang.org site

https://doc.rust-lang.org/rust-by-example/ fonte

https://doc.rust-lang.org/book/title-page.html outra fonte

https://play.rust-lang.org rust online

outra linguagem de baixo nivel

desenvolvida pela Mozila

Tipos e variavies

fn main() {
    // Variables can be type annotated.
    let logical: bool = true;

    let a_float: f64 = 1.0;  // Regular annotation
    let an_integer   = 5i32; // Suffix annotation

    // Or a default will be used.
    let default_float   = 3.0; // `f64`
    let default_integer = 7;   // `i32`
    
    // A type can also be inferred from context 
    let mut inferred_type = 12; // Type i64 is inferred from another line
    inferred_type = 4294967296i64;
    
    // A mutable variable's value can be changed.
    let mut mutable = 12; // Mutable `i32`
    mutable = 21;
    
    // Error! The type of a variable can't be changed.
    mutable = true;
}
fn main() {
    let a = [1, 2, 3, 4, 5];

    println!("Please enter an array index.");

    let mut index = String::new();

    io::stdin()
        .read_line(&mut index)
        .expect("Failed to read line");

    let index: usize = index
        .trim()
        .parse()
        .expect("Index entered was not a number");

sintaxe

sintaxe do C com ; e { }

permite programacao funcional (veja https://doc.rust-lang.org/rust-by-example/fn/hof.html (ao que parece com thunks - veja o (0..) é um range infinito

Ownership

esse é o grande diferencial de Rust

https://www.makeuseof.com/rust-ownership/

https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html

variavies que apontam para a mesma posicao de memoria - só uma tem direito aquela posicao

transferir posse de uma para outra variavel é chamado de move

let s = "um";  <- aloca no stack
let owner = String::from("one");  <- aloca no heap e pode ser modificavel
...
let new_owner = owner; <- new_owner passa a ter o valor
...
println("{}",owner); <- da erro

nao ha problema com variavies no stack - tamanho fixo

let x = 5; 
let y = x; <-- causa copia

println("{}",x); <-- sem problema

o problema parece ser funcoes

passar uma variavel para uma funçao causa um move

fn takes_ownership(some_string: String) { 
    println!("{}", some_string);
} 

fn makes_copy(some_integer: i32) { 
    println!("{}", some_integer);
} 
 
... 

    let s = String::from("hello");  // s comes into scope

    takes_ownership(s);             // s's value moves into the function...
                                    // ... and so is no longer valid here

    let x = 5;                      // x comes into scope
    
    makes_copy(x);                  // x would move into the function,
                                    // but i32 is Copy, so it's okay to still
                                    // use x afterward

voce pode passar uma referencia que nao causa o move

fn main() {
    let s1 = String::from("hello");

    let len = calculate_length(&s1);  <-- referencia a s1 e nao causa o move

    println!("The length of '{}' is {}.", s1, len); <-- funciona
}

fn calculate_length(s: &String) -> usize {
    s.len()
}

referencias mutaveis

fn main() {
   let mut s = String::from("hello");

   change(&mut s);
                   <-- acho!! que o s esta disponivel aqui
}

fn change(some_string: &mut String) {
   some_string.push_str(", world");
}

nao pode haver mais de uma referencia mutavel ao mesmo tempo

let mut s = String::from("hello");

    let r1 = &mut s;
    let r2 = &mut s;

    println!("{}, {}", r1, r2);

ownership sobre partes de um array/slice https://doc.rust-lang.org/book/ch04-03-slices.html

por que o ownership?

Me parece que é a ideia do escape analysys. Vc determina que referencias a uma memoria nao escapam de uma funcao e entao qunado termina o escopo da referencia, vc pode desalocar a memoria do heap.

Outras coisas se Rust

https://doc.rust-lang.org/book/title-page.html