Rust : 危险! 关于字符串切片以及取值......
来源:互联网 发布:淘宝买小饰品文艺店铺 编辑:程序博客网 时间:2024/05/21 09:35
我们知道,Rust中字符串的切片容易会引起panic,千万要注意。主要是,Rust的切片,切的其中字节,这个说法有些抽象,如何能理解呢?
首先,对一个字符串,你认为其字符数和长度是一个什么样的概念?相等,不相等?
比如,对于ascii码字符串,
let same_string ="abc";println!("chars:{}, length:{}",same_string.chars().count(),same_string.len());// chars :3,length:3
当然,不都是这样的。
let other_string ="忠犬ハチ公";println!("chars:{}, length:{}",other_string.chars().count(),other_string.len());// chars :5,length:15
所以,最重要的是,Rust的切片,切的是字节,而不是字符。
一、Rust的切片操作
//String let t1 = "love".to_string(); println!("String =>t1:{:?}", &t1[2..]);//必须带&, =>ve // &str let t2 = "love"; println!("&str =>t2:{:?}", &t2[2..]);//必须带& =>ve
好象看起来,很正常呀,没什么问题的。
如果碰到的全是a…z之类构成的,是可能没问题的,但其它的呢?
二、有没有意外?
既然是危险的操作,危险就是必然的。
// 一个“不正常”的例子 let love_china = "忠犬ハチ公"; println!("{:?}=>bytes :{:?}", love_china, love_china.bytes().len()); //println!("{:?}", love_china.len_utf8()); for i in love_china.chars() { println!("{:?} =>bytes :{:?}", i, i.len_utf8()); } println!("love_china[0] :{:?}", love_china.chars().nth(0));// 一个正常的例子 let normal = "love"; println!("=>{:?} =>bytes: {:?}", normal, normal.bytes().len()); for i in normal.chars() { println!("{:?}, =>bytes:{:?}", i, i.len_utf8()); } println!("normal[0] :{:?}", normal.chars().nth(0).unwrap());
output:
"忠犬ハチ公"=>bytes :15'忠' =>bytes :3'犬' =>bytes :3'ハ' =>bytes :3'チ' =>bytes :3'公' =>bytes :3love_china[0] :Some('忠')=>"love" =>bytes: 4'l', =>bytes:1'o', =>bytes:1'v', =>bytes:1'e', =>bytes:1normal[0] :'l'
发现什么没有?
println!("love_china len:{:?}", love_china.len());// => len =15,而不是5!
知道问题所在了吧…….
(1) ‘忠’ =>bytes :3.
也就是说,’忠’字符却占3个字节,如果你去切1个字节,还会报什么呢,Rust只能panic了。
let dd1 = &love_china[0..3];//切前3个字节=>'忠'. println!("dd:{:?}", dd);
如果&love_china[0..2]=>切前2个字节,则会panic!.
(2) ‘l’, =>bytes:1。
象“love”其它的每个字符,都只占了1个字节,形成了字符位和字节位的刚好重合,给人一种“安全”的错觉。
三、正确的打开方式
1、单个字符的取值
下面是推荐的取字符串中正确的打开方式:.chars().nth(0)。
println!("love_china[0] :{:?}", love_china.chars().nth(0));
那如果要取其中的两个字符呢? 思考一下…….
2、多个字符的取值
let tt = "我爱工作,rust,julia!"; let t = tt.chars().into_iter().map(|x| x.to_string()).collect::<Vec<_>>(); println!("t:{:?}", t); let ww: String = t[1..3].concat(); let qq: String = t[1..3].join(""); println!("ww:{:?} qq:{:?}", ww, qq);
阅读全文
0 0
- Rust : 危险! 关于字符串切片以及取值......
- Python 的切片操作以及 利用步长对序列进行倒序取值
- 文件取值以及字符串存至文件中
- java json字符串转JSONObject和JSONArray以及取值
- java json字符串转JSONObject和JSONArray以及取值
- java json字符串转JSONObject和JSONArray以及取值
- java json字符串转JSONObject和JSONArray以及取值
- 关于汇编中取字符串
- DataFrame 行列选择,切片操作,多重索引取值
- 关于iframe取值问题以及google浏览器测试
- JavaScript:数组增加、删除、翻转、转字符串、取索引、截取(切片)slice、剪接splice、数组合并
- 关于IOS中UIimage字符串取值(使用range)
- Rust和golang之字符串
- python中的字符串切片
- python中的字符串切片
- 对字符串切片
- python对字符串切片
- Nim语言字符串切片
- HDU 1166 敌兵布阵 (线段树 插点问线)
- JS全屏
- 菱形继承的二义性和数据冗余问题
- mac下phalcon安装与配置
- 使用Java的Graphics类进行绘图的方法详解
- Rust : 危险! 关于字符串切片以及取值......
- LeetCode_Easy心得:7. Reverse Integer(C语言)
- SparkSQL实战之Youtube数据集
- 树莓派IP地址设置
- 【大数据部落】NBA体育决策和数据挖掘分析
- eclipse如何导入okhttp 2.x源码
- Ubuntu中安装中文输入法
- eclipse tomcat May be locked by another process 解决
- Span使用之利用自定义Span解析Html中特殊标签实现类似微博@效果