rust面向对象
目录 (Table of Contents)
🦀 Introduction🦀 Arithmetic Operators🦀 Comparison Operators🦀 Logical Operators🦀 Bitwise Operators🦀 Compound Assignment Operators🦀 Operator Overloading🦀 XOR and Bitwise Operators Truth Table🦀 Problem 1: Single Number🦀 Method and Associated Functions🦀 Solution Using an Associated Function🦀 Problem 2: Number of Steps to Reduce a Number to Zero🦀 Conclusion
🦀 介绍 🦀 算术运算符 🦀 比较运算符 🦀 逻辑运算符 🦀 位运算符 🦀 复合赋值运算符 🦀 运算符重载 🦀 XOR和位运算符真值表 🦀 问题1:单一号码 🦀 的方法和相关联的功能 🦀 解决方案使用相关联的功能 🦀 问题2:数数减少到零的步骤结论
介绍 (Introduction)
Operators tell the compiler or interpreter to perform a specific mathematical, relational, or logical operation. Many programming languages make use of similar operator symbols.
运算符告诉编译器或解释器执行特定的数学,关系或逻辑运算。 许多编程语言都使用类似的运算符。
We will go through the important arithmetic, relational, and logical operators available in Rust and we will compare them to Python.
我们将介绍Rust中可用的重要算术,关系和逻辑运算符,并将它们与Python进行比较。
We will learn the differences between methods and associated functions.
我们将学习方法与关联函数之间的差异。
We also convert two simple Python codes to Rust codes to learn more about Rust programming.
我们还将两个简单的Python代码转换为Rust代码,以了解有关Rust编程的更多信息。
Let’s get started!
让我们开始吧!
算术运算符 (Arithmetic Operators)
Python and Rust share the same arithmetic symbols as you see in the above table. Rust calls %
as Remainder instead of the Modulus.
Python和Rust共享与上表相同的算术符号。 Rust将%
称为余数而不是模量 。
We will cover “Rust Overloading Trait” later in the Operator Overloading.
我们将在稍后的“ 操作员重载 ”中介绍“Rust重载特征”。
Output:
输出:
a: 20, b: 20+1=21, c: 20-2=18, d: 20*3=60, e: 20/4=5, f: 20%3=2
In Rust, you can’t use different data types in an operation. For example, if you try to subtract an unsigned integer from a signed integer, it will fail:
在Rust中,您不能在操作中使用不同的数据 类型 。 例如,如果尝试从有符号整数中减去无符号 整数 ,它将失败:
// This will fail.
fn main() {
let a = 8u8;
let b = 2i32;
println!("{}", a - b);
}
Rust uses the as
keyword to cast between primitive types. Please read more about the cast in Rust here.
Rust使用as
关键字在原始类型之间进行转换。 请在此处详细了解Rust中的演员表。
Output:
输出:
6
指数 (Exponent)
Python uses the **
symbol for exponents:
Python使用**
符号表示指数:
Output:
输出:
2^3 is 8
3^3 is 27
3^3.2 is 33.63473536961897
Rust uses pow
, powi
, and powf
depends on the type:
Rust使用pow
, powi
和powf
取决于类型:
Output:
输出:
2 ^ 3 in Rust: 2u8.pow(3) = 8
2 ^ 3 in Rust: 2i32.pow(3) is 8
3.0 ^ 3 in Rust: 3.0f32.powi(3) 27
3.0 ^ 3.2 in Rust: 3.0_f32.powf(3.2) is 33.63474
a = 3, a ^ 3 in Rust: i32::pow(a,3) = 27
b = 3.1, b ^ 3 in Rust: f64::powi(b, 3) = 29.791000000000004
b = 3.1, b ^ PI in Rust: std::f64::consts::PI) = 34.96699308140392
In Rust, you can annotate a number type like 2u8
or 2_u8
. u8
is an unsigned 8-bit integer type and i32
is a signed integer type.
在Rust中,您可以注释数字类型,例如2u8
或2_u8
。 u8
是无符号的8位整数类型,而i32
是有符号的整数类型 。
i32
and f32
have a group of built-in methods. All the integer types u8
, u16
, u32
, u64
, u128
, i16
,i32
, i64
, i128
, isize
, and usize
have the pow
method.
i32
和f32
具有一组内置方法。 所有整数类型u8
, u16
, u32
, u64
, u128
, i16
, i32
, i64
, i128
, isize
和usize
有pow
的方法。
pub fn pow(self, exp: u32) -> i32
The above definition tells you that using the pow
method raises self to the power of exp
(which is u32
) and returns i32
(a signed integer).
上述定义告诉你,使用pow
方法提高自我的力量exp
(这是u32
),并返回i32
(有符号整数)。
The floating-point types, f32
and f64
have powi
and powf
methods.
powi
raises a number to an integer power and powf
raises a number to a floating-point power.
powi
将数字提高为整数幂,而powf
将数字提高为浮点幂。
pub fn powi(self, n: i32) -> f32
pub fn powf(self, n: f32) -> f32
楼层部 (Floor Division)
In Python, we use //
to find a floor division. For example 5//2=2
.
在Python中,我们使用//
查找底数分割。 例如5//2=2
。
Output:
输出:
5 // 2 is 2
-5 // 2 is -3
Rust’s floating-point types use the floor method.
Output:
输出:
2
-3
比较运算符 (Comparison Operators)
Python and Rust share the same symbols for all the comparison operators.
Python和Rust为所有比较运算符共享相同的符号。
Output:
输出:
a: 7, b: 4,
c: 7 == 4 is false,
d: 7 != 4 is true,
e: 7<4 is false,
f: 7>4 is true,
g: 7<=7 is true,
h: 7>=7 is true
逻辑运算符 (Logical Operators)
Rust logical operator symbols are different from Python ones.
Rust逻辑运算符与Python运算符不同。
Output:
输出:
a: true, b: false,
c: !true is false,
d: true && false is false,
e: true || false is true
按位运算符 (Bitwise Operators)
All the Rust and Python Bitwise operators share the same bitwise operator symbols except the bitwise NOT.
除按位NOT之外,所有Rust和Python按位运算符都共享相同的按位运算符。
Output:
输出:
a: 1, b: 2,
c: 1 & 2 is 0,
d: 1 | 2 is 3,
e: 1 ^ 2 is 3,
f: 1 << 2 is 4,
f2: 1 << 4 is 16,
g: 1 >> 2 is 0,
g2: 1 >> 2 is 1,
h: !1 = -2
Bitwise negation !1
returns -2
. Rust uses the two’s complement to find the bitwise negation for signed types. Rust’s signed integer types are called the signed two’s complement integer types.
按位取反 !1
返回-2
。 Rust使用二进制补码来查找有符号类型的按位求反。 Rust的有符号整数类型称为有符号二进制补码整数类型 。
You can use 1 << n
to find out exponents of 2.
您可以使用1 << n
找出2的指数。
Output:
输出:
2 ^ 3 = 8
2 ^ 4 = 16
2 ^ 5 = 32
复合分配运算符 (Compound Assignment Operators)
All the Rust and Python compound assignment operators have the same symbols except Rust doesn’t have the equivalence of power assignment **=
, and floor division assignment //=
.
所有Rust和Python复合赋值运算符都具有相同的符号,不同之处在于Rust不具有等效的功率分配**=
和下层划分的分配//=
。
Output:
输出:
a is 2
1: a += 5 is 7
2: a -= 2 is 5
3: a *= 5 is 25
4: a /= 2 is 12
5: a %= 5 is 2
6: a &= 2 is 2
7: a |= 5 is 7
8: a ^= 2 is 5
9: a <<= 1 is 10
10: a >>= 2 is 2
运算符重载 (Operator Overloading)
Operator overloading is to specify more than one definition for an operator in the same scope. Python and Rust provide operator overloading. You can find Rust overloadable operators in the standard library ops module.
运算符重载是为同一范围内的运算符指定多个定义。 Python和Rust提供了运算符重载。 您可以在标准库ops模块中找到Rust重载运算符。
Output:
输出:
Point { x: 3, y: 3 }
XOR和按位运算符真值表 (XOR and Bitwise Operators Truth Table)
As we saw previously, Python and Rust use the same symbols for bitwise symbols AND
, OR
, and XOR
.
如前所述,Python和Rust将相同的符号用于按位符号AND
, OR
和XOR
。
&
is the bitwise AND
, |
is the bitwise OR
, and ^
is the bitwise XOR (exclusive OR). You can see the truth table and the Venn diagram below.
&
是按位AND
, |
是按位OR
, ^
是按位XOR(异或)。 您可以在下面看到真值表和维恩图。
When you use XOR
with even numbers of the same number, the output is always 0.
当您将XOR
与相同数字的偶数一起使用时,输出始终为0。
In Rust, you can use {:#b}
to print binary.
在Rust中,您可以使用{:#b}
打印binary 。
Output:
输出:
0 ^ 0 = 0
Binary: 0 ^ 0 = 0b0
1 ^ 1 = 0
Binary: 1 ^ 1 = 0b0
2 ^ 2 = 0
Binary: 2 ^ 2 = 0b0
3 ^ 5 ^ 3 ^ 5 = 0
Binary: 3 ^ 5 ^ 3 ^ 5 = 0b0
1 ^ 1 ^ 1 = 1
Binary: 1 ^ 1 ^ 1 = 0b1
1 ^ 1 ^ 5 = 5
Binary: 1 ^ 1 ^ 5 = 0b101
You can find Python code here.
您可以在此处找到Python代码。
问题1:单数 (Problem 1: Single Number)
We are going to use this XOR
to solve the LeetCoder problem called Single number.
我们将使用此XOR
解决称为单数的LeetCoder问题。
In this problem, an array input has a pair of numbers except one, for example [1, 1, 5, 5, 2]
. You need to find a sing number from this array and in this case the output should be 2
.
在此问题中,数组输入具有一对数字,但一个除外,例如[1, 1, 5, 5, 2]
。 您需要从该数组中找到一个单号,在这种情况下,输出应为2
。
More example: When the input is [2, 2, 1]
, the output should be 1
. When an input is [4, 1, 2, 1, 2]
the output should be 4
.
更多示例:输入为[2, 2, 1]
,输出应为1
。 当输入为[4, 1, 2, 1, 2]
,输出应为4
。
This is a good example to use the XOR
operator.
这是使用XOR
运算符的一个很好的例子。
Python解决方案 (Python Solution)
We briefly go through the Python solution to see how the problem was solved.
我们简要地介绍了Python解决方案,以了解如何解决该问题。
Output:
输出:
4
Line 1: We use Python typing
which is introduced from v3.5.
第1行:我们使用从v3.5引入的 Python typing
。
Line 3–4: After importing List
, we create a class called Solution
and method called singleNumber
.
第3至4行:导入List
,我们创建一个名为Solution
的类和一个名为singleNumber
方法。
With Python type hints, we capitalize the name of the type, and set the name of the type inside the collection in brackets as seen above, num: List[int]
.
通过Python类型提示 ,我们将类型的名称大写,并在集合内的类型名称中设置括号,如上图所示: num: List[int]
。
Line 5–8: We set a variable ans
to 0. Using a for
loop, we iterate the input array, nums
using XOR
compound assignment, ans ^= n
. This will output the single number from the array.
第5–8行:我们将变量ans
设置为0。使用for
循环,使用XOR
复合赋值ans ^= n
迭代输入数组nums
。 这将从数组中输出单个数字。
Line 10–11: We instantiate the class Solution
and call the method singleNumber
.
第10-11行:我们实例化类Solution
并调用方法singleNumber
。
(You can run this Python code without type notations if you are interested.)
(如果您感兴趣的话,可以运行此Python代码而无需输入类型注释。)
The following is the solution for the LeetCode environment:
以下是LeetCode环境的解决方案:
class Solution:
def singleNumber(self, nums: List[int]) -> int:
ans = 0
for n in nums:
ans ^= n
return ans
防锈码 (Rust Code)
Rust structs contain named fields. We use a keyword struct
and set fields with its type within the curly bracket. We put methods into a impl
block.
Rust 结构包含命名字段。 我们使用关键字struct
并在大括号内设置其类型的字段。 我们将方法放入impl
块中。
起始码 (Starting code)
Output:
输出:
1
Line 1: We suppress dead_code
warning.
第1行:我们禁止显示dead_code
警告。
Line 2–4: Create a struct
called Solution
that takes one field nums
with Vec<i32>
type. (More on Vectors.)
2-4线:创建struct
称为Solution
,它有一个字段nums
用Vec<i32>
类型。 (有关向量的更多信息。)
Line 6–10: We create a method single_number
in impl Solution
. The single_number
takes the first parameter &self
(More on self
.) and we just return 1
for now.
第6-10行:我们在impl Solution
创建一个方法single_number
。 single_number
采用第一个参数&self
( 有关 self
更多信息 。),我们现在只返回1
。
Line 12–17: In the main function, we create an instance and print 1
using the method.
第12-17行:在main函数中,我们创建一个实例并使用方法打印1
。
It seems all working so we are going to complete the single_number
method next.
看来一切正常,因此我们接下来将完成single_number
方法。
方法和相关功能 (Method and Associated Functions)
Methods are defined within the context of a struct and their first parameter is always
self
, which represents the instance of the struct the method is being called on. - The Rust Programming Language方法是在结构的上下文中定义的,它们的第一个参数始终是
self
,它表示正在调用该方法的结构的实例。 -Rust编程语言
Associated functions don’t take self
as a parameter and they are not methods because they don’t have an instance of the struct to work with.
关联函数不以self
为参数,也不是方法,因为它们没有可使用的结构实例。
A good example is String::from
function.
一个很好的例子是String::from
函数。
We use the ::
syntax with the struct name to call this associated function whereas we use .
when we call a method.
我们使用::
语法和结构名称来调用此关联函数,而使用.
当我们调用一个方法时。
A common associated function is a new
function that returns a value of the type the associated function is associated with.
常用的关联函数是一个new
函数,它返回与该关联函数关联的类型的值。
Output:
输出:
x: 5, y: 4
x: 8, y: 9
最终代码 (Final code)
Line 7–11: We create a mutable variable ans
with the type of i32
. Using for
loop, we iterate &self.nums
using ans ^=n
.
第7-11行:我们创建了一个i32
类型的可变变量ans
。 使用for
循环,我们使用ans ^=n
迭代&self.nums
。
Output:
输出:
5
We adjust the above code to the LeetCode environment.
我们将上面的代码调整为LeetCode环境。
impl Solution {
pub fn single_number(nums: Vec<i32>) -> i32 {
let mut ans: i32 = 0;
for n in nums {
ans ^= n;
}
ans
}
}
The memory usage is 2.2 MB in Rust and 16.5 MB in Python. (More on Runtime & Memory usage)
Rust的内存使用为2.2 MB,Python的为16.5 MB。 ( 有关运行时和内存使用的更多信息 )
使用关联函数的解决方案 (Solution Using an Associated Function)
Since we learned about the associated function, let’s apply it to this problem.
由于我们了解了关联的函数,因此将其应用于此问题。
Output:
输出:
1
4
Line 6–10: We create an associated function, new
as we have done it before. This new
function takes one parameter nums
that is a vector with items of i32
.
第6-10行:我们创建了一个关联的函数,这是我们之前做的new
函数。 此new
函数采用一个参数nums
,它是带有i32
项的i32
。
When the parameter names and the struct field names are exactly the same, we can use the field init shorthand syntax as nums
instead of nums: nums
.
当参数名称和结构字段名称完全相同时,我们可以使用字段初始化速记语法作为nums
而不是nums: nums
。
In the main function, we call an associated function, new
and pass nums
as an argument. We use method syntax to call the single_number
method on the ans3
instance.
在主函数中,我们调用关联的函数new
和nums
作为参数。 我们使用方法语法在ans3
实例上调用single_number
方法。
问题2:将数字减少为零的步骤数 (Problem 2: Number of Steps to Reduce a Number to Zero)
In this problem, you input a non-negative integer num
and return the number of steps to reduce it to zero. If the current number is even, you have to divide it by 2, otherwise, you have to subtract 1 from it.
在此问题中 ,您输入一个非负整数num
并返回将其减少为零的步骤数。 如果当前数字是偶数,则必须将其除以2,否则,必须从中减去1。
For example:
例如:
Input: num = 14
Output: 6
Explanation:
Step 1) 14 is even; divide by 2 and obtain 7.
Step 2) 7 is odd; subtract 1 and obtain 6.
Step 3) 6 is even; divide by 2 and obtain 3.
Step 4) 3 is odd; subtract 1 and obtain 2.
Step 5) 2 is even; divide by 2 and obtain 1.
Step 6) 1 is odd; subtract 1 and obtain 0.Input: num = 8
Output: 4
Explanation:
Step 1) 8 is even; divide by 2 and obtain 4.
Step 2) 4 is even; divide by 2 and obtain 2.
Step 3) 2 is even; divide by 2 and obtain 1.
Step 4) 1 is odd; subtract 1 and obtain 0.
This is a good example that we can use the Modulus/Remainder operator and the compound assignment operators.
这是一个很好的例子,我们可以使用“模数/余数”运算符和复合赋值运算符。
Python解决方案 (Python Solution)
Output:
输出:
6
4
Line: 3–10: We use a while
loop for num > 0
. If the modulus is 0, then it must be an even number so we divide the num
by 2 using a compound assignment /=2
, otherwise, we subtract 1 using a compound assignment -=1
. We increase the steps
by 1. Finally, we return the steps
.
第3-10行:对于num > 0
我们使用while
循环。 如果模量为0,则它必须是偶数,因此我们使用复合赋值/=2
将num
除以/=2
,否则,使用复合赋值-=1
减去-=1
。 我们将steps
增加1。最后,我们返回steps
。
We adjust the above code to the LeetCode environment.
我们将上面的代码调整为LeetCode环境。
class Solution:
def numberOfSteps (self, num: int) -> int:
steps = 0
while num > 0:
if num % 2 == 0:
num //= 2
else:
num -=1
steps += 1
return steps
防锈解决方案 (Rust Solution)
Output:
输出:
6
4
In Rust, we take the same steps as we did in Python.
在Rust中,我们采取与在Python中相同的步骤。
Line 7–16: We assign 0 to a mutable variable steps
. While self.num
is greater than 0, we use the compound assignment /=2
if self.num
's remainder is 0, otherwise, we subtract 1, and increase the number of step by 1.
第7-16行:我们将0分配给可变变量steps
。 当self.num
大于0时,如果self.num
的余数为0,则使用复合赋值/=2
,否则,我们减去1,并将步数增加1。
We adjust the above code to the LeetCode environment.
我们将上面的代码调整为LeetCode环境。
impl Solution {
pub fn number_of_steps (mut num: i32) -> i32 {
let mut steps = 0;
while num > 0 {
if num % 2 == 0 {
num /= 2;
} else {
num -=1;
}
steps += 1;
}
steps
}
}
结论 (Conclusion)
We learned arithmetic, comparison, logical, bitwise, and compound assignment operators in Rust. We also learned operator overloading, the difference between associated function and methods, how to use operators in Rust by converting simple Python codes to Rust.
我们在Rust中学习了算术,比较,逻辑,按位和复合赋值运算符。 我们还学习了运算符重载,相关函数和方法之间的区别,如何通过将简单的Python代码转换为Rust来在Rust中使用运算符。
I hope you learned something and are ready for the next step. Please stay tuned for the next post.
希望您能学到一些知识并为下一步做好准备。 请继续关注下一篇文章。
翻译自: https://towardsdatascience.com/a-comprehensive-tutorial-to-rust-operators-for-beginners-11554b2c64d4
rust面向对象