Author: Zhang Handong
A programming language is like a small universe, with various syntax concepts resembling stars scattered across the sky. For beginners, the confusion caused by these syntax concepts is similar to the bewilderment one feels when gazing at the starry sky. Fortunately, programming languages are created by humans, and the authors of these languages can be found. The source code of programming languages can also be viewed, and some good programming languages even provide rich documentation for reference and learning. Through this information, we can understand: why a language was born, what problems it aims to solve, and what design philosophy it follows. A good language is one that embodies a profound philosophy, being consistent in its internal and external aspects, having intentions and actions. The Rust language is such a programming language rich in philosophical connotations. By understanding the design philosophy that Rust adheres to, we can further grasp its syntax structure and programming concepts, systematically mastering the core of this language without getting lost in its complex syntax details.
Introduction
The world is changing, but not as quickly as you might imagine, so you need to observe carefully.
In July of this year, two events, neither too big nor too small, brought the Rust language into the public eye.
The first event occurred on July 4, when social media giant Facebook, along with 100 other industry leaders, announced plans to build the Libra project. The technical feature of this project is that it is built on blockchain technology and implemented in Rust.
Building on blockchain technology indicates that giants like Facebook believe the next generation of the financial world will be based on blockchain, as blockchain is the future of trust. The choice to use the Rust language to construct the blockchain infrastructure for Libra is because Rust can help developers achieve this trust. In Rust, We Trust.
The second event took place on July 18, when the Microsoft Security Response Center (MSRC) published an article stating: We need safer system programming languages. In a series of subsequent articles, they gradually explored why Microsoft believes Rust is currently the best choice in the industry.
This series of articles from Microsoft seems to attract more attention than Facebook’s Libra project. Everyone believes that Microsoft plans to use Rust, but in fact, Microsoft has already been using Rust internally, such as in the Azure IoT Edge project, which has been open-sourced on GitHub. Additionally, the popular web development framework actix-web in the Rust community was developed by Microsoft engineer Nikolay for internal use on the Azure platform.
The Microsoft Security Response Center is a department responsible for receiving and processing security-related vulnerability reports for Microsoft. As early as February of this year, an engineer from this department gave a talk at the BlueHat security conference in Israel titled “Microsoft: 70% of Security Vulnerabilities are Memory Safety Issues.” About six months later, the department’s official blog began to declare that Rust should become the best choice in the industry. This indicates that Microsoft arrived at this conclusion after careful consideration.
The February talk sparked a debate on Reddit. One mainstream viewpoint was that the issue was not with the programming language, but rather with the skill level of the coder, which led to such security problems. However, no programmer is omnipotent; the errors caught by the Rust compiler may exceed the programmer’s experience. Is it not necessary to wear a seatbelt just because there are better drivers on the road? No. We need a language like Rust, which has safety protections to prevent errors.
The two events mentioned above are just the visible influences that have brought Rust to your attention, but many companies have already adopted the Rust language. International giants like Amazon, Google, Facebook, and Dropbox, as well as domestic companies like Alibaba, Toutiao, Zhihu, Bilibili, PingCAP, and others.
So, why did these pioneers choose Rust? Are they all just fanatics for new technology? The answer to this question is what this article aims to convey.
1.1 Origins
The rise of any new technology is to solve a problem.
Since the birth of operating systems, mainstream system-level programming languages have evolved from assembly language to C++ over nearly 50 years, yet two major challenges remain:
-
It is difficult to write memory-safe code.
-
It is difficult to write thread-safe code.
The fundamental reason for these two challenges is that C/C++ are type-unsafe languages, and their weak memory management mechanisms lead to many common vulnerabilities. In fact, excellent languages like Ada emerged in the 1980s. Ada has many outstanding features: it can perform type checking at compile time, has deterministic memory management without GC, built-in safe concurrency models, no data races, and system-level hard real-time programming. However, its performance is indeed inferior compared to C/C++ of the same era. At that time, computing resources were scarce, and everyone pursued performance. Therefore, people were willing to sacrifice safety for performance. This is also the reason why C/C++ became popular.
Fast forward to 2006, Graydon Hoare (abbreviated as GH), who calls himself a “professional programming language engineer,” began developing a programming language called Rust.
What is a “professional programming language engineer”? In GH’s own words, a professional programming language engineer’s daily work involves developing compilers and toolsets for other languages, but not participating in the design of these languages themselves. Naturally, GH conceived the idea of developing his own language, which is Rust.
The name “Rust” reflects GH’s expectations for this language. In nature, there is a fungus called Rust Fungi, which parasitizes plants, causing diseases, and is known as one of the most terrifying ecological diseases of this century. This fungus has a very strong vitality, capable of producing up to five types of spores during its life cycle, and these five life forms can transform into each other. If we describe this feature in software terms, it means “extreme robustness.” Recall the shape of Rust’s logo (as shown in Figure 1-1), which has five circles corresponding to the five life forms of the rust fungus, suggesting that the robustness of the Rust language is also extremely strong. “Rust” also means “iron rust,” hinting at its “bare metal” nature, representing Rust’s capability as a system-level programming language with direct access to underlying hardware. Additionally, the combination of the letters in “Rust” also blends “Trust” and “Robust,” implying “trust” and “robustness.” Therefore, “Rust” is indeed a good name. It has been proven that the Rust language is not just well-named.
Figure 1-1:Rust Language Logo
GH believes that the future internet will not only focus on performance but will also pay great attention to safety and concurrency. The world’s preference for the design of C and C++ is gradually changing. In fact, many excellent languages emerged in the 1970s and 1980s, possessing many excellent features, but their memory models were very simplistic and could not guarantee sufficient safety. For example, while Ada’s dynamic memory management is a high-standard safety design, it still caused significant safety incidents (in the 1990s, the failure of the European Space Agency’s Ariane 5 rocket launch was due to an overflow when Ada converted a 64-bit floating-point number to a 16-bit unsigned integer).
Therefore, GH’s expectations for this language are as follows:
-
It must be safer and less prone to crashes, especially when operating on memory, which is particularly important.
-
It should not require a system with garbage collection, and it cannot introduce performance burdens for memory safety.
-
It should not be a language with just one main feature, but should possess a wide range of features that are consistent with each other. These features can work well together, making the language easier to write, maintain, and debug, allowing programmers to write safer and more efficient code.
In summary, it is a language that can provide high development efficiency, easy maintenance of code, performance comparable to C/C++, and ensure safety. It is precisely because GH established this viewpoint as a foundation that today’s Rust has become a modern system-level programming language that simultaneously pursues safety, concurrency, and performance.
GH indeed identified the essential problem—since the development of the internet, performance issues are no longer its bottleneck; safety issues are the “chronic disease” hindering its development. But why can Rust solve this problem?
1.2 Design Philosophy
To achieve its goals, the Rust language adheres to three design philosophies:
-
Memory Safety
-
Zero-Cost Abstraction
-
Practicality
In other words, all syntax features in the Rust language are designed around these three philosophies, which is also the basis for Rust’s consistency.
1.2.1 Memory Safety
Safety is the top priority that Rust must guarantee. If safety cannot be ensured, then Rust has no reason to exist. How does the Rust language design to ensure safety?
Modern programming languages have already developed to the stage of “program as type proof,” and type systems have basically become standard in major programming languages, especially in the new programming languages that have emerged in recent years. Type systems provide the following benefits:
-
Allow the compiler to detect meaningless or even invalid code, exposing hidden errors in the program.
-
Provide meaningful type information to the compiler, helping to optimize code.
-
Enhance code readability, clearly expressing the developer’s intentions.
-
Provide a certain degree of high-level abstraction, improving development efficiency.
Generally speaking, as long as a language ensures type safety, it can be considered a safe language. In simple terms, type safety means that the type system can guarantee that the program’s behavior is meaningful and error-free. For example, the type system of C/C++ is not type-safe because it does not constrain meaningless behaviors. A simple example is array out-of-bounds access, which is not checked in C/C++, leading to behaviors outside the language specification, known as Undefined Behavior. These undefined behaviors are precisely the breeding ground for vulnerabilities. Therefore, languages like C/C++ are type-unsafe languages.
If Rust wants to ensure memory safety, the first thing it must do is ensure type safety.
Among various programming languages, OCaml and Haskell are recognized as paradigms of type safety. Their type systems not only have strong theoretical backing but have also been tested in practical production environments. Therefore, the Rust language borrows from their type systems to ensure type safety, especially Haskell, where you can see more of Haskell’s type system reflected in Rust.
However, directly using Haskell’s type system cannot solve the memory safety problem. The role of the type system is to define the types of values and expressions in the programming language, classify them, assign them different behaviors, and guide how they interact. Haskell is a pure functional programming language, and its type system mainly serves to carry its “purely functional” philosophy, reflecting category theory. In contrast, Rust’s type system must carry its “memory safety” philosophy. Therefore, a safe memory management model must also be established and expressed through the type system to ensure memory safety.
So, what is memory safety? In simple terms, it means that there will be no memory access errors.
Memory errors occur only when a program accesses undefined memory. Generally, the following situations can lead to memory errors:
-
Dereferencing a null pointer.
-
Using uninitialized memory.
-
Using after free, which is dereferencing a dangling pointer.
-
Buffer overflow, such as array out-of-bounds access.
-
Illegally freeing already freed pointers or unallocated pointers, which is known as double freeing.
These situations lead to memory errors because they all access undefined memory. To ensure memory safety, the Rust language establishes a strict safe memory management model:
-
Ownership system. Every allocated memory has a pointer that exclusively owns it. Only when that pointer is destroyed can the corresponding memory be released.
-
Borrowing and lifetimes. Every variable has its lifetime, and once it exceeds its lifetime, the variable will be automatically released. If it is borrowed, it can prevent dangling pointers by marking lifetime parameters for the compiler to check.
The ownership system also includes the RAII mechanism borrowed from modern C++, which is the cornerstone of Rust’s ability to manage memory safely without garbage collection.
After establishing a safe memory management model, it can be expressed through the type system. Rust borrows the following features from Haskell’s type system:
-
No null pointers
-
Default immutability
-
Expressions
-
Higher-order functions
-
Algebraic data types
-
Pattern matching
-
Generics
-
Traits and associated types
-
Local type inference
To achieve memory safety, Rust also possesses the following unique features:
-
Affine types, which express the Move semantics in Rust’s ownership.
-
Borrowing and lifetimes.
With the power of the type system, the Rust compiler can check types at compile time to see if they meet the safe memory model, effectively preventing undefined behaviors from occurring.
The internal causes of memory safety bugs and concurrency safety bugs are the same; both are caused by improper memory access. Similarly, by leveraging the powerful type system with ownership, Rust also solves concurrency safety issues. The Rust compiler will perform static checks to analyze and check all data race issues in multithreaded concurrent code at compile time.
1.2.2 Zero-Cost Abstraction
In addition to safety, Rust also pursues efficient development and performance.
If a programming language wants to achieve efficient development, it must have a certain level of abstraction capability. The most representative language regarding abstraction capability is Ruby. The comparison of Ruby code and Rust code is illustrated in Code Listing 1-1.
Code Listing 1-1:Comparison of Ruby and Rust Code
In Code Listing 1-1, lines 2 and 3 are Ruby code, representing “output ‘Hello Ruby’ 5 times” and “from now on two days later,” respectively. The abstraction capability of the code is very close to natural language. Now looking at lines 5 and 6 of the Rust code, its abstraction capability is on par with that of Ruby.
However, Ruby’s abstraction capability is entirely achieved at the cost of performance.Rust’s abstraction is zero-cost; it incurs no runtime performance overhead, as everything is completed at compile time. The abstract code that iterates 5 times in Code Listing 1-1 will be expanded into low-level code close to handwritten assembly code at compile time, so there is no performance overhead at runtime due to interpreting this layer of abstraction. For a system-level programming language, zero-cost at runtime is very important. Rust achieves this through its foundations of generics and traits.
1.2.3 Practicality
How do we evaluate the practicality of a programming language? In fact, there is no unified standard, but it can be assessed from the following three aspects:
-
Practicality: It must be applicable to the development of industrial-grade products and easy to learn and use.
-
Beneficiality: It should have a positive effect or impact on the industry.
-
Stability: The language itself must be stable. When solving the same problem, it should not yield random results due to different users.
So how does the Rust language perform in these three aspects?
Practicality
Rust is well-prepared for developing industrial-grade products.
To ensure safety, Rust introduces a powerful type system and ownership system, which not only guarantees memory safety but also ensures concurrency safety without sacrificing performance.
To support hard real-time systems, Rust borrows deterministic destruction, RAII, and smart pointers from C++ to automate and deterministically manage memory, thus avoiding the introduction of garbage collection, which would lead to the “world pausing” problem. Although these aspects are borrowed from C++, they are simpler to use than in C++.
To ensure program robustness, Rust reexamines the error handling mechanism. In daily development, there are generally three types of abnormal situations: failures, errors, and exceptions. However, in procedural languages like C, developers can only handle errors through return values, goto statements, etc., and there is no unified error handling mechanism. While higher-level languages like C++ and Java introduce exception handling mechanisms, they do not provide specific syntax to effectively distinguish normal logic from error logic, leading developers to treat all abnormal situations as exceptions, which is not conducive to developing robust systems. Additionally, exception handling incurs significant performance overhead.
The Rust language provides specialized handling methods for these three types of abnormal situations, allowing developers to choose appropriately.
-
For failures, assertion tools can be used.
-
For errors, Rust provides a layered error handling method based on return values, such as Option for handling potential null values, and Result for handling errors that can be reasonably resolved and need to be propagated.
-
For exceptions, Rust treats them as problems that cannot be reasonably resolved and provides a thread panic mechanism, allowing threads to exit safely when exceptions occur.
Through such exquisite design, developers can handle abnormal situations more granularly, ultimately writing more robust systems.
To integrate well with existing ecosystems, Rust supports a very convenient and zero-cost FFI mechanism, compatible with C-ABI, and from a language architecture perspective, Rust is divided into Safe Rust and Unsafe Rust. Unsafe Rust is specifically for interacting with external systems, such as operating system kernels. This division is made because the Rust compiler’s checks and tracking have limitations; it cannot check the safety status of external language interfaces, so it relies on developers to ensure safety. Unsafe Rust provides the unsafe keyword and unsafe blocks, explicitly distinguishing safe code from unsafe code that accesses external interfaces, also facilitating debugging for developers. Safe Rust indicates that developers trust the compiler to guarantee safety at compile time, while Unsafe Rust indicates that the compiler trusts developers to ensure safety.
Wherever there are people, there are bugs. The Rust language, through exquisite design, hands over all parts that machines can check and control to the compiler, while leaving parts that machines cannot control to developers. Safe Rust ensures that the compiler maximizes memory safety at compile time, preventing undefined behaviors from occurring. Unsafe Rust serves as a reminder to developers that the code being developed may lead to undefined behavior, so caution is advised! Humans and the compiler share the same “safety model,” trusting each other and harmonizing to maximize the elimination of bugs caused by humans.
To facilitate collaboration among developers, Rust provides a very user-friendly package manager, Cargo. Rust code is compiled and distributed in packages (crates), and Cargo offers many commands to help developers create, build, distribute, and manage their packages. Cargo also provides a plugin mechanism, allowing developers to write custom plugins to meet additional needs. For example, the official rustfmt and clippy tools can be used for automatic code formatting and discovering “bad smells” in code, respectively. Additionally, the rustfix tool can even help developers automatically fix erroneous code based on compiler suggestions. Cargo also embraces the open-source community and Git, supporting one-click publishing of written packages to the crates.io website for others to use.
To help developers learn Rust, the official Rust team has made the following efforts:
-
Established a dedicated community working group to write the official Rust Book and various documents of different depths, such as compiler documentation and the nomicon book. They even organize free community teaching activities like Rust Bridge, strongly encouraging community blogging, etc.
-
The Rust language documentation supports Markdown format, so the documentation of the Rust standard library is rich in expressiveness. Many third-party packages in the ecosystem also benefit from enhanced documentation expressiveness.
-
Provided a very user-friendly online Playground tool for developers to learn, use, and share code.
-
The Rust language has long achieved self-hosting, making it easy for learners to understand its internal mechanisms by reading the source code and even contributing.
-
The Rust core team is continuously improving Rust, striving to enhance its friendliness and significantly reduce the cognitive burden on beginners, easing the learning curve. For example, the introduction of the NLL feature improves the borrowing check system, allowing developers to write more intuitive code.
-
Although many type system-related features are borrowed from Haskell, the Rust team intentionally avoids academic jargon when designing and promoting language features, making Rust’s concepts more accessible.
-
Providing support for mixed programming paradigms based on the type system, offering powerful and concise abstraction capabilities, greatly enhancing developers’ development efficiency. Providing a stricter and smarter compiler. Based on the type system, the compiler can strictly check hidden issues in the code. The Rust official team is also continuously optimizing the compiler’s diagnostic information, making it easier for developers to locate errors and quickly understand the reasons for errors.
-
Although the Rust official team has made many efforts, a significant portion of developers still find the learning curve of Rust quite steep. The most criticized aspect is the current borrowing check system. This is actually because the design of the Rust language integrates features from many languages, while most developers today are only proficient in one language and may not be familiar with the features of others. C language developers may be familiar with low-level memory management but may not be familiar with C++’s RAII mechanism; even if they are familiar with C++, they may not understand Haskell’s type system; and even if they are familiar with Haskell’s type system, they may not understand low-level memory management mechanisms. Not to mention developers of object-oriented languages like Java, Ruby, and Python, which have built-in garbage collection.
To address this issue, one can start learning Rust from the following points:
-
Maintain a beginner’s mindset. When facing difficult concepts in Rust, do not rush to apply experiences from other languages; instead, understand the reasons behind Rust’s design philosophy and seek its internal consistency.
-
Learn concepts before practicing. Many traditional language developers jump straight into writing code when learning Rust, only to stumble and fail to compile. What seems intuitive may fail to compile due to borrowing checks. This is because the Rust compiler detects hidden errors in the code you wrote, which you may not have noticed. Therefore, it is not that Rust has a steep learning curve, but rather that the method of jumping straight into coding is flawed.
-
Consider the compiler as a friend. Do not ignore the diagnostic information from the Rust compiler; in most cases, these diagnostics clearly explain the reasons for errors. This information can help you learn Rust and correct your misconceptions.
As the saying goes, adversity is also an opportunity. It is precisely because Rust has these characteristics that the process of learning Rust is also a process of self-improvement, helping you become a better programmer.
Beneficiality and Stability
The Rust language solves the problems of memory safety and concurrency safety, which can greatly enhance software quality. The birth of Rust provides the industry with a better choice beyond C and C++. Because Rust is a language that values safety, concurrency, and performance, it can be used in embedded systems, operating systems, network services, and other low-level systems, but it is not limited to this; it can also be used to develop upper-level web applications, game engines, and machine learning, and even develop frontend components based on WebAssembly technology. Due to its high safety and performance comparable to C/C++, Rust is also applied in new frontier fields such as blockchain technology.
It is evident that the birth of Rust has brought very positive impacts to the industry. Since the release of version 1.0, Rust has entered a stable phase. Although it continues to improve and release new features, the core of Rust remains unchanged.
In summary, Rust has excelled in practicality, beneficiality, and stability, making its practicality beyond doubt.
1.3 Current Status and Future
Since the release of Rust 1.0 in 2015, the Rust language has been widely adopted by major companies and in various fields. Every year, the Rust community gathers to formulate a roadmap and plan the future development of Rust. In 2018, the Rust team launched a new major version (edition) plan:
-
Rust 2015 edition, which includes semantic versions from Rust 1.0 to 1.30. The goal is to make Rust more stable.
-
Rust 2018 edition, Rust 1.31 will be the first semantic version of the Rust 2018 edition. The goal is to further bring Rust to production-level.
This major version and semantic version are orthogonal. The significance of the major version is to facilitate the evolution of Rust itself. For example, if a new keyword like try is to be introduced in Rust, but only the semantic version dimension exists, the new keyword may disrupt the existing Rust ecosystem. Therefore, a major version is needed to introduce the try keyword in the Rust 2018 edition. Developers choosing “edition=2018” indicates their acceptance of this internal change in Rust and the new keyword try. The major version upgrade only changes superficial syntax features; the core concepts of Rust will not change. If you compile individual files using rustc, you need to add the “–edition 2018” parameter.
The Rust compiler can conveniently manage version compatibility:
-
Rust 2015 and Rust 2018 are compatible with each other.
-
The Rust compiler knows how to compile both versions, just as javac knows how to compile Java 9 and Java 10, and gcc and clang know how to handle C++ 14 and C++ 17.
-
Rust 2018 can depend on libraries from Rust 2015, and vice versa.
-
The Rust 2015 version is not frozen.
Additionally, major versions may be released every three years, with the next release expected in 2021. However, the Rust team reserves the right to modify this.
1.3.1 Language Architecture
To facilitate learning, the author has organized the hierarchical structure of Rust language concepts, as shown in Figure 1-2.
Figure 1-2: Hierarchical Structure of Concepts in Rust
Figure 1-2 divides the concepts in the Rust language into four levels. The lowest level is the safe memory management layer, which mainly involves concepts related to memory management. The second-to-last level is the type system layer, which serves as a bridge. The type system layer carries the semantics of the ownership system and mixed programming paradigms of the upper layer, endowing the Rust language with high-level abstraction capabilities and safety. At the same time, it retains control over low-level code execution, data representation, and memory allocation.
For developers, it is sufficient to master the type system, ownership system, and mixed programming paradigms without worrying about whether the underlying memory is safe, as the compiler and type system help manage it. Under this language architecture, humans and the compiler share the same “mental model,” greatly ensuring the safety and robustness of the system.
1.3.2 Open Source Community
The Rust language itself, as an open-source project, is also a shining gem in modern open-source software.
All languages that emerged before Rust were merely for commercial development, but Rust changed this situation. For the Rust language, the Rust open-source community is also part of the language. At the same time, the Rust language belongs to the community.
The Rust team consists of both Mozilla and non-Mozilla members, and to date, the number of contributors to the Rust project has exceeded 1,900. The Rust team is divided into core groups and other domain working groups. In line with the goals of Rust 2018, the Rust team has been divided into embedded working groups, CLI working groups, networking working groups, and WebAssembly working groups, as well as ecosystem working groups and community working groups.
Designs in these domains will first go through an RFC process, while changes that do not require an RFC process can simply submit a Pull Request to the Rust project repository. All processes are transparent to the community, and contributors can participate in reviews, although the final decision-making power rests with the core group and relevant domain working groups.
The Rust team maintains three release branches:Stable, Beta, and Nightly. The stable and beta versions are released every six weeks. Language features or standard library features marked as unstable and feature-gated can only be used in the nightly version.
1.3.3 Development Prospects
According to community popularity survey reports, as of July 2018, the total number of PRs for the Rust language ranked 15th in GitHub’s Octoverse report, showing an upward trend. In terms of active projects, there are a total of 2,604 active projects in Rust.
Currently, in the commercial sector, the number of heavyweight commercial users of Rust is growing rapidly, including:
-
Amazon, using Rust as a building tool.
-
Atlassian, using Rust in the backend.
-
Dropbox, using Rust in both frontend and backend.
-
Facebook, rewriting its source management tool in Rust.
-
Google, partially using Rust in the Fuchsia project.
-
Microsoft, partially using Rust in the Azure IoT network.
-
npm, using Rust in its core services.
-
RedHat, using Rust to create a new storage system.
-
Reddit, using Rust to handle comments.
-
Twitter, using Rust in its building team.
In addition to the companies listed above, many others can be found on the official Rust friends page, including Baidu, Samsung, Mozilla, etc. Rust covers fields such as databases, gaming, cloud computing, security, science, healthcare, and blockchain, with an increasing number of related job positions. The future of Rust is becoming clearer, and it will have great potential.
1.4 How Rust Code Executes
From its inception, Rust has considered platform portability issues. Typically, the compilation phase is divided into frontend and backend parts. As a compiled language, Rust is also divided this way. The Rust compiler is a compilation frontend, responsible for lexical analysis, syntax analysis, type checking, generating intermediate code, and performing optimizations independent of the target machine. By using LLVM as the backend code generation framework, Rust can leverage LLVM’s compatibility with multiple target machines to achieve cross-platform compilation and optimization. Therefore, when using Rust, users generally do not need to consider the specific properties of each target machine platform, essentially achieving the goal of “write once, run anywhere.” When users need to handle cross-platform compatibility issues, Rust also provides many aids in the form of third-party crates.
Rust source code undergoes tokenization and parsing to generate an AST (Abstract Syntax Tree). The AST is then further simplified into HIR (High-level IR) to facilitate type checking by the compiler. HIR will be further compiled into MIR (Middle IR), which is an intermediate representation introduced in Rust 1.12, primarily for the following purposes:
-
Shortening compilation time. MIR can help achieve incremental compilation; when you modify the code and recompile, the compiler only calculates the changed parts, thus shortening compilation time.
-
Shortening execution time. MIR can implement finer-grained optimizations before LLVM compilation, as relying solely on LLVM’s optimization granularity is too coarse, and Rust cannot control it. Introducing MIR increases optimization space.
-
More precise type checking. MIR will help achieve more flexible borrowing checks, thus enhancing the Rust user experience.
Ultimately, MIR will be translated into LLVM IR and then processed by LLVM to compile into target machine code that can run on various platforms.
1.5 Summary
The emergence of Rust seems coincidental, but it is actually inevitable. The future internet’s emphasis on safety and high performance is an inevitable trend. GH recognized this, and Mozilla did too, which is why they could come together to create Rust.
Since its birth in 2006, Rust has had a clear goal—to pursue safety, concurrency, and high performance as a modern system-level programming language. To achieve this goal, the Rust language adheres to three major design philosophies: memory safety, zero-cost abstraction, and practicality. With the help of a modern type system, Rust is endowed with high-level abstraction capabilities while retaining control over low-level operations. Developers and the Rust compiler share the same “mental model,” trusting and collaborating with each other to maximize the safety and robustness of the system. Another point that distinguishes the Rust language from traditional languages is that it regards the open-source community as part of the language. Rust itself is a model open-source project, which is very worthy of study.
Some have called Rust “The New C,” and I wholeheartedly agree; Rust is a language that opens the door to a new era. However, Rust may not have a killer application that suddenly emerges to lead a trend in a particular field like other languages. The way Rust changes the world can be aptly described by an ancient poem: “Good rain knows its season; it falls when spring arrives. It enters the night with the wind, moistening things silently.”
Rust is not a silver bullet; it does not pursue perfection. It seeks better solutions to problems in the old world built on C and C++.
So, are you ready to learn Rust?
(This article is excerpted from Chapter 1 of “The Way of Rust Programming”)
Author Introduction: Zhang Handong, born in the 1980s, is a senior software engineer, independent corporate consultant, technical writer, and translator, as well as an entrepreneur. He enjoys reading, writing, and researching technology, learning paths, and cognitive thinking. He has worked in the internet industry for over a decade, serving in e-commerce, social gaming, advertising, and crowdfunding sectors. As an independent corporate consultant, he has provided consulting services for companies like Cisco, Ping An Technology, and SanDisk. He began learning the Rust language in 2015 and has participated in the management and operation of the domestic Rust community. In 2018, he created the “Rust Daily” channel, which is well-loved by Rustaceans. He has crafted the essential first lesson for beginners in Rust: Zhihu Live “How to Systematically Learn Rust Language,” which received five-star reviews. In early 2019, he published the technical bestseller “The Way of Rust Programming,” which has been well received. He is currently exploring the fields of cognitive education and makers, striving to build his own educational brand.
Book Links:
https://item.jd.com/12479415.html
https://www.amazon.cn/dp/B07NW95M76/
https://github.com/ZhangHanDong/tao-of-rust-codes
Click to see less bugs👇