Rust or Rest

缘起

与Rust的相遇,是在一个散漫的周末的午后,冬日将阳光慢悠悠地扔了进来,沏一杯茶,便开始了与你的邂逅。

倾心

曾经也算是看过一些编程语言(Python, Go, Lua, Haskell)的人,为什么会被Rust所吸引?

Rust最让我着迷的有两点一个是无GC,另外一个便是Rust只有一个极小的运行时,这使得它可以直接运行在裸机之上。

带着好奇心,我走进了Rust的世界,后面所经历的一切都让我对Rust甚至是编程语言的认识有了飞跃。

感受

讲Rust就绕不过所有权,所有权是Rust内存管理的核心概念。

让我们看一下下面这个例子。

fn main() {
    {
        let s = 5;
    }

    println!("{}", s);
}

把5这个值绑定到s,如果所有权没有发生转移,那么在s所在的作用域中s拥有5的所有权,如果离开它所在的作用域,s将被drop,此程序无法通过编译。

我们再来看一个例子。

fn change(a: &mut i32) {
    *a = 6
}

fn main() {
    let mut s: i32 = 5;

    {
        change(&mut s);
    }

    println!("{}", s);
}

我初始化了一个可变的i32类型的s并绑定到5,然后我们以可变引用的方式将s传递给change,这时我们说change借用了s,只是借用,所有权没有发生转移,由于是可变引用,所以我们可以在change中修改借用的值。

下面我们再来聊一下trait,例如我们想实现一个接受Tcp连接的服务器,我们可以定义如下的trait。

use std::net::TcpStream;

pub trait HandleStream {
    fn handle_stream(&self, stream: TcpStream);
}

HandleStream trait告诉我们实现它需要定义handle_stream方法来处理每一个Tcp连接。

下面的Server结构体实现了其关联函数并实现了HandleStream trait。

use std::net::TcpListener;

#[derive(Debug)]
pub struct Server {
    l: TcpListener,
}

impl Server {
    pub fn new(l: TcpListener) -> Server {
        Server {
            l
        }
    }
}


impl HandleStream for Server {
    fn handle_stream(&self, mut stream: TcpStream) {
        ...
    }
}

在调用结构体的关联函数时,我们使用如下的语法:

use std::net::TcpListener;

let r = TcpListener::bind("127.0.0.1:1234");
match r {
    Err(e) => println!("{:?}", e),
    Ok(l) => {
        let svr = Server::new(l);
        ...
    },
}

Rust中的其他特性包括,泛型、生命周期、智能指针、裸指针等,此文不再介绍。

你可能感兴趣的:(Rust or Rest)