【问题标题】:Create a SUBSCRIPT EXTENSION for String with integer Range为具有整数范围的字符串创建一个 SUBSCRIPT EXTENSION
【发布时间】:2019-02-11 13:55:55
【问题描述】:

这个具有两个整数的解决方案有效,但我想改用一个范围:

extension String {
   subscript(start: Int, end: Int) -> String? {
      return String(self[index(startIndex, offsetBy: start#)...index(startIndex, offsetBy: end)])
   }
}

以下两个解决方案使用范围,但都产生相同的错误,不是在扩展代码中,而是在尝试使用它时:

'subscript' 不可用:不能用整数范围为字符串下标。

这是一个荒谬的错误,它基本上告诉我 String 没有范围下标,而实际上我只是创建了它,所以它确实存在。

extension String {
   subscript(range: Range<String.IndexDistance>) -> String? {
      return String(self[index(startIndex, offsetBy: range????.startIndex)...index(startIndex, offsetBy: range????.endIndex)])
   }

   subscript(range: Range<Int>) -> String? {
      return String(self[index(startIndex, offsetBy: range.startIndex)...index(startIndex, offsetBy: range.endIndex)])
   }
}

let greeting = "Hello, World"
print(greeting[0...4]) // should print "Hello"

【问题讨论】:

标签: swift string range


【解决方案1】:

编译器错误并非意外。范围0...4 的类型不是Range&lt;Int&gt;,而是ClosedRange&lt;Int&gt;,它们是不相关的类型。如果您修改您的 subscript 实现以采用 ClosedRange&lt;Int&gt; 而不是 Range&lt;Int&gt;,您的代码可以编译并正常工作。

extension String {
    subscript(range: ClosedRange<Int>) -> String? {
        return String(self[index(startIndex, offsetBy: range.lowerBound)...index(startIndex, offsetBy: range.upperBound)])
    }
}

如果您想返回nil,以防任何索引产生范围超出范围异常,您可以使用index(_:,offsetBy:,limitedBy:)

extension String {
    subscript(range: ClosedRange<Int>) -> String? {
        guard let startIndex = index(startIndex, offsetBy: range.lowerBound,limitedBy: endIndex), let endIndex = index(startIndex, offsetBy: range.upperBound,limitedBy: endIndex) else { return nil }
        return String(self[startIndex...endIndex])
    }
}

【讨论】:

  • 不错。谢谢你,大卫。您将如何添加一个将 range.endIndex 与 String 的计数进行比较的保护语句,以防止出现 index-out-of-range 错误?类型似乎不兼容。
  • 哦...它不太好用。我正在尝试使用以下代码: let numbers = "0123456789" numbers[0...4] // 正确:"01234" numbers[2...2] // 不正确:"234"
  • @Hikarus 请说明“不太好用”。使用我的测试输入,它工作得很好
  • 对不起,我在评论完成前不小心按了回车。我正在尝试使用 [2...3] 或 [2],但它不会产生正确的结果...
  • 没关系。我在解决方案链接中得到了它:)
【解决方案2】:

正确答案基于@Dávid Pásztor 的代码:

extension String {
    subscript(range: ClosedRange<Int>) -> String? {
        guard let startIdx = index(startIndex, offsetBy: range.lowerBound,limitedBy: endIndex), let endIdx = index(startIndex, offsetBy: range.upperBound,limitedBy: endIndex) else { return nil }
        return String(self[startIdx...endIdx])
     }   
}

这里是错误发生的地方

let startIndex = index(startIndex, offsetBy: range.lowerBound,limitedBy: endIndex)

// startIndex shall be self. startIndex, name does matter
let endIndex = index(startIndex, offsetBy: range.upperBound,limitedBy: endIndex) 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-31
    • 2019-11-24
    • 2015-05-15
    • 2017-08-20
    • 1970-01-01
    • 2012-09-04
    相关资源
    最近更新 更多