SWIFT字符串索引组合(" 作为一个字符而不是两个字符(") [英] Swift string indexing combines " " as one char instead of two

查看:48
本文介绍了SWIFT字符串索引组合(" 作为一个字符而不是两个字符(")的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用SWIFT 4.2处理包含 的字符串。我遇到了一种奇怪的SWIFT索引行为,似乎 将被SWIFT索引方法视为一个字符而不是两个字符。我编写了一段代码来表示此行为:

var text = "ABC

DEF"

func printChar(_ lower: Int, _ upper: Int) {
    let start = text.index(text.startIndex, offsetBy: lower)
    let end = text.index(text.startIndex, offsetBy: upper)
    print(""" + text[start..<end] + """)
}

printChar(0, 1) // "A"
printChar(1, 2) // "B"
printChar(2, 3) // "C"
printChar(3, 4) // new line
printChar(4, 5) // new line (okay, what's going on here?)
printChar(5, 6) // "D"
printChar(6, 7) // "E"
printChar(7, 8) // "F"

打印结果将为

"A"
"B"
"C"
"
"
"
"
"D"
"E"
"F"

知道为什么是这个样子吗?

推荐答案

TLDR: 是一个字素簇,在SWIFT中被视为单个Character,因为UNICODE。


  • SWIFT将 视为一个Character

  • Objective-CNSString将其视为两个字符(根据length的结果)。

On the swift-users forum有人写道:

-&报价; ";是单个Character。这是正确的行为吗?

-是的,Character对应于Unicode字素簇,并且"; &qot;被视为单个字素簇。

随后的响应发布了指向Unicode文档的链接,请签出this table,该文档正式声明CRLF是字素簇。

查看Apple documentation on Characters and Grapheme Clusters

通常认为字符串是一个字符序列,但在处理NSString对象或一般的Unicode字符串时,大多数情况下最好处理子字符串,而不是单个字符。其原因是,在许多情况下,用户认为是文本中的字符的内容可能由字符串中的多个字符表示。

Strings and Characters上的SWIFT文档也值得阅读。

这个overview from objc.io也很有趣。

NSString表示UTF-16编码的文本。长度、索引和范围均基于UTF-16代码单元。

另一个例子是像👍🏻这样的表情符号。这个字符实际上是%uD83D%uDC4D%uD83C%uDFFB,四个不同的Unicode标量。但是,如果您仅使用该表情对字符串调用count,您将(正确地)获得1

如果您想查看标量,可以按如下方式迭代它们:

for scalar in text.unicodeScalars {
    print("(scalar.value) ", terminator: "")
}

哪个" "将为您提供13 10

In the Swift documentation您会发现NSString不同的原因:

Count属性返回的字符计数并不总是与包含相同字符的NSString的Length属性相同。NSString的长度基于字符串的UTF-16表示形式中16位代码单元的数量,而不是字符串中Unicode扩展字素簇的数量。

因此,这并不是SWIFT字符串索引的奇怪行为,而是Unicode如何处理这些字符以及SWIFT中的String是如何设计的结果。SWIFT字符串索引使用Character 是单个Character

这篇关于SWIFT字符串索引组合(&QUOT; 作为一个字符而不是两个字符(&QUOT;)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆