Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does String.subscript(_:) require the types `String.Index` and `Int` to be equal when there is no `Int` involved?

I fail to understand the problem Xcode is confronting me with in this line:

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

template is a String and iterationSubstring and substring are Substrings of template. Xcode highlights the opening square bracket with the following message:

Subscript 'subscript(_:)' requires the types 'Substring.Index' and 'Int' be equivalent

The error message does not make any sense to me. I try to obtain a Substring by creating a Range<String.Index> with the [template.startIndex...template.endIndex] subscript. How is this related to Int? And why does the same pattern work elsewhere?


Xcode playground code reproducing the problem:

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]

After all I have a template string and two substrings of it. I want to get a String ranging from the end of the first Substring to the start of the second Substring.

like image 331
Peter Avatar asked Feb 06 '20 12:02

Peter


1 Answers

The current version of Swift works with the Substring struct which is a sliced String.

The error seems to be misleading and occurs if you are going to assign a (range-subscripted) Substring to a String variable.

To fix the error create a String from the Substring

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

Nevertheless you are strongly discouraged from creating ranges with indices from different strings (iterationSubstring and substring). Slice the main string, the indices are preserved.


The crash in the second (meanwhile deleted) example occurred because the last character of a string is at index before endIndex, it's

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

or shorter

template[template.startIndex...]
like image 155
vadian Avatar answered Nov 19 '22 18:11

vadian