rust废铁最快_如何快速优雅的掌握Rust(二)

1、3天的成果

代码在 https://github.com/caiqingfeng/rustguru ,完成了poker算法里最核心的建表算法,共计有900多行代码,包含注释和测试。为什么说在学习过程中心情很愉悦,有一个很重要的原因,就是把C++代码转成rust代码,包括循环、递归、HashMap、Vector、测试等等这些都几乎是直觉就搞定,除了早期第一个函数在理解使用Rust的内存管理机制上稍微费了点力气,其它的都非常顺利,几乎算是一版搞定。当然过程中也碰到有些有意思的问题,这篇文章就趁着自己还记得,新鲜热乎着,放在这里跟大家分享。

2、for循环的改造

我们在C++/golang代码里,特别喜欢写类似如下的代码:

for (int i=12; i>=0; i--) {

std::vector s;

s.push_back(i);

set.push_back(s);

}

Rust不支持这样的语法,那只能用

for i in 0..13 {

let mut s: Vec = Vec::new();

s.push((12-i) as u64);

comb.push(s);

}

这样带来一个问题,因为我们是希望逆序遍历,在循环体里需要把i换成12-i,当算法比较复杂的时候,这种简单替换带来了一些很让人费解的问题。

更好的解决方案是用while来替换。

let mut i:i32 = 12;

while i>=0 {

let mut s: Vec = Vec::new();

s.push(i as u64);

comb.push(s);

i=i-1;

}

这里有一个特别需要注意的是,要在循环体的所有出口(continue处)都要对计数器进行自减的工作。

let mut z:i32 = y-1;

while z>=0 {

if z == i { z=z-1; continue;}

}

3、数据溢出

我们在C++/golang里对32位无符号整数进行乘法运算的时候,例如41*41*41*43*37*37=4057172507,结果其实已经超过了32位的最大表达能力2147483647,但在C++/golang里,溢出会自动处理成取余运算,在rust里运行就会报错误 overflow,所以在代码里,就大量的使用了41u64*37u64*31u64*29u64*19u64这样的操作,避免出现overflow的情况发生。

4、单元测试

可以看到单元测试代码非常符合直觉,基本上我把C++的测试代码拷贝过来,改成符合Rust语法,就一版编译通过。

5、为什么要单元测试

这里给一个例子,用单元测试发现的问题。

对比下图中C++代码,其中第217行对应101行,当时在转C++代码到rust代码的时候,先是把循环换成for i in 0..13,然后把i替换成12-i逆序来,后来发现这样逻辑很不直观,最后还是换成了while循环,把12-i又全替换成i,在这里就误伤了,但我们在运行单元测试代码的时候,马上就发现了这个问题。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值