Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What are the generics and features of Rust

2025-03-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

This article mainly introduces the generics and characteristics of Rust, which has a certain reference value, interested friends can refer to, I hope you can learn a lot after reading this article, let the editor take you to understand it.

Rust is a new programming language of Mozilla, which focuses on security, especially concurrency security, and supports functional, imperative and generic programming paradigms. It is jointly developed by Brendan Eich (father of js), the leader of the web language, Dave Herman and Graydon Hoare of Mozilla.

Define generics in a function

This is a method for selecting and sorting integer numbers: an example

Fn max (array: & [i32])-> i32 {let mut max_index = 0; let mut i = 1; while i len () {if array [I] > Array [max _ index] {max_index = I;} I + = 1;} array [max _ index]} fn main () {let a = [2,4,6,3,1]; println! ("max = {}", max (& a);}

Running result:

Max = 6

This is a simple maximum program that can be used to process data of the i32 digital type, but not for data of the f64 type. By using generics, we can make this function available to all types. But in fact, not all data types can be compared to size, so the next piece of code is not used to run, but to describe the syntax format of function generics:

Example

Fn max (array: & [T])-> T {let mut max_index = 0; let mut i = 1; while i len () {if array [I] > array [max _ index] {max_index = I;} I + = 1;} array [max _ index]} structure and generics in enumerated classes

The Option and Result enumeration classes we learned earlier are generic.

Both structures and enumerated classes in Rust can implement generic mechanisms.

Struct Point {x: T, y: T}

This is a point coordinate structure, and T represents the numerical type that describes the point coordinates. We can use it like this:

Let p1 = Point {x: 1, y: 2}; let p2 = Point {x: 1, y: 2}

The type is not declared when it is used. The automatic type mechanism is used here, but type mismatches are not allowed as follows:

Let p = Point {x: 1, y: 2.0}

When x is bound to 1, T is set to i32, so the type of f64 is no longer allowed. If we want x and y to be represented by different data types, we can use two generic identifiers:

Struct Point {x: T1, y: T2}

Methods that represent generics in enumerated classes such as Option and Result:

Enum Option {Some (T), None,} enum Result {Ok (T), Err (E),}

Both structures and enumerated classes can define methods, so methods should also implement generic mechanisms, otherwise generic classes will not be effectively manipulated by methods.

Example

Struct Point {x: t, y: t,} impl Point {fn x (& self)-> & T {& self.x}} fn main () {let p = Point {x: 1, y: 2}; println! ("p.x = {}", p.x ());}

Running result:

P.X = 1

Note that there must be an impl keyword after it, because the T after it is an example. But we can also add methods to one of these generics:

Impl Point {fn x (& self)-> f64 {self.x}}

The generics of the impl block itself do not hinder the ability of its internal methods to be generic:

Impl Point {fn mixup (self, other: Point)-> Point {Point {x: self.x, y: other.y,}

The method mixup fuses the x of a Point point and the y of a Point point into a new point of type Point.

Characteristics

The concept of trait is close to the Interface in Java, but the two are not exactly the same. Features are similar to interfaces in that they are behavioral specifications that can be used to identify which classes have which methods.

Properties are represented in Rust as trait:

Trait Descriptive {fn describe (& self)-> String;}

Descriptive specifies that the implementer must have the describe (& self)-> String method.

We use it to implement a structure:

Example

Struct Person {name: String, age: U8} impl Descriptive for Person {fn describe (& self)-> String {format! ("{} {}", self.name, self.age)}}

The format is:

Impl for

Rust can implement multiple features in the same class, and only one can be implemented per impl block.

Default Properti

This is the difference between a property and an interface: an interface can only standardize a method, not define a method, but a property can define a method as the default method, and because it is "default", the object can redefine the method or not redefine the method using the default method:

Example

Trait Descriptive {fn describe (& self)-> String {String::from ("[Object]")} struct Person {name: String, age: U8} impl Descriptive for Person {fn describe (& self)-> String {format! ("{} {}", self.name, self.age)} fn main () {let cali = Person {name: String::from ("Cali"), age: 24} Println! ("{}", cali.describe ();}

Running result:

Cali 24

If we remove the contents of the impl Descriptive for Person block, the result of the run is:

[Object] property as parameter

In many cases, we need to pass a function as an argument, such as a callback function, setting button events, and so on. In Java, the function must be passed as an instance of the class implemented by the interface, and it can be achieved by passing property parameters in Rust:

Fn output (object: impl Descriptive) {println! ("{}", object.describe ());}

Any object that implements the Descriptive feature can be used as an argument to this function. There is no need for this function to know whether the incoming object has any other properties or methods. It only needs to know that it must have a Descriptive feature specification. Of course, other properties and methods cannot be used within this function.

Property parameters can also be implemented using this equivalent syntax:

Fn output (object: t) {println! ("{}", object.describe ();}

This is a syntactic sugar with a style similar to generics, which is useful when multiple parameter types are properties:

Fn output_two (arg1: t, arg2: t) {println! ("{}", arg1.describe ()); println! ("{}", arg2.describe ());}

If multiple properties are involved in the type representation of a property, it can be represented by a + symbol, for example:

Fn notify (item: impl Summary + Display) fn notify (item: t)

Note: when used only to represent types, it does not mean that it can be used in impl blocks.

Complex implementation relationships can be simplified using the where keyword, such as:

Fn some_function (t: t, u: U)

Can be simplified to:

Fn some_function (t: t, u: U)-> i32 where T: Display + Clone, U: Clone + Debug

After understanding this syntax, the "take the maximum" case in the generic chapter can be really implemented:

Example

Trait Comparable {fn compare (& self, object: & Self)-> i8;} fn max (array: & [T])-> & T {let mut max_index = 0; let mut i = 1; while i len () {if array [I]. If (& array [max _ index]) > 0 {max_index = I;} I + = 1 } & Array [max _ index]} impl Comparable for f64 {fn compare (& self, object: & F64)-> i8 {if & self > & object {1} else if & self = & object {0} else {- 1}} fn main () {let arr = [1.0,3.0,5.0,4.0,2.0]; println! ("maximum of arr is {}", max (& arr));}

Running result:

Maximum of arr is 5

Tip: since you need to declare that the second parameter of the compare function must be the same as the type that implements this feature, the Self keyword represents the current type (not the instance) itself.

Property as the return value

The format of the return value of the property is as follows:

Example

Fn person ()-> impl Descriptive {Person {name: String::from ("Cali"), age: 24}}

However, the return value of the property only accepts the object that implements the property as the return value, and all possible return value types in the same function must be exactly the same. For example, both structure An and structure B implement the feature Trait. The following function is incorrect:

Example

Fn some_function (bool bl)-> impl Descriptive {if bl {return A {};} else {return B {};}} conditional implementation

Impl is so powerful that we can use it to implement class methods. But for a generic class, sometimes we need to distinguish between the methods that the generic class to which it belongs has been implemented to determine which method it should implement next:

Struct A {} impl A {fn d (& self) {}}

This code declares that type A can effectively implement this impl block only if T has implemented the B and C features.

Thank you for reading this article carefully. I hope the article "what are the generics and features of Rust" shared by the editor will be helpful to you. At the same time, I also hope you will support us and pay attention to the industry information channel. More related knowledge is waiting for you to learn!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report