rust有准星_Rust能力养成系列之(2):功能抽象

前言

上一篇,介绍了上一篇,介绍了Rust语言的安装与编译

基本数据类型

变量声明和不可变绑定

这其中已经蕴含着Rust精华的成分了。本篇内容将涉及常规函数

闭包

字符串

函数(Function)

一般而言,编程语言中的函数,将过程性指令抽象为专名的功能实体,以重复调用,简化代码。在上一篇中,我们已经看过了main函数,这里看下如何定义一个常规函数。

//function.rs

fn add(a: u64, b: u64) -> u64 {

a + b

}

fn main() {

let a: u64 = 17;

let b = 3;

let result = add(a, b);

println!("Result {}", result);

}

解释代码

从以上代码第2行可见,这个add 是一个简单的加法函数,

fn是创建函数的关键字,

参数 a,b在函数名的括号中,各自的数据类型显式的声明在冒号之后,

返回类型也得到显式声明->u64, 如果没有返回值,这一步可以不写

如第一篇所提及,函数是有类型的,这里为 fn(u64, u64) -> u64显然,函数也可以作为变量和其他函数的参数

第3行现已不需要return关键词进行函数值返回

再看一下main函数,第5-10行:第6行,声明了一个变量a,及其类型,并初始化

第7,8行,声明变量b,result,并初始化,这里没有显式声明b的类型,表明是可以省略的,因为Rust能够在大多数情况对代码中的变量类型进行正确推断,不难得知:b和result 都是u64

对类型的显式声明在Rust中是有其目的:避免类型标识上可能出现的冲突

提升代码的可读性,尤其当多种类型嵌套一起时

Rust的类型推理基于Hindly Milner类型系统,是一整套支持编程语言中类型推断的规则和算法,可在线性时间内执行,不但高效,而且在大型程序的类型检查中很为实用。

上述代码结果

我们再看一个改变函数参数的代码实例。

// function_mut.rs

fn increase_by(mut val: u32, how_much: u32) {

val += how_much;

println!("You made {} points", val);

}

fn main() {

let score = 2048;

increase_by(score, 30);

}

解释代码

代码不长,大致说下:在main函数中,声明score,初始化为2048;调用increase_by函数,30为该函数的第2个参数。

需要说明一下,在increas_by中,明确了第1个参数为mut val,表明这一参数可以在该函数内部改变赋值,这显然是可变绑定在函数体中的一次体现。

上述代码结果

闭包(Closure)

到这里,谈一下Rust中也同样支持的闭包,其与函数相似,但在声明之时,附及更多的环境(environment)或范围(scope)信息;

再者,定义时,函数有名(关键字fn),而闭包无名,虽然无名,但又能够赋值

同函数一样,可以作为值存储,并被其他的函数体调用。

闭包的主体,可以单行,也可以多行

举例而言,一个简单的闭包可能形如: let my_closure = || (); ,可见这个闭包既无参数,又没有任何功能,可以直接调用my_closure(),;而||是用来装载参数的,比如|a,b|, 如果感到类型不太好推断,当然最好明确类型,如|a:u32|。

我们看一下这个代码,里面有两个闭包doubler 和big_closure

// closures.rs

fn main() {

let doubler = |x| x * 2;

let value = 5;

let twice = doubler(value);

println!("{} doubled is {}", value, twice);

let big_closure = |b, c| {

let z = b + c;

z * twice

};

let some_number = big_closure(1, 2);

println!("Result from closure: {}", some_number);

}

可见:第3行,一定不要看成是绝对值,这是一个单行闭包--doubler,参数是x,功能是返回x的2倍;

第4行,初始化变量value=5

第5行,初始化变量twice=doubler(value),同时也是调用闭包doubler

第6行,打印相关值

第8-11,第2个闭包big_closure ,是一个多行闭包,参数为b,c; 函数内定义初始化变量z,最终返回z*twice的值

第13行,初始化变量some_number,调用闭包big_closure

第14行,打印相关值

上述代码结果

有关闭包的用途,主要是作为高阶函数(higher-order function)的参数,原因在于闭包可以提供相对便利的抽象(convenient abstraction)。

相关的实例,比如:thread::spawn或者迭代器Iterator特性中的filter方法,但这些东西,在本文中尚非重点,而且需要很多前提知识才能讲清楚,会在后续有关Rust高级概念的篇章中详细介绍。

字符串(String)

字符串是编程语言中颇为常用的数据类型,在Rust中,通常有两种形式:字符串,String

字符串指针,&str,与C语言一样,&就是一个指针符号

Rust字符串是有效的UTF-8编码的字节序列;像C字符串那样以null结尾,之间可以包含null字节。

我们看一下代码实例

// strings.rs

fn main() {

let question = "How are you ?"; // a &str type

let person: String = "Bob".to_string();

let namaste = String::from("नमस्ते"); // unicodes yay!

println!("{}! {} {}", namaste, question, person);

}

依然是不难的代码,希望我们这可以这样循序渐进的学下去。第1行,初始化一个字符串指针&str类型的变量question

第2-3行,初始化String类型变量person 和namaste

上述代码结果

显然存在多种方式创建String类型。

字符串变量分配在堆(heap)上,而字符串指针类型&str,指向一个现有字符串,既可以在堆,也可在栈(stack)上。

这里依然还是一个简单介绍,关于字符串的进一步讨论会在之后篇章中继续。

结语

本文介绍了Rust中的函数,闭包和字符串,都是编程中的基本元素,请读者注意下在函数定义中有关类型方面的特点。

下一篇会介绍一下Rust中的分支与循环。

主要参考和建议读者进一步阅读的文献The Rust Programming Language​doc.rust-lang.org

Rust编程之道,2019, 张汉东

The Complete Rust Programming Reference Guide,2019, Rahul Sharma,Vesa Kaihlavirta,Claus Matzinger

Hands-On Data Structures and Algorithms with Rust,2018,Claus Matzinger

Beginning Rust ,2018,Carlo Milanesi

Rust Cookbook,2017,Vigneshwer Dhinakaran

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值