Rust v1.39 released - the programming language really unusual!

https://zhuanlan.zhihu.com/p/90612241

Today (2019-11-07) Rust has finally released the long-awaited release of v1.39, adds heavyweight async/ awaitkeyword support. Rust was released in 2015 as an official version of the star, using a few number of people, but it the fourth consecutive year in StackOverflow first launched the "favorite programming language" Year voting. Rust can beat what Python and many other languages successive four-year tyrants? Behind all this with what kind of secret? It distorted or moral evil of humanity?

Directed async/ awaitsupport, I recently tried Rust v1.39 in a small project. Rust deeply appreciate all the unique advantage after although only a small project, finished.

1. Never compromise - both performance and safety

For decades, C / C ++ has been the operating system kernel, browser, NGINX, Redis and other such critical performance (Performance Critical) preferred language software development. But the problem is also very obvious: null pointers, wild pointers, memory and other cross-border. Ranging from Segment Fault collapse, while it difficult to find a 0-day vulnerability.

Hopes developers do not make the slightest error memory write secure software is tantamount to nonsense. Therefore, since the 1990s, as the representative of the Java programming language, a series of automated memory management rise. By making the appropriate compromises and concessions in terms of performance, the introduction of GC and other mechanisms to achieve secure memory.

Since then, software development often faced with the dilemma: either for security and compromise in performance; or for the ultimate in performance sacrificing security. For example, when using Java to develop a network service, in order to achieve zero-copy forwarded, JVM's management byte[]has been unable to meet the requirements, without the need to use GC management Direct Buffer. Such as the use netty.io the reference count management ByteBuf , the use of cautious, otherwise very easily lead to memory leaks or memory early release, in particular, plus these errors will inevitably occur in case of exception handling logic branch. Since then, the choice of performance and security seems to become a "fish and bear's paw can not have both," the problem.

"Fish and bear's paw can not have both," the problem

Rust beginning in the design and set a goal to be taking into account the performance and security - we must have "underlying language" the same performance, but also have the security of "high-level language" (even more than in terms of security threads Java / C # and other languages ​​safer!). Such an uncompromising design philosophy, let Rust from birth on the doomed its extraordinary.

Rust taking into account the "low-level" and "high-level" language features

1.1 Memory Security

Rust is not a traditional garbage collector. In order to solve the memory security, Rust original ownership (Onwership) system and lease Checker (Borrow Checker).

For example, the following code

s Is a referent, it points to a string object in memory. When the code compiler will automatically generate a memory location referred to in object code destroyed scope range referent ends. That has a referent ownership of this memory object. Ownership can be transferred from one to another referent referent, i.e. ownership transfer (move). No matter how transfer, for an object in memory and only one referent get its ownership at the same time. It sounds a bit like a referent in C ++ auto_ptrsmart pointers, but in Rust referent more delicate and powerful.

b1/b2/b3看上去很像指针,在Rust中它们被称为租借(borrow)。

  • 其中b1是可变(mutable)租借,而b2/b3 属于不可变(immutable)租借。
  • 在同一时间内,一个referent可以有多个不可变租借或者一个可变租借,这点类似于读写锁(Readers-Writer lock);
  • 租借的作用域不能超过其referent作用域,以此防止野指针的出现。
  • referent和borrow都没有空值,因此杜绝了空指针。
  • 多个对象之间的borrow不能出现闭环(相互引用或者循环引用),极大地避免隐式内存泄漏。

关于referent和borrow的详细规则可见下图(原图地址)。

所有的这些规则都由编译器实现。简而言之,Rust通过编译期的规则实现了没有GC下的内存安全。

1.2 线程安全性

在内存安全的基础上,Rust更进一步地保证了线程安全性。

  • 默认情况下一个对象只能被拥有所有权的线程访问。
  • 实现了Send trait的数据类型所有权能够在多个线程间转移,但线程间不存在共享数据。
  • 实现了Sync trait的数据类型能够被多个线程同时访问,代表着该数据类型实现了线程间的同步操作。

需要说明的是,SendSync都属于编译器自动添加的标记(marker trait),并不需要开发人员实现。如果某个数据类型所有成员都是SendSync的,那么该数据类型也会被自动标记为SendSync。这样如果代码能够编译通过就自然而然地说明线程安全。

1.3 性能

benchmark show Rust with efficiency comparable to C / C ++, the mad child in terms of execution speed Golang / Java.

In TechEmpower mainstream Web performance tests conducted in the framework used by Microsoft employees Kim Rust open source framework built actix come out on top in a number of test scenarios.

Based on years of data, 70% of the vulnerabilities related to security and memory. Rust perfect solution to the dilemma of security and performance, but also make it a better choice to develop the underlying application. Currently, Intel , Microsoft and Linux are preparing to use Rust develop drivers and even the operating system kernel to improve the increasingly serious security problems.

In recent years CVE Memory security vulnerabilities scale drawing class

2. Compatibility - supports multiple programming paradigms

Rust is positioned in the beginning of the design for the multi-paradigm language (multi-paradigm language), draws a lot of success in other languages ​​on the basis of experience, user adoption is not limited to a particular paradigm.

2.1 Command style and functional style

Rust supports traditional command-style (imperative style) Code not be further described. Rust also learned a great deal ML camp style function (functional style) characteristic of many programming languages, such as pattern matching, not without side effects and variable method, Haskell type system, and a reverse type inference system characteristic trait. This makes Rust have the ultimate performance and delicate at the same time the underlying ability to control, with highly abstract expression.

More than 2.2 threading model

Use Rust multithreaded application development, also has a high degree of freedom.

  • Data shared between threads can be selected by a conventional operating system or synchronization primitives lockless data structure;
  • 也可以选择CSP(Communicating sequential processes)模型,就如Golang开发手册中总结的那样“Do not communicate by sharing memory; instead, share memory by communicating.”。
  • 还可以选择如Erlang那样的异步Actor模型

3 v1.39添加了async/await 异步编程支持

对于高并发I/O应用的开发,异步编程是首选项。传统的异步依赖于回调或者闭包,实现起来麻烦不说,代码可读性也差强人意。而Rust这次新添加的两个关键字类似于C#和Python中的async / await ,用户无需再依赖于回调或者闭包,用最自然的方式编写可读性佳的I/O操作代码,代码看上去和同步代码无异,而编译器将异步调用部分编译为状态机从而实现异步执行。这点感觉非常好。

4.个人使用体会

Rust学习曲线略为陡峭,突破新手期所需时间数倍于Golang/Python,如果有着C++和Haskell经验对这一阶段帮助很大。突破新手期后就一片坦途,不再像编写C/C++程序那样谨小慎微,而async/await关键字的引入大大方便了异步编程,很多时候感觉都在用C#/Java这样的高层语言编程一样--关注于业务和程序结构而不用去担心某个对象错误地释放。

需要吐槽的是各自为战的生态系统,为了熟练使用async/await关键字,关于future就需要知晓std::future::Future 和futures::future::Future, 而后者还分为0.1版本和0.3版本。又由于不同的库依赖于不同的future实现,所以还需要精通它们之间各种转换,开始时真有点头大╮(﹀_﹀)╭。

瑕不掩瑜。Rust可以说是目前最全面的编程语言。它既可以用于开发与硬件打交道的底层,也能用来开发对性能有极致要求的微服务,甚至还可以开发运行在浏览器中的WebAssembly网站。在拥有极致性能的同时又不失鲁棒性和安全性。编程风格自由且高效,能够被广泛的其它语言开发者(C++/Haskell/Python/Scala等)接纳。这些优势决定了Rust将会大放异彩!

最后来一段使用Seed开发的WebAssembly浏览器页面代码展示:

fn view(model: &Model) -> impl View<Msg> {
    let plural = if model.count == 1 {""} else {"s"};

    // Attrs, Style, Events, and children may be defined separately.
    let outer_style = style!{
            St::Display => "flex";
            St::FlexDirection => "column";
            St::TextAlign => "center"
    };

    div![ outer_style,
        h1![ "The Grand Total" ],
        div![
            style!{
                // Example of conditional logic in a style.
                St::Color => if model.count > 4 {"purple"} else {"gray"};
                St::Border => "2px solid #004422"; 
                St::Padding => unit!(20, px);
            },
            // We can use normal Rust code and comments in the view.
            h3![ format!("{} {}{} so far", model.count, model.what_we_count, plural) ],
            button![ simple_ev(Ev::Click, Msg::Increment), "+" ],
            button![ simple_ev(Ev::Click, Msg::Decrement), "-" ],

            // Optionally-displaying an element
            if model.count >= 10 { h2![ style!{St::Padding => px(50)}, "Nice!" ] } else { empty![] }
        ],
        success_level(model.count),  // Incorporating a separate component

        h3![ "What are we counting?" ],
        input![ attrs!{At::Value => model.what_we_count}, input_ev(Ev::Input, Msg::ChangeWWC) ]
    ]
}


#[wasm_bindgen(start)]
pub fn render() {
    seed::App::build(|_, _| Init::new(Model::default()), update, view)
        .build_and_start();
}

 

Guess you like

Origin www.cnblogs.com/dhcn/p/12075023.html