第七章——字符串(代码点视图)

news/2024/7/24 7:40:24 标签: swift

本文系阅读阅读原章节后总结概括得出。由于需要我进行一定的概括提炼,如有不当之处欢迎读者斧正。如果你对内容有任何疑问,欢迎共同交流讨论。

有时候我们需要直接对底层的代码点进行一些操作,而不是处理Character,这有以下几个原因。

首先,有时候我们真正需要的就是代码点,比如渲染UTF-8编码的网页或者在与非Swift的API交互中用到了代码点。举个例子,我们看一下NSCharacterSet和Swift中字符串的联合使用。在此前我们说过NSString使用的是UTF-16编码的代码点,所以如果你想用NSCharacterSet来分割字符串,你需要在UTF-16视图中进行:

swift copyable">extension String {
func words(splitBy: NSCharacterSet = .alphanumericCharacterSet()) -> [String] {
return self.utf16.split {
!splitBy.characterIsMember($0)
}.flatMap(String.init)
}
}

let s = "Wow! This contains _all_ kinds of things like 123 and \"quotes\"?"
print(s.words())

// 输出结果:
// ["Wow", "This", "contains", "all", "kinds", "of", "things", "like", "123", "and", "quotes"]
复制代码

具体看一下这段代码的原理。它调用split方法将字符串分割成若干段,分段原理是遇到非数字或字母的字符就分段,分段结果是若干个String.UTF16View的切片,然后再通过flatMap方法转换成字符串,方法的参数是字符串的可失败构造器,这是因为下标有可能落在字符内部的边界上。因此flatMap方法的使用还有助于我们过滤掉所有nil的元素,这在《可选类型技术之旅》中有详细描述。

如果你是用的不是self.utf16而是self.utf8self.utf32,代码无法通过编译。

使用代码点而不是字符的另一个原因是处理代码点比字符快得多。这是因为字符需要组合多个代码点,这需要不断向前寻找有没有可以组合的代码点。在后面的“性能”章节中我们会展示这个速度差异。

最后,UTF-16视图还具有一个其他视图不具备的优点:它可以随机访问。String.UFT16View.Index被拓展,实现了RandomAccessIndexType协议。在上一节中我们知道字符串在String类型的内部正是以UTF-16编码方式存储的。随机访问意味着第n个UFT-16的代码点一定在buffer的第n个位置,无论字符串中是否包含非ASCII码。

你可能认为随机访问很少会派上用场,大多数情况下字符串只需要线性访问。但有一些算法依赖于随机访问以保证其效率。比如Boyer- Moore算法(改良版的KMP) 依赖于随机访问,一次跳过多个字符。你也可以在你的算法中利用上这个特性,比如:

swift copyable">// 貌似原文中没有实现search方法,所以这段代码其实无法编译
let greeting = "Hello, world!"
if let idx = greeting.utf16.search("world".utf16)?.samePositionIn(greeting) {
//     print(greeting[idx..<greeting.endIndex])
}
复制代码

不过这种效率的提示或简便特性的获得是有代价的,现在你的代码无法确保完全是符合Unicode标准的了,所以下面这个断言将会被触发:

swift copyable">let text = "Look up your Pok\u{0065}\u{0301}mon in a Pokédex."
assert(text.utf16.search("Pokémon".utf16) == nil)
复制代码

理论上说,字符串Pok\u{0065}\u{0301}mon和字符串"Pokémon"完全相等,但这里的search方法会返回nil

Unicode标准把变音符和字母连接起来的字符定义为alphanumeric(数字或字母),所以下面这行代码不会出现问题:

swift copyable">print(text.words())

// 输出结果:
// ["Look", "up", "your", "Pokémon", "in", "a", "Pokédex"]
复制代码

http://www.niftyadmin.cn/n/1271234.html

相关文章

hive 修改分桶数 分桶表_Hive SQL之分区表与分桶表

Hive sql是Hive 用户使用Hive的主要工具。Hive SQL是类似于ANSI SQL标准的SQL语言&#xff0c;但是两者有不完全相同。Hive SQL和Mysql的SQL方言最为接近&#xff0c;但是两者之间也存在着显著的差异&#xff0c;比如Hive不支持行级数据的插入、更新和删除&#xff0c;也不支持…

华为 DHCP基本配置及概念

DHCP实验 一、基本概念 &#xff08;1&#xff09;DHCP服务器 负责从地址池中分配地址给HDCP客户端&#xff0c;可以为DHCP客户端提供其他网络参数&#xff08;dns服务器地址、域名、租期等、默认网关等&#xff09;&#xff0c;还可以处理来自本网段或跨网段由HDCP中继转发的…

暴力探测蓝牙设备工具redfang

2019独角兽企业重金招聘Python工程师标准>>> 暴力探测蓝牙设备工具redfang 根据是否可以被扫描到&#xff0c;蓝牙设备具有可见&#xff08;Disoverable&#xff09;和不可见&#xff08;non discoverable&#xff09;两种模式。为了扫描不可见蓝牙设备&#xff0c;…

华为ACL通配符

IP地址中的是掩码 ACL中wildcard是通配符 路由协议中的wild card是反掩码 接下来解释ACL的通配符的规则&#xff1a; 掩码、反掩码、通配符&#xff1a; 掩码连续的1和0IP地址255.255.255.01对应网络位&#xff0c;0对应主机位反掩码连续的0和1路由协议0.0.0.2550必须匹配…

react-router browserHistory刷新页面404问题解决

使用React开发新项目时&#xff0c;遇见了刷新页面&#xff0c;直接访问二级或三级路由时&#xff0c;访问失败&#xff0c;出现404或资源加载异常的情况&#xff0c;本篇针对此问题进行分析并总结解决方案。 查看个人博客 背景 使用webpack-dev-server做本地开发服务器时&…

dedecmsjs表单提交_dedecms,ajax提交,前端验证,前端提示,以及30秒后再提交

前端代码.form-control{height: 2.5rem;font-size: .875rem;}input#btn-form1.btn.btn-default:focus{border-color:#ccc;webkit-box-shadow:none;box-shadow:none;}input#btn-form2.btn.btn-default:focus{border-color:#ccc;webkit-box-shadow:none;box-shadow:none;}.blank2…

华为PPP认证

PAP 认证方: [R1-Serial1/0/0]ppp authentication-mode pap [R1-Serial1/0/0]q [R1]aaa [R1-aaa]local-user 123 pas cipher huawei Info: Add a new user. [R1-aaa]local-user 123 service-type ppp 被认证方&#xff1a; [R2-Serial1/0/0]ppp pap local-user 123 pass…

Mcad学习笔记之序列化(2进制和Soap序列化)

相关文章导航Sql Server2005 Transact-SQL 新兵器学习总结之-总结Flex,Fms3相关文章索引FlexAir开源版-全球免费多人视频聊天室,免费网络远程多人视频会议系统((Flex,Fms3联合开发))<视频聊天,会议开发实例8>我最近学习remoting和web服务时,总是看到一个重要的字眼"…