'subscript' 不可用:无法使用 CountableClosedRange<Int> 下标字符串,请参阅文档评论进行讨论
'subscript' is unavailable: cannot subscript String with a CountableClosedRange<Int>, see the documentation comment for discussion
在 Swift 4 中,当我尝试使用下标语法获取 String
的 Substring
时出现此错误。
'subscript' is unavailable: cannot subscript String with a CountableClosedRange, see the documentation comment for discussion
例如:
let myString: String = "foobar"
let mySubstring: Substring = myString[1..<3]
两个问题:
- 我该如何解决这个错误?
- 错误中提到的 "the documentation comment for discussion" 在哪里?
- How can I resolve this error?
此错误意味着您不能在下标格式中使用 Int – 您必须使用 String.Index,您可以使用 encodedOffset Int 对其进行初始化。
let myString: String = "foobar"
let lowerBound = String.Index.init(encodedOffset: 1)
let upperBound = String.Index.init(encodedOffset: 3)
let mySubstring: Substring = myString[lowerBound..<upperBound]
- Where is "the documentation comment for discussion" that was referred to in the error?
它在 GitHub 的 Swift 标准图书馆存储库中一个名为 UnavailableStringAPIs.swift.gyb 的文件中,该文件位于一个锁着的文件柜的底部,该文件柜卡在废弃的厕所里,门上有一个标志说 'Beware of the Leopard'。 link
你的问题(和自我回答)有 2 个问题:
在 Swift 的标准库中从未提供过使用 Int
为字符串下标。只要 Swift 存在,此代码就一直无效:
let mySubstring: Substring = myString[1..<3]
新的 String.Index(encodedOffset: )
returns UTF-16(16 位)编码的索引。 Swift 的字符串使用 Extended Grapheme Cluster,它可以使用 8 到 64 位来存储一个字符。表情符号可以很好地演示:
let myString = ""
let lowerBound = String.Index(encodedOffset: 1)
let upperBound = String.Index(encodedOffset: 3)
let mySubstring = myString[lowerBound..<upperBound]
// Expected: Canadian and UK flags
// Actual : gibberish
print(mySubstring)
事实上,得到 String.Index
在 Swift 4 中根本没有改变,无论好坏:
let myString = ""
let lowerBound = myString.index(myString.startIndex, offsetBy: 1)
let upperBound = myString.index(myString.startIndex, offsetBy: 3)
let mySubstring = myString[lowerBound..<upperBound]
print(mySubstring)
- 如果您想在
"palindrome"[1..<3]
和 "palindrome"[1...3]
等字符串上使用下标,请使用这些扩展。
Swift 4
extension String {
subscript (bounds: CountableClosedRange<Int>) -> String {
let start = index(startIndex, offsetBy: bounds.lowerBound)
let end = index(startIndex, offsetBy: bounds.upperBound)
return String(self[start...end])
}
subscript (bounds: CountableRange<Int>) -> String {
let start = index(startIndex, offsetBy: bounds.lowerBound)
let end = index(startIndex, offsetBy: bounds.upperBound)
return String(self[start..<end])
}
}
Swift 3
对于 Swift 3 替换为 return self[start...end]
和 return self[start..<end]
。
- Apple 没有将其构建到 Swift 语言中,因为 'character' 的定义取决于字符串的编码方式。一个字符可以是 8 到 64 位,默认通常是 UTF-16。您可以在
String.Index
. 中指定其他字符串编码
This is the documentation Xcode 错误指的是。
基于
Swift 4
extension StringProtocol {
subscript(bounds: CountableClosedRange<Int>) -> SubSequence {
let start = index(startIndex, offsetBy: bounds.lowerBound)
let end = index(start, offsetBy: bounds.count)
return self[start..<end]
}
subscript(bounds: CountableRange<Int>) -> SubSequence {
let start = index(startIndex, offsetBy: bounds.lowerBound)
let end = index(start, offsetBy: bounds.count)
return self[start..<end]
}
}
显着变化:
- 现在是
StringProtocol
的扩展。这使得 Substring
等采用者也可以获得这些下标。
- 结束索引从边界的开始索引而不是字符串的开始偏移。这可以防止从
String
的开头遍历两次。 index
方法是 O(n),其中 n 是与 i 的偏移量。
在两个 and 答案的基础上,这里有两个扩展可以防止超出字符串开头和结尾的无效索引(这些扩展还避免了从头开始重新扫描字符串只是为了在范围结束):
extension String {
subscript(bounds: CountableClosedRange<Int>) -> String {
let lowerBound = max(0, bounds.lowerBound)
guard lowerBound < self.count else { return "" }
let upperBound = min(bounds.upperBound, self.count-1)
guard upperBound >= 0 else { return "" }
let i = index(startIndex, offsetBy: lowerBound)
let j = index(i, offsetBy: upperBound-lowerBound)
return String(self[i...j])
}
subscript(bounds: CountableRange<Int>) -> String {
let lowerBound = max(0, bounds.lowerBound)
guard lowerBound < self.count else { return "" }
let upperBound = min(bounds.upperBound, self.count)
guard upperBound >= 0 else { return "" }
let i = index(startIndex, offsetBy: lowerBound)
let j = index(i, offsetBy: upperBound-lowerBound)
return String(self[i..<j])
}
}
extension String {
subscript(bounds: CountableClosedRange<Int>) -> String {
let lowerBound = max(0, bounds.lowerBound)
guard lowerBound < self.count else { return "" }
let upperBound = min(bounds.upperBound, self.count-1)
guard upperBound >= 0 else { return "" }
let i = index(startIndex, offsetBy: lowerBound)
let j = index(i, offsetBy: upperBound-lowerBound)
return String(self[i...j])
}
subscript(bounds: CountableRange<Int>) -> String {
let lowerBound = max(0, bounds.lowerBound)
guard lowerBound < self.count else { return "" }
***let upperBound = min(bounds.upperBound, self.count-1)***
guard upperBound >= 0 else { return "" }
let i = index(startIndex, offsetBy: lowerBound)
let j = index(i, offsetBy: upperBound-lowerBound)
return String(self[i..<j])
}
}
你得到这个错误是因为范围内的下标结果是
Substring?
不是 Substring
。
您必须使用以下代码:
let myString: String = "foobar"
let mySubstring: Substring? = myString[1..<3]
您可以将字符串转换为字符数组...
let aryChar = Array(myString)
然后你得到所有的数组功能...
在 Swift 4 中,当我尝试使用下标语法获取 String
的 Substring
时出现此错误。
'subscript' is unavailable: cannot subscript String with a CountableClosedRange, see the documentation comment for discussion
例如:
let myString: String = "foobar"
let mySubstring: Substring = myString[1..<3]
两个问题:
- 我该如何解决这个错误?
- 错误中提到的 "the documentation comment for discussion" 在哪里?
- How can I resolve this error?
此错误意味着您不能在下标格式中使用 Int – 您必须使用 String.Index,您可以使用 encodedOffset Int 对其进行初始化。
let myString: String = "foobar"
let lowerBound = String.Index.init(encodedOffset: 1)
let upperBound = String.Index.init(encodedOffset: 3)
let mySubstring: Substring = myString[lowerBound..<upperBound]
- Where is "the documentation comment for discussion" that was referred to in the error?
它在 GitHub 的 Swift 标准图书馆存储库中一个名为 UnavailableStringAPIs.swift.gyb 的文件中,该文件位于一个锁着的文件柜的底部,该文件柜卡在废弃的厕所里,门上有一个标志说 'Beware of the Leopard'。 link
你的问题(和自我回答)有 2 个问题:
在 Swift 的标准库中从未提供过使用 Int
为字符串下标。只要 Swift 存在,此代码就一直无效:
let mySubstring: Substring = myString[1..<3]
新的 String.Index(encodedOffset: )
returns UTF-16(16 位)编码的索引。 Swift 的字符串使用 Extended Grapheme Cluster,它可以使用 8 到 64 位来存储一个字符。表情符号可以很好地演示:
let myString = ""
let lowerBound = String.Index(encodedOffset: 1)
let upperBound = String.Index(encodedOffset: 3)
let mySubstring = myString[lowerBound..<upperBound]
// Expected: Canadian and UK flags
// Actual : gibberish
print(mySubstring)
事实上,得到 String.Index
在 Swift 4 中根本没有改变,无论好坏:
let myString = ""
let lowerBound = myString.index(myString.startIndex, offsetBy: 1)
let upperBound = myString.index(myString.startIndex, offsetBy: 3)
let mySubstring = myString[lowerBound..<upperBound]
print(mySubstring)
- 如果您想在
"palindrome"[1..<3]
和"palindrome"[1...3]
等字符串上使用下标,请使用这些扩展。
Swift 4
extension String {
subscript (bounds: CountableClosedRange<Int>) -> String {
let start = index(startIndex, offsetBy: bounds.lowerBound)
let end = index(startIndex, offsetBy: bounds.upperBound)
return String(self[start...end])
}
subscript (bounds: CountableRange<Int>) -> String {
let start = index(startIndex, offsetBy: bounds.lowerBound)
let end = index(startIndex, offsetBy: bounds.upperBound)
return String(self[start..<end])
}
}
Swift 3
对于 Swift 3 替换为 return self[start...end]
和 return self[start..<end]
。
- Apple 没有将其构建到 Swift 语言中,因为 'character' 的定义取决于字符串的编码方式。一个字符可以是 8 到 64 位,默认通常是 UTF-16。您可以在
String.Index
. 中指定其他字符串编码
This is the documentation Xcode 错误指的是。
基于
Swift 4
extension StringProtocol {
subscript(bounds: CountableClosedRange<Int>) -> SubSequence {
let start = index(startIndex, offsetBy: bounds.lowerBound)
let end = index(start, offsetBy: bounds.count)
return self[start..<end]
}
subscript(bounds: CountableRange<Int>) -> SubSequence {
let start = index(startIndex, offsetBy: bounds.lowerBound)
let end = index(start, offsetBy: bounds.count)
return self[start..<end]
}
}
显着变化:
- 现在是
StringProtocol
的扩展。这使得Substring
等采用者也可以获得这些下标。 - 结束索引从边界的开始索引而不是字符串的开始偏移。这可以防止从
String
的开头遍历两次。index
方法是 O(n),其中 n 是与 i 的偏移量。
在两个
extension String {
subscript(bounds: CountableClosedRange<Int>) -> String {
let lowerBound = max(0, bounds.lowerBound)
guard lowerBound < self.count else { return "" }
let upperBound = min(bounds.upperBound, self.count-1)
guard upperBound >= 0 else { return "" }
let i = index(startIndex, offsetBy: lowerBound)
let j = index(i, offsetBy: upperBound-lowerBound)
return String(self[i...j])
}
subscript(bounds: CountableRange<Int>) -> String {
let lowerBound = max(0, bounds.lowerBound)
guard lowerBound < self.count else { return "" }
let upperBound = min(bounds.upperBound, self.count)
guard upperBound >= 0 else { return "" }
let i = index(startIndex, offsetBy: lowerBound)
let j = index(i, offsetBy: upperBound-lowerBound)
return String(self[i..<j])
}
}
extension String {
subscript(bounds: CountableClosedRange<Int>) -> String {
let lowerBound = max(0, bounds.lowerBound)
guard lowerBound < self.count else { return "" }
let upperBound = min(bounds.upperBound, self.count-1)
guard upperBound >= 0 else { return "" }
let i = index(startIndex, offsetBy: lowerBound)
let j = index(i, offsetBy: upperBound-lowerBound)
return String(self[i...j])
}
subscript(bounds: CountableRange<Int>) -> String {
let lowerBound = max(0, bounds.lowerBound)
guard lowerBound < self.count else { return "" }
***let upperBound = min(bounds.upperBound, self.count-1)***
guard upperBound >= 0 else { return "" }
let i = index(startIndex, offsetBy: lowerBound)
let j = index(i, offsetBy: upperBound-lowerBound)
return String(self[i..<j])
}
}
你得到这个错误是因为范围内的下标结果是
Substring?
不是 Substring
。
您必须使用以下代码:
let myString: String = "foobar"
let mySubstring: Substring? = myString[1..<3]
您可以将字符串转换为字符数组...
let aryChar = Array(myString)
然后你得到所有的数组功能...