Introdução: A "armadilha" que espera cada desenvolvedor Swift
\n\nImagine a situação: você está escrevendo código em Swift com confiança, tudo está indo bem, e de repente você precisa pegar os três primeiros caracteres de uma string. Você, sem pensar, escreve algo como myString[0..<3] — e recebe... um erro de compilação. Familiar?
Bem-vindo ao mundo do String substring em Swift. Este é um daqueles tópicos que causam verdadeira dor em iniciantes e até mesmo em desenvolvedores experientes vindos de outras linguagens. A pergunta "How does String substring work in Swift" no Stack Overflow acumulou milhares de visualizações — e não é por acaso.
\n\nNeste artigo, vamos analisar por que o Swift é tão "estranho" ao trabalhar com substrings, como usar corretamente o substring em Swift e quais novos recursos surgiram nas versões mais recentes. Vamos lá!
\n\nPor que o Swift não permite simplesmente cortar um pedaço da string?
\n\nNa maioria das linguagens (Python, JavaScript, C#), uma string é apenas um array de caracteres. Quer uma substring? Escreva str[0:3] e obtenha o resultado. No Swift, é diferente.
A razão está no trabalho com Unicode. Strings em Swift não são apenas bytes ou caracteres ASCII. Elas consistem em clusters de grafemas (grapheme clusters). Um único caractere que o usuário vê (por exemplo, "é" ou "👍🏽") pode ocupar vários Character ou até vários Unicode.Scalar. Imagine que você corta uma string no meio de um desses clusters — você obterá dados corrompidos.
Por isso, o Swift usa índices (String.Index), em vez de números inteiros. Isso garante que você nunca divida um caractere ao meio.
Fundamentos: String.Index e extração simples de substring
\n\nVamos começar com um exemplo básico. Suponha que temos uma string:
\n\nlet fullString = "Olá, Swift!"\n// Queremos pegar a palavra "Swift"\nlet startIndex = fullString.index(fullString.startIndex, offsetBy: 5)\nlet endIndex = fullString.index(fullString.startIndex, offsetBy: 10)\nlet substring = fullString[startIndex..<endIndex]\nprint(substring) // Exibirá: "Swift"\n\nObserve: substring tem o tipo Substring, não String. Esta é uma diferença importante. Substring é uma "janela" para a string original. Ela não copia os dados, apenas faz referência a uma parte da memória da string original. Isso é super eficiente, mas pode levar a vazamentos de memória se a string original for grande e a substring for pequena.
Para transformar Substring em uma String completa, basta usar o inicializador:
let newString = String(substring)\nprint(newString) // "Swift"\n\nAçúcar sintático: RangeExpression
\n\nEscrever index(offsetBy:) toda vez é cansativo. Felizmente, o Swift permite usar formas mais curtas com RangeExpression.
Operador ... (ClosedRange)
\nlet str = "Olá, Mundo!"\nif let range = str.range(of: "Mundo") {\n let mundoSubstring = str[range]\n print(mundoSubstring) // "Mundo"\n}\n\nIntervalos parciais (Partial Range)
\nQuer pegar tudo até um determinado índice ou depois dele? Fácil:
\nlet texto = "Swift Programação"\nlet prefixo = texto[..<texto.index(texto.startIndex, offsetBy: 5)]\nprint(prefixo) // "Swift"\n\nlet sufixo = texto[texto.index(texto.startIndex, offsetBy: 6)...]\nprint(sufixo) // "Programação"\n\nObserve: prefixo e sufixo também são Substring.
Métodos integrados: prefix, suffix, dropFirst, dropLast
\n\nO Swift fornece métodos convenientes que eliminam a necessidade de calcular índices manualmente. Eles retornam Substring.
- \n
str.prefix(5)— primeiros 5 caracteres. \n str.suffix(3)— últimos 3 caracteres.
Blogs
Book Recommendations
Leia também
Salários de desenvolvedores Kotlin na Rússia: panorama do mercado 2024