【问题标题】:Why does String.subscript(_:) require the types `String.Index` and `Int` to be equal when there is no `Int` involved?为什么 String.subscript(_:) 在不涉及 `Int` 的情况下要求 `String.Index` 和 `Int` 类型相等?
【发布时间】:2020-05-22 12:41:14
【问题描述】:

我无法理解 Xcode 在这一行中遇到的问题:

iteration.template = template[iterationSubstring.endIndex...substring.startIndex]

templateStringiterationSubstringsubstringSubstrings 的 template。 Xcode 使用以下消息突​​出显示左方括号:

下标 'subscript(_:)' 要求类型 'Substring.Index' 和 'Int' 等价

错误消息对我没有任何意义。我尝试通过创建带有[template.startIndex...template.endIndex] 下标的Range<String.Index> 来获得Substring。这与Int 有什么关系?为什么相同的模式在其他地方也有效?


Xcode Playground 代码重现问题:

import Foundation
let template = "This is an ordinary string literal."

let firstSubstringStart = template.index(template.startIndex, offsetBy: 5)
let firstSubstringEnd = template.index(template.startIndex, offsetBy: 7)
let firstSubstring = template[firstSubstringStart...firstSubstringEnd]

let secondSubstringStart = template.index(template.startIndex, offsetBy: 10)
let secondSubstringEnd = template.index(template.startIndex, offsetBy: 12)
let secondSubstring = template[secondSubstringStart...secondSubstringEnd]

let part: String = template[firstSubstring.endIndex...secondSubstring.startIndex]

毕竟我有一个模板字符串和它的两个子字符串。我想得到一个String,范围从第一个Substring 的结尾到第二个Substring 的开头。

【问题讨论】:

  • 您的财产template是什么类型的?似乎它被声明为String。主要问题是使用ClosedRange 而不是Range 和类型不匹配试图将Substring 分配给String 或两者的组合。尝试let part: String = template[template.startIndex...template.endIndex] 会抛出Subscript 'subscript(_:)' requires the types 'String.Index' and 'Int' be equivalent
  • @MartinR 我更新了操场代码以在第一个 sn-p 中重现我的问题。
  • @LeoDabus template 确实是String。我忘了提那个。事实上,这是一个明显的类型不匹配。哎呀。 Xcode 真的让我分心了。

标签: swift xcode foundation


【解决方案1】:

当前版本的 Swift 使用 Substring 结构,它是一个切片的 String

如果您要将(范围下标的)Substring 分配给 String 变量,则该错误似乎具有误导性。

要修复错误,请从 Substring 创建一个 String

iteration.template = String(template[iterationSubstring.endIndex...substring.startIndex])

尽管如此,强烈建议您不要使用来自不同字符串的索引创建范围(iterationSubstringsubstring)。切片主字符串,索引被保留。


第二个(同时被删除的)示例中发生崩溃是因为字符串的最后一个字符endIndex之前的索引处,它是

template[template.startIndex..<template.endIndex] 

或更短的

template[template.startIndex...]

【讨论】:

  • 确实是误导!我试图将Substring 分配给String。将其包装成String() 解决了这个问题。我仍然需要习惯这一点。正如@MartinR 建议的那样,我也会详细说明我最初的问题。
  • 编辑后:partSubstring,即使您注释 String 也会导致上述错误。删除注释并使用String(...) 创建一个字符串。要获取子字符串,您还可以编写 template[firstSubstringEnd..&lt;secondSubstringStart]
  • 在真实的项目代码中,part 的等价物是对象上的 String 属性,用于将事物分开。我在操场代码中添加了类型注释以进行解释。产生误导性错误是必要的。
  • 顺便可以写短一点:let firstSubstringEnd = template.index(template.startIndex, offsetBy: 8); let secondSubstringStart = template.index(template.startIndex, offsetBy: 10); let part = template[firstSubstringEnd...secondSubstringStart]
  • 这是错误SR-11702,已在master上修复。
猜你喜欢
  • 1970-01-01
  • 2014-08-27
  • 2011-09-05
  • 1970-01-01
  • 2018-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-28
相关资源
最近更新 更多