替换参数字符串中的字符

Rap*_*ael 2 string string-length swift inout

我想擦除输入字符串。让我们从这个开始:

func foo(s: String) {
    s.replaceSubrange(0..<s.characters.count,
            with: String(repeating: "0", count: s.characters.count))
}
Run Code Online (Sandbox Code Playgroud)

可以预见的是,这会导致

不能对不可变值使用变异成员:“s”是“let”常量

美好的:

func foo(s: inout String) {
    s.replaceSubrange(0..<s.characters.count,
            with: String(repeating: "0", count: s.characters.count))
}
Run Code Online (Sandbox Code Playgroud)

但现在:

“inout String”无法转换为“String”

指着.character——什么?!

奇怪的是,当我这样做时:

func foo(s: inout String) {
    let n = s.characters.count
    s.replaceSubrange(0..<n,
            with: String(repeating: "0", count: n))

}
Run Code Online (Sandbox Code Playgroud)

调用.characters完全没问题,但是

无法使用“(CountableRange, with: String)”类型的参数列表调用“replaceSubrange”

使用0...n-1也不行。

如何替换参数字符串中的字符?

Ham*_*ish 5

AString不由CharacterView索引Int,而是由不透明类型索引String.Index。因此你想说:

\n\n
func foo(s: inout String) {\n    s.replaceSubrange(s.startIndex..<s.endIndex,\n                      with: String(repeating: "0", count: s.characters.count))\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

我们不直接使用字符串的characters属性来获取开始或结束索引,String为了方便起见,它在 API 中提供了它们 \xe2\x80\x93 但它们只是转发到CharacterView.

\n\n

要替换不同的子范围,您需要使用各种索引方法,例如index(after:)index(before:)index(_:offsetBy:)onString来偏移范围下限和上限的索引(这些方法也只是转发到字符串的字符视图) 。本问答中对这些方法进行了很好的总结。

\n\n

不使用作为索引类型的原因Int部分是因为String用 an 下标 aInt会产生一种错觉,即索引字符串是一个微不足道的操作 \xe2\x80\x93 ,但情况并非总是如此,因为以下事实:字符可以具有不同的字节长度,因此可能使索引成为 O(n) 操作。

\n\n

尽管如果您的目标只是设置s一个包含所有零且计数与之前的值相同的字符串,那么您可以只进行赋值:

\n\n
func foo(s: inout String) {\n    s = String(repeating: "0", count: s.characters.count)\n}\n
Run Code Online (Sandbox Code Playgroud)\n