【问题标题】:Why do I need the string to determine the index for the Nth character?为什么我需要字符串来确定第 N 个字符的索引?
【发布时间】:2017-07-24 09:45:21
【问题描述】:

我想得到一个字符串的子字符串,它只是前 N 个字符。 (例如 10 个)。

但字符串是函数生成的输出。

我想这样做......

let string = someInputString
    .someGeneratorFunctionThatReturnsAString()
    .substring(to: 10)

但我不能这样做。因为 substring 函数中的索引需要字符串本身来确定第 10 个字符在哪里。

  • 第一个问题...为什么会这样?
  • 第二个问题...如何在不需要原始字符串获取索引的情况下获得这样的子字符串。

【问题讨论】:

  • 据我所知,它或多或少是这样的:Swift 中的字符串在内部存储为 UTF-8,因此无法进行随机访问(字符的字节长度可变),所以有这个叫做“索引”的东西是你创建的一个特定的字符串,并通过前进或后退整数个位置(顺序)来修改,它们仅适用于该字符串。
  • @NicolasMiari:实际上字符串在内部使用 ASCII 或 UTF-16,但这是一个实现细节,将来可能会改变。
  • @NicolasMiari:不是这样。但是Character 是一个“扩展字形簇”,由一个或多个 unicode 标量组成。
  • @Fogmeister:这是您的问题的简单解决方案:stackoverflow.com/a/32984213/1187415
  • @Fogmeister 看到了吗?我说的是我的** :-) 听听那些知道的人!

标签: swift string substring


【解决方案1】:

我只是可能理解你的问题是错误的,但在这里你可以很容易地子字符串:

extension String {
    func substring(to: Int) -> String? {
        return self.substring(to: self.index(self.startIndex, offsetBy: to))
    }
} 

【讨论】:

  • 是的,我也创建了一个这样的扩展。只是想知道为什么它需要字符串。谢谢:D
【解决方案2】:

请参阅Gunhan 对问题 2 的回答。

对于问题 1:

长答案:基本上,在 Swift 中,Collection 协议(Array 和 String 等类型采用)指定了性能标准。最值得注意的是,集合的开始和结束索引必须在 O(1) 时间内可访问。这也适用于元素的下标访问(参见https://developer.apple.com/documentation/swift/collection预期性能标题下的文本)。

索引是指向另一个引用或值类型的内存地址。对于字符串,索引指向Character 结构值。虽然字符串let x = "hello"let y = "hello" 中字符的 可能相同,但常量xy 是不同的内存地址,指向它们的索引也是各自的Character 结构值。因此,您不能使用相同的索引从x 获取子字符串"llo" 和从y 获取子字符串"llo"...这没有任何意义,因为您将使用的索引将是特定的内存地址这些变量。

在架构上,这里有三个相互影响的实体:

String |--hasIndicesOfType--> String.Index |--whichPointTo--> Character

(旁注:这里,IndexString 上的associatedtype,这就是为什么你会看到String.Index 的原因,比如说,将其中一个记录到Xcode 控制台)。

简而言之为什么函数需要字符串本身的答案是因为字符串的索引是字符串字符的内存地址。 String 符合 Collection 以在访问 String 的元素时获得 O(1) 性能。因此,指数。因为索引是内存地址,它们只适用于给定的对象(引用类型)——这就是为什么对字符串字符的通用访问只适用于一个字符串(即,您不能使用内存地址访问字符串 A 的元素到字符串 B 的字符.. . 这没有意义。)

简而言之:因为String符合Collection

一些有用的教程式代码:

Teleology:明显的最终目标推理(又名teleological 分析)为什么String 是它在 Swift 中的方式:

语言的贡献者更喜欢优化 time complexity 而不是 space complexity

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-15
    • 2021-02-04
    • 2011-03-03
    • 1970-01-01
    • 1970-01-01
    • 2012-01-03
    • 2020-01-08
    • 1970-01-01
    相关资源
    最近更新 更多