Refleksi pada Rust

Halo. Tidak langsung, tapi saya suka Rust. Dan cinta ini membawaku ke lautan kode tanpa hukum yang tak ada habisnya. Tentang apa yang berhasil saya temukan - di bawah luka.





Tipe data rahasia

Jika Anda pernah membaca Rust Book, Anda mungkin ingat kode cuplikan serupa:





fn unwrap<T>(option: Option<T>) -> T{
    let unwrapped = match option{
        Some(val) => val,
        None => panic!("This cannot be None!")
    };
    return unwrapped;
}

fn main() {
    let unwrapped = unwrap(Some(0));
}
      
      



Memeriksa





Tentu saja, tidak ada yang aneh di sini. Kembalikan nilai di dalam Option, jika ada, atau panggil penghentian proses menggunakan panic! Macro. Tapi pernahkah Anda bertanya-tanya mengapa kode ini terkompilasi ? Bagaimana kompilator mengetahui bahwa fungsi yang mengembalikan T dapat mengembalikan ... this?





, - panic "!".





"!" . ? :





#![feature(never_type)]
use std::convert::TryInto;

#[derive(Debug)]
enum ConnectionError{
    BrokenPipe,
    BadId,
    Other
}

struct Client;
struct Request;
struct Response;

impl Request{
    pub fn build_response(&self) -> Response{
        Response
    }
}

fn get_request(id: i32) -> Result<(Client, Request), ConnectionError>{
    match id % 2 == 0{
        true => {
            Ok((Client, Request))
        },
        false => {
            Err(ConnectionError::BadId)
        }
    }
}

fn init_server() -> Result<!, ConnectionError>{
    loop {
        let (client, request) = get_request(5i32)?;
        let resp = request.build_response();
    };
}

fn main() {
    let x: ! = init_server().unwrap();
}
      
      







, , nightly , "!" "()":





fn init_server() -> Result<(), ConnectionError>{
    loop {
        let (client, request) = get_request(5i32)?;
        let resp = request.build_response();
    };
}

fn main() {
    let x = init_server().unwrap();
}
      
      



? , :





fn main() {
    match init_server(){
        Ok(v) => { println!("unreachable? {:?}", v); },
        Err(_) => {}
    }; 
}
      
      



, Ok(v) - . , , . , , , .





? , v



"". "!" , break



, continue



std::process::exit



.





, , . #![feature(never_type)]



? , , , . , , . panic, expect, todo unimplemented. "!"?





, . , .





Rust ( - , ) Fn



. - - ("closures" "", ), , . ?





, , , impl Trait. , , ...





use std::any::type_name;
fn type_of<T>(x: T) -> &'static str {
    type_name::<T>()
}

fn callback() -> impl Fn(f32) -> f32{
    |a| {
      a*2.  
    }
}

fn main() {
    let x = callback();
    println!("{}", type_of(x));
}
      
      



: playground::callback::{{closure}}



. , , impl Fn(f32) -> f32



, , . , trait object, dyn. - , trait object, Box:





fn main() {
    let x: Box<dyn Fn(f32) -> f32> = Box::new(callback());
    println!("{}", type_of(x));
}
      
      



:





alloc::boxed::Box&lt;dyn core::ops::function::Fn&lt;(f32,)>+Output = f32>







: , , .





, :





use tokio; // 1.0.2
use tokio::task::JoinError;
use futures::prelude::*; // 0.3.12

async fn job1(){}

async fn job2(){
	for i in 0..5{}
}

async fn job() -> Vec<impl Future<Output = Result<(), JoinError>>>{
    vec![
    tokio::spawn(async move{
        job1().await;
    }),
    tokio::spawn(async move{
        job2().await;
    })]
}

#[tokio::main]
async fn main() {
    let mut v = job();
}
      
      



, - tokio::spawn



tokio::task::JoinHandle



. , JoinHandle - , , async{}



, , async-, ?





let v = vec![
        Box::new(async{}),
        Box::new(async{
            let cb = |x| x*2.;
            let val = cb(1f32);
        })
    ];
      
      



, , , ? . , . , .





Karat, bagaimanapun juga, terkadang dapat menggugah pikiran. Mengapa tidak mempertahankan kapasitas perubahan? Mengapa kalkulus fungsional dibuat malas? Mengapa kargo membuat folder aneh dengan hash untuk setiap kesempatan, alih-alih membangun perpustakaan yang sama sekali (walaupun, sejujurnya, ini bukan masalah bahasa itu sendiri)? Bagaimanapun, jika menulis tentang plus adalah untuk menembak diri Anda sendiri, maka menulis dengan kasar adalah mencoba menembak diri Anda sendiri di kaki (dan Tuhan melarang Anda menggunakan ffi dalam proyek tersebut, maka upaya mungkin cukup berhasil) .





Tujuan artikel ini adalah mencoba mendalami bahasanya, untuk memahami cara kerjanya dari dalam, karena, seperti yang Anda ketahui, Anda hanya bisa mencintai seseorang yang Anda pahami.








All Articles