今天在工作中遇到一个问题,string调用truncate()接口panic了,报错信息大致如下:thread '0' panicked at 'assertion failed: self.is_char_boundary(new_len)', liballoc/string.rs:1121:13

我的代码如下:

示例1:

fn main() {let mut s = String::from("hello 中国");s.truncate(7); //获取前7个字节println!("s:{}", s);
}------------------------------------------------------------------------Compiling playground v0.0.1 (/playground)Finished dev [unoptimized + debuginfo] target(s) in 0.61sRunning `target/debug/playground`
thread 'main' panicked at 'assertion failed: self.is_char_boundary(new_len)', src/liballoc/string.rs:1123:13
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.

当然原始代码不是这个,但是原理是一样的。这里的问题出现在字符串中的中文(纯英文字符不会出现panic)。原因是,一个汉字所在字节数为非1 byte,当去截取slice的中字符时,字符边界判断导致panic了。

一开始怀疑是truncate()接口的问题,但后来发现并不是truncate本身的问题,所有涉及到slice中截取中文字符都会容易导致panic,不信看下面例子:

示例2:

fn main() {let a = "abcd早";let b = &a[..5];println!("b={}", b);
}-------------------------------------------------------------------------Compiling playground v0.0.1 (/playground)Finished dev [unoptimized + debuginfo] target(s) in 0.51sRunning `target/debug/playground`
thread 'main' panicked at 'byte index 5 is not a char boundary; it is inside '早' (bytes 4..7) of `abcd早`', src/libcore/str/mod.rs:2027:5
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.

再看如下例子:

示例3:

fn main() {let a = "abcd早";let b = &a[..3];println!("b={}", b);
}--------------------------------------------------------------
输出结果:
b=abc

示例4:

fn main() {let a = "abcd早";let b = &a[..7];println!("b={}", b);
}-------------------------------------------------------------
输出结果:
b=abcd早

示例3与示例2的区别在于,截取的字节数不同。示例3截取前3个字符均是英文,而示例4正好截取到了中文“早”字的字符边界(“早”字占4个字节)。

那么实际生产环境中很难保证我们要截取的slice中没有中文字符,任意截取不能保证正好是字符边界,那该怎么办?

网上有人提到先把slice转换为chars的vector,然后再调用truncate()之类的,但是觉得这样太消耗性能,所以我得方法是:

// 首先判断给出的index是不是字符边界,否则向后找到字符边界所在位置
fn find_char_boundary(s: &str, index: usize) -> usize {if s.len() <= index {return index;}let mut new_index = index;while !s.is_char_boundary(new_index) {new_index += 1;}new_index
}fn main() {let mut s = String::from("hello 中国");let idx = find_char_boundary(&s, 7); //实际获取到的idx=9s.truncate(idx);println!("idx:{}, s:{}", idx, s);
}-------------------------------------------------------------------
输出结果:
idx:9, s:hello 中

好了,以上就是对自己在rust编程中遇到的问题,做一个总结与备忘,希望对有需要的人也能够有所帮助!

rust中slice panicked at 'byte index 5 is not a char boundary' 问题解决办法相关推荐

  1. 关于unity 中使用AssetBundle加载资源,shader偶尔会丢失的问题解决办法

    问题描述: 因为项目中要进行热更新设计,所以用unity官方推荐的打包方式assetbundle进行打包,打包好了以后再电脑上运行正常,但是当发布到android上后发现偶尔场景背景会出现空白,多方查 ...

  2. 在Eclipse中编写servlet时出现The import javax.servlet cannot be resolved 问题解决办法

    在Eclipse中,project->properties,选择Java Build Path->Libraries->Add External JARs,找到你计算机中tomcat ...

  3. rust中的slice

    一.什么是切片(Slice) 切片这个概念很形象,也很容易为人理解.正如一个面包,如果一个无法吃掉全部,那么给他切一片不正好么?既不浪费,又不会引起不必要的后果.这样比喻不是很贴切,但其实意思有些类似 ...

  4. 17.Rust中函数式语言功能:迭代器与闭包

    Rust 的设计灵感来源于很多现存的语言和技术.其中一个显著的影响就是 函数式编程(functional programming).函数式编程风格通常包含将函数作为参数值或其他函数的返回值.将函数赋值 ...

  5. 深入解析 Go 中 Slice 底层实现

    转载地址:https://mp.weixin.qq.com/s/8b6FudzXStKN3d6p8wYSqQ 切片是 Go 中的一种基本的数据结构,使用这种结构可以用来管理数据集合.切片的设计想法是由 ...

  6. Rust 中的基本数据类型——Rust语言基础06

    文章目录 1. 前言 2. 标量类型(Scalar) 2.1. 整型(Integer) 2.2. Rust 的整数形式 2.3. 奇怪的问题(整数的溢出) 2.4. 浮点类型(Float) 2.5. ...

  7. rust全息要啥才能做_在 Rust 中不能做什么

    编者注:上周 Armin 在自己的博客上首次发布了这个版本.如果你想再次阅读这篇文章,或者想看看 Armin 还在做什么,一定要去看看. 去年一直很有趣,因为我们用 Rust 建造了很多好东西,并且这 ...

  8. c++ enum 给定类型_在 Rust 中创建 C/C++ API

    Rust 是一种神奇的语言,有着更好的生态系统.许多 Rust 的设计决策都非常适合向现有的C/C++系统添加新功能,或者逐步替换这些系统的部分! 当我尝试为 Rust 创建 C++ API 时,我发 ...

  9. Golang 中 Slice的分析与使用(含源码)

    文章目录 1.slice结构体 2.slice初始化 3.append操作 4.slice截取 5.slice深拷贝 6.值传递还是引用传递 参考文献 众所周知,在golang中,slice(切片)是 ...

  10. Rust语言- Slice(切片)类型([u8])

    文章目录 Rust语言- Slice(切片)类型(&[u8]) 动态类型(Dynamically Sized Types) 字符串字面值 Rust中的String与str 字符串切片 非字符串 ...

最新文章

  1. 第104天:web字体图标使用方法
  2. 1280*720P和1920*1080P的视频在25帧30帧50帧60帧时的参数
  3. 45种Javascript技巧大全
  4. java标识符的规则等
  5. JVM中GC的停顿现象
  6. 初识ABP vNext(2):ABP启动模板
  7. sky下载 star_star sky五军之战高清无损下载 star sky 高清mv下载
  8. java程序员需要掌握的知识,看完直接跪服
  9. JSK-25 两数之和【暴力】
  10. 父元素没有高度,子元素高度失效
  11. 三菱plc pwm指令_三菱PLC初学者只要解决这50个问题,那你就觉得很容易上手?
  12. 纯js代码-实战轮播图
  13. delphi pi怎么得到?
  14. 介绍计算机方队,方阵
  15. Photoshop-图层相关概念-LayerComp-Layers-移动旋转复制图层-复合图层
  16. python命名规则数字开头的成语_浅谈Python中带_的变量或函数命名
  17. 趋势:TypeScript - 一种思维方式
  18. java thrift异步调用_thrift异步调用 - thrift-cob_style-tnonblockingserver - ItBoth
  19. alibaba/COLA 4.0框架 使用记录
  20. google/filament 场景(Scene)管理

热门文章

  1. windows10虚拟机安装苹果系统
  2. 聚类时的轮廓系数评价和inertia_
  3. 视频带宽(码流_分辨率_帧率)
  4. 私人用的红帽linux,红帽宣布为个人开发者提供16个RHEL免费许可 支持在生产环境中使用...
  5. 正多边形和多面体的对称群
  6. CGAL多面体布尔运算
  7. 如何使用手机作为树莓派的显示屏幕
  8. ubuntu18.04桌面美化
  9. 关于Oracle练习
  10. 八核处理器真的比四核性能强悍吗?