Strings e Caracteres

Uma String é uma série de caracteres, como "hello, world" ou "albatross". as strings no Swift são representados pelo tipo String. O conteúdo de uma string pode ser acessado de várias maneiras, incluindo como uma coleção de caracteres.

Os tipos de String e Character do Swift fornecem uma forma rápida e compatível com Unicode para trabalhar com texto em seu código. A sintaxe para a criação e manipulação de String é leve e legível, com uma sintaxe literal semelhante a linguagem C. A concatenação de strings é tão simples como combinar duas strings com o operador + e a possibilidade da string mudar é gerenciada escolhendo entre uma constante ou uma variável (isso significa que strings apontadas por variáveis podem mudar, enquanto constantes não), assim como qualquer outro valor em Swift. Você também pode usar as strings para inserir valores como constantes, variáveis, valores literais e expressões para criar strings mais longas, em um processo conhecido como interpolação de strings. Isso facilita a criação de strings personalizados para exibição, armazenamento e impressão.

Apesar desta simplicidade de sintaxe, o tipo String do Swift é uma implementação rápida e moderna. Cada string é composta de caracteres Unicode independentes de codificação e fornece suporte para acessar esses caracteres em várias representações Unicode.

Nota

O tipo String do Swift é uma ponte com a classe NSString do pacote Foundation. O Foundation também estende String para expor os métodos definidos pelo NSString. Isto significa que, se você importar o pacote Foundation, você pode acessar os métodos da classe NSString na String sem castings.Veremos mais a respeito de como trabalhar com tipo String junto com tipos do Objective-C mais adiante neste livro.

Strings literais

Você pode incluir valores do tipo String predefinidos dentro do seu código como um valor do tipo string literal. Um valor literal do tipo string é uma sequência de caracteres que começa e termina com aspas duplas “”. Use um literal como um valor inicial para uma constante ou variável:

Note que o Swift consegue inferir o tipo String para a constante someString porque é inicializado com um valor literal do tipo String.

Strings literais com multiplas linhas

Se você precisa de uma string que tenha várias linhas, use uma string com multiplas linhas - uma seqüência de caracteres cercada por três aspas duplas “““:

Uma string literal com multiplas linhas inclui todo o seu conteúdo entre as aspas de abertura e de fechamento. Ela começa na primeira linha após as aspas de abertura """ e termina na linha antes das aspas de fechamento, o que significa que nenhuma das strings abaixo começa ou termina com uma quebra de linha:

Quando seu código fonte inclui uma quebra de linha dentro de uma string literal com multiplas linhas, esse intervalo de linha também aparece no valor da string. Se você quiser usar quebras de linha para tornar seu código fonte mais fácil de ler, mas você não deseja que as quebras de linha façam parte do valor da string, escreva uma barra invertida \ no final dessas linhas:

Para criar uma string literal com multiplas linhas que começa ou termina com uma quebra de linha, escreva uma linha em branco como primeira ou última linha. Por exemplo:

Uma string literal com multiplas linhas pode ser recuada para combinar o código ao seu redor. O espaço em branco antes das aspas de fechamento """ diz ai Swift quais espaços em branco ignorar antes de todas as outras linhas. No entanto, se você escrever espaços em branco no início de uma linha, além do que está definido antes das aspas de fechamento, esses espaços em branco serão incluídos.

No exemplo acima, mesmo que toda string esteja com identação, a primeira e a última linha na string não começam com nenhum espaço em branco. A linha do meio tem mais indentação do que as aspas de fechamento, então começa com esse recuo adicional de quatro espaços.

Caracteres especiais em strings literais

As strings literais podem incluir os seguintes caracteres especiais:

  • Os caracteres especiais de escape \0 (caractere nulo), \ (barra invertida), \t (tabulacao horizontal), \n (quebra de linha), \r (antigo quebra de linha), \"" (aspas dupla) e \" (aspas simples )

  • Um caractere Unicode arbitrário, escrito como \u{n}, onde n é um número hexadecimal de 1-8 dígitos com um valor igual a de código Unicode válido (o conceito de Unicode será discutido abaixo)

O código abaixo mostra quatro exemplos desses caracteres especiais. A constante wiseWords contém dois caracteres de aspas duplas. As constantes dollarSign, blackHeart e sparklingHeart demonstram o formato Unicode:

Uma vez que as strings literais com multiplas linhas usam três aspas duplas em vez de apenas uma, você pode incluir uma aspa dupla " dentro de uma string literal com multiplas linha sem escapar. Para incluir o texto """ em uma string de várias linhas, escape pelo menos uma das aspas. Por exemplo:

Inicializando strings vazias

Para criar uma string vazia como ponto de partida para a construção de uma string mais longa, atribua uma string literal vazia a uma variável ou inicialize uma nova instância de String com o inicializador vazio:

Descubra se um valor de uma string está vazio, verificando sua propriedade booleana isEmpty:

Mutabilidade de Strings

Você pode indicar se uma determinada string pode ser modificada (ou mutada) atribuindo-a a uma variável (que indica que ela pode ser modificada) ou a uma constante (que indica que ela não pode ser modificada):

Nota

Essa abordagem é diferente da mutação de Strings em Objective-C e Cocoa, onde você escolhe entre duas classes (NSString e NSMutableString) para indicar se uma string pode ser mutada ou não.

Strings são do tipo Value

A String do Swift é do tipo Value, isto é, se você criar uma nova String, esse valor será copiado quando for passado para uma função ou método, ou quando for atribuído a uma constante ou variável. Em cada uma desses casos, uma nova cópia do valor da string existente é criada e essa nova cópia é passada ou atribuída, e não o valor original. Os tipos Value serão explicados mais adiante neste livro.
O comportamento da String do Swift, por padrão, garante que quando uma função ou método passa uma string, seja certeza que você possui esse valor exato, independentemente de onde ele veio. Você pode ter certeza de que a string que você passou não será modificada, a menos que você a modifique.

Por trás das cenas, o compilador do Swift otimiza o uso da String para que a cópia real ocorra somente quando for absolutamente necessário. Isso significa que você sempre obtém excelente desempenho ao trabalhar com strings comoValues.

Trabalhando com caracteres

Caracteres são simbolos simples e isolados, podendo ser uma letra ou uma pontuação ou até mesmo simbolos como emojis e afins. Em Swift, os caracteres são representados pelo tipo Character. Você pode acessar os valores individuais que são caracteres de uma string iterando sobre ela com um loop usando o comando for-in :

O comando de loop for-in será descrito mais adiante neste livro.

Alternativamente, você pode criar uma constante ou variável que armazena caracteres a partir de um valor literal como se fosse uma String, mas fornecendo apenas um único caractere e uma anotação de tipo para o tipo Character:

Valores do tipo String podem ser construídos através de um array de caracteres como argumento para seu inicializador:

Concatenando Strings e Caracteres

Valores do tipo Stringpodem ser adicionados junto (ou concatenados) com o operador de adição + para criar um novo valor para a string:

Você também pode adicionar um valor do tipo String a uma variável do tipo String existente com o operador de atribuição e adição +=:

Você pode adicionar um valor do tipo Character numa variável do tipo Stringusando o método append():

Nota

Você não pode adicionar uma Stringou Characterpara um Characterque já existe porque seu valor só pode conter um único caractere.

Se você estiver usando strings literais com várias linhas para criar as linhas de uma string mais longa e você deseja que cada linha da seqüência termine com uma quebra de linha, inclua uma última linha. Por exemplo:

No código acima, concatenar a constante badStart com a constante end produz uma string de duas linhas, que não é o resultado desejado. Como a última linha de badStart não termina com uma quebra de linha, essa linha é combinada com a primeira linha da constante end. Em contraste, ambas as linhas de goodStart terminam com uma quebra de linha, então, quando combinada com end, o resultado tem três linhas, como esperado.

Interpolação de Strings

A interpolação de strings é uma maneira de construir uma nova string a partir de uma mistura de constantes, variáveis, valores literais e expressões, incluindo seus valores dentro de uma string literal. Você pode usar a interpolação de strings com strings de uma única linha ou com várias linhas. Cada item que você insere na string deve ser envolvido em um par de parênteses, prefixados por uma barra invertida \ :

No exemplo acima, o valor da constante multiplier é inserido em uma string literal como \(multiplier). Este placeholder é substituído pelo valor da constante multiplier quando a interpolação é avaliada para criar uma String real.
O valor de multiplier também faz parte de uma expressão maior no final da string. Esta expressão calcula o valor de Double(multiplier)*2.5 e insere o resultado 7.5 na string. Neste caso, a expressão é escrita como \(Double (multiplicador) * 2.5) quando está incluída dentro da string literal.

Nota

As expressões que você escreve dentro de parênteses dentro de uma string interpolada não podem conter uma barra invertida \, ou quebra de linha ou retorno para indentação. No entanto eles podem conter outras strings literais.

Unicode

O Unicode é um padrão internacional para codificação, representação e processamento de texto em diferentes sistemas de escrita. Ele permite que você represente quase qualquer caractere de qualquer idioma em uma forma padronizada e também permite ler e escrever esses caracteres para uma fonte externa, como um arquivo de texto ou uma página da Web. Os tipos Charactere String do Swift são totalmente compatíveis com Unicode, conforme descrito nesta seção.

Unicode Escalares

Por trás das cenas, o tipo Stringnativo do Swift é construído a partir de valores Unicode escalares (que se juntam, ou seja, escalam, para criar algo maior). Um Unicode escalar é um número único de 21 bits para um caractere ou emoji, como U+0061 para LATIN SMALL LETTER A a, ou U+1F425 para FRONT-FACING BABY CHICK 🐥.

Nota

Um Unicode escalar é qualquer código Unicode no intervaloU+0000 a U+D7FF inclusiveU+E000 a U+10FFFF. Os Unicode escalares não incluem os Unicode surrogate, que são os códigos no intervaloU+D800a U+DFFF.

Observe que nem todos os Unicode escalares de 21 bits são atribuídos a um caractere, alguns escalares são reservados para futuras atribuições. Os escalares que foram atribuídos a um caractere tipicamente também têm um nome, comoLATIN SMALL LETTER AeFRONT-FACING BABY CHICKnos exemplos acima.

Conjuntos ampliados de grafemas

Cada instância do tipo Character do Swift representa um único conjunto ampliado de grafemas. Um conjunto ampliado de grafemas é uma seqüência de um ou mais Unicode escalares que (quando combinados) produzem um único caractere legível para humanos.

Aqui está um exemplo. A letra é pode ser representada como o Unicode escalar é LATIN SMALL LETTER E WITH ACUTE ou U+00E9. No entanto, a mesma letra também pode ser representada como um par de escalares - uma letra padrão e LATIN SMALL LETTER E, ou U+0065, seguido do escalar COMBINING ACUTE ACCENT ou U+0301. O escalar COMBINING ACUTE ACCENT é aplicado graficamente ao escalar que o precede, transformando a caractere e em um é quando ele é processado por um sistema de renderização de texto com reconhecimento Unicode.

Em ambos os casos, a letra é é representada como um único valor do tipo Characterdo Swift que representa um conjunto ampliado de grafemas. No primeiro caso, o conjunto contém um único escalar, no segundo caso, é um conjunto de dois escalares:

Os conjuntos ampliados de grafemas são uma maneira flexível de representar muitos caracteres complexos como um único valor do tipo Character. Por exemplo, as sílabas Hangul do alfabeto coreano podem ser representadas como uma seqüência pré composta ou decomposta. Ambas as representações se qualificam como um único valor Character no Swift:

Os conjuntos ampliados de grafemas permitem que os escalares usem marcas de fechamento como COMBINING ENCLOSING CIRCLE ouU+20DD incluam outros Unicode escalares como parte de um único valor Character:

Os Unicode escalares para símbolos de indicadores regionais podem ser combinados em pares para criar um único valor de Character, como a combinação de REGIONAL INDICATOR SYMBOL LETTER U U+1F1FA e REGIONAL INDICATOR SYMBOL LETTER S U+1F1F8:

Contando Caracteres

Para recuperar uma contagem dos valores do tipo Characterem uma string, use a propriedade countda structure String:

Note que o uso de conjuntos ampliados de grafemas no Swift para valores do tipo Charactersignifica que a concatenação e modificação de strings nem sempre podem afetar a contagem de caracteres de uma string.

Por exemplo, se você inicializar uma nova string com a palavra de quatro caracteres cafe, em seguida, anexar um COMBINING ACUTE ACCENT U+0301 ao final da string, a seqüência resultante ainda terá uma contagem de caracteres de 4, com um quarto caractere de é, e não e:

Nota

Conjuntos ampliados de grafemas podem ser compostos por vários Unicode escalares. Isso significa que caracteres diferentes e representações diferentes do mesmo caractere podem exigir quantidades diferentes de memória para armazenar. Por isso, os caracteres no Swift não ocupam a mesma quantidade de memória dentro da representação de uma string. Como resultado, o número de caracteres em uma string não pode ser calculado sem iterar através da String para determinar seus limites do conjunto ampliado de grafemas. Se você estiver trabalhando com valores String particularmente longos, esteja ciente de que a propriedadecountdeve iterar sobre os Unicode escalares em toda a string para determinar os caracteres dela.

A contagem dos caracteres retornados pela propriedade count não é sempre a mesma que a propriedadelengthde um NSStringque contém os mesmos caracteres. O comprimento de um NSStringé baseado no número de unidades de código de 16 bits dentro da representação UTF-16 da String e não no número de conjuntos ampliados de grafemas Unicode dentro da string.

Acessando e modificando uma String

Você pode acessar e modificar uma string através de seus métodos e propriedades, ou usando sintaxe de subscript.

Indices de uma String

Cada Stringtem um índice associado do tipoString.Index, que corresponde à posição de cada caractere na String.

Conforme menciona'do acima, diferentes caracteres podem exigir diferentes quantidades de memória para serem armazenados, portanto, para determinar qual caractere está em uma posição específica, você deve iterar sobre cada Unicode escalar desde o início ou do fim dessa String. Por esse motivo, as Strings em Swift não podem ser indexadas por valores inteiros.

Use a propriedade startIndexpara acessar a posição do primeiro Characterda String. A propriedade endIndexé a posição após o último caractere em uma string. Como resultado, a propriedade endIndex não é um argumento válido para um subscript de uma string. Se uma string estiver vazia, startIndexe endIndexsão iguais.

Você pode acessar os índices antes e depois de um determinado índice usando os métodos index(before: ) e index(after: ) da structure String. Para acessar um índice mais distante de um índice específico, você pode usar o método index(_: offsetBy: ) em vez de chamar um desses métodos várias vezes.

Você pode usar a sintaxe de subscript para acessar um caractere em um índice da string em particular.

Tentar acessar um índice fora do range de uma String ou um Character irá disparar um erro de tempo de execução.

Use a propriedade indices para acessar todos os índices de caracteres individuais em uma string.

Nota

Você pode usar as propriedades startIndexe endIndexe os métodos index(before:) , index(after: ) eindex(_: offsetBy: ) em qualquer tipo que esteja em conformidade com o protocolo Collection. Isso inclui String, como mostrado aqui, bem como tipos de coleção, como Array, Dictionarye Set.

Inserindo e Removendo

Para inserir um caractere em uma string em um índice específico, use o métodoinsert(_: at: ) e para inserir o conteúdo de outra string em um índice específico, use o método insert(contentsOf: at: ).

Para remover um único caractere de uma string em um índice específico, use o método remove(at :)e para remover uma substring em um intervalo específico, use o método removeSubrange (_ :) :

Nota

Você pode usar os métodosinsert(_: at:), insert(contentsOf: at:), remove(at :) e removeSubrange(_ :) em qualquer tipo que esteja em conformidade com o protocolo RangeReplaceableCollection. Isso inclui String, como mostrado aqui, bem como tipos de coleção, como Array, Dictionarye Set.

Substrings

Quando você obtém uma Substringde uma String, por exemplo, usando um subscript ou um método como prefix(_:) , o resultado é uma instância de Substring, não outra String. Substrings no Swift possuem a maioria dos métodos como strings, o que significa que você pode trabalhar com substrings da mesma maneira que você trabalha com strings. No entanto, ao contrário das strings, você deve usar substrings apenas por um curto período de tempo enquanto executa ações em uma string. Quando estiver pronto para armazenar o resultado por mais tempo, você converte a substring em uma instância de String. Por exemplo:

Assim como Strings, cada Substringpossui uma região de memória onde os caracteres que compõem a substring são armazenados. A diferença entre strings e substrings é que, como uma otimização de desempenho, uma substring pode reutilizar parte da memória usada para armazenar a string original ou parte da memória usada para armazenar outra substring. (As strings têm uma otimização similar, mas se duas strings compartilham o mesmo espaço na memória, elas são iguais). Essa otimização de desempenho significa que você não precisa pagar o custo de desempenho de copiar a memória até que você modifique a string ou a substring. Como mencionado acima, as substrings não são adequadas para o armazenamento a longo prazo, porque reutilizam o armazenamento da string original, toda a string original deve ser mantida na memória, desde que qualquer uma das suas substrings esteja sendo usada.

No exemplo acima, greetingé uma String, o que significa que ela tem uma região de memória onde os caracteres que compõem a string são armazenados. Como beginning é uma Substringde greeting, ela reutiliza a memória que greetingusa. Em contrapartida, newStringé uma Stringe quando é criada a partir da Substring, possui seu próprio armazenamento. A figura abaixo mostra essas relações:

Nota

Ambos os tipos Stringe Substringimplementam o protocolo StringProtocol, o que significa que muitas vezes é conveniente para as funções de manipulação de strings aceitar um valor do tipo StringProtocol. Você pode chamar essas funções passando um valor Stringou Substring.

Comparando Strings

O Swift fornece três maneiras de comparar valores de texto: igualdade de strings e caracteres, igualdade de prefixo e igualdade de sufixo.

Igualdade de String e Character

A igualdade de strings e caracteres é verificada com o operador "igual a" == e o operador "não igual" !=, Conforme descrito na seção de Operadores de comparação:

Dois valores do tipo String(ou dois valores do tipo Character) são considerados iguais se os seus conjuntos ampliados de grafema são canonicamente equivalentes. Conjuntos ampliados de grafemas são canonicamente equivalentes se eles têm o mesmo significado e aparência lingüística, mesmo que sejam compostas por diferentes Unicode escalares nos bastidores.

Por exemplo, o Unicode LATIN SMALL LETTER E WITH ACUTE U+00E9 é canonicamente equivalente a LATIN SMALL LETTER E U+0065, seguido de COMBINING ACUTE ACCENT U+0301. Ambos esses grafemas ampliados são formas válidas de representar o caractere é, portanto, são considerados canonicamente equivalentes:

Por outro lado, o Unicode LATIN CAPITAL LETTER A U+0041, ou "A", como usado em inglês, não é equivalente a CYRILLIC CAPITAL LETTER A U+0410 ou "А", como usado em russo. Os caracteres são visualmente semelhantes, mas não têm o mesmo significado lingüístico:

Nota

Comparações entre strings e caracteres não levam em consideração o Locale(representação da região como forma e internacionalização).

Igualdade de prefixo e sufixo

Para verificar se uma string tem um prefixo ou sufixo particular, chame os métodos hasPrefix(_ :) e hasSuffix(_ :)da structure String, ambos levando um único parâmetro do tipo Stringe retornando um valor booleano.

Os exemplos abaixo consideram uma série de strings que representam os locais de cena dos dois primeiros atos de Romeu e Julieta de Shakespeare:

Você pode usar o método hasPrefix(_ :)com o array romeoAndJuliet para contar o número de cenas no Ato 1 da peça:


Da mesma forma, use o método hasSuffix(_ :) para contar o número de cenas que ocorrem em ou ao redor da mansão de Capulet e da célula de Fr. Lawrence:

Nota

Os métodoshasPrefix(_ :) e hasSuffix(_ :) executam uma comparação de equivalência canônica caractere por caractere entre os conjuntos ampliados de grafemas em cada string, conforme descrito na seção de Igualdade de String e Character.

Representação Unicode de Strings

Quando uma string Unicode é gravada em um arquivo de texto ou em algum outro tipo de armazenamento, os Unicode escalares nessa string são codificados em uma das várias formas de codificação definidas pelo Unicode. Cada forma codifica a string em pequenos fragmentos conhecidos como unidades de código. Estes incluem a forma de codificação UTF-8 (que codifica uma string como unidades de código de 8 bits), a forma de codificação UTF-16 (que codifica uma string como unidades de código de 16 bits) e a forma de codificação UTF-32 (que codifica uma string como unidades de código de 32 bits).

O Swift fornece várias maneiras diferentes de acessar representações Unicode de strings. Você pode iterar sobre a string como comandofor-inpara acessar seus valores de caracteres individuais como conjuntos ampliados de grafemas Unicode. Este processo é descrito na seção Trabalhando com caracteres.

Como alternativa, acesse o valor de uma string em uma das três outras representações compatíveis com Unicode:

  • Uma coleção de unidades de código UTF-8 (acessado através da propriedade utf8da structure String)

  • Uma coleção de unidades de código UTF-16 (acessado através da propriedade utf16 da structure String)

  • Uma coleção de valores Unicode escalares de 21 bits, equivalente a forma de codificação UTF-32(acessado através da propriedade unicodeScalarsda structure String)

Cada exemplo abaixo mostra uma representação diferente da string abaixo, que é composta pelos caracteres D,o,g,!! (DOUBLE EXCLAMATION MARK ou Unicode escalar U+203C) e o caractere 🐶 (DOG FACE ou Unicode scalar U+1F436):

Representação UTF-8

Você pode acessar uma representação UTF-8 da structure Stringao iterar sobre sua propriedade utf8. Essa propriedade é do tipo String.UTF8View, que é uma coleção de valores sem sinal de 8 bits UInt8, um para cada byte na representação UTF-8 da string:

No exemplo acima, os três primeiros valores decimais codeUnit (68, 111, 103) representam os caracteres D, o e g, cuja representação UTF-8 é a mesma que a representação ASCII. Os próximos três valores decimais codeUnit (226, 128, 188) são uma representação UTF-8 na forma de tres bytes do caractere DOUBLE EXCLAMATION MARK. Os últimos quatro valores codeUnit (240, 159, 144, 182) são uma representação UTF-8 na forma de quatro bytes do caractere DOG FACE.

Representação UTF-16

Você pode acessar uma representação UTF-16 da structure Stringao iterar sobre sua propriedade utf16. Essa propriedade é do tipo String.UTF16View, que é uma coleção de valores sem sinal de 16 bits UInt16, um para cada unidade de código de 16 bits na representação UTF-16 da string:

Novamente, os três primeiros valores codeUnit (68, 111, 103) representam os caracteres D, o e g, cujas unidades de código UTF-16 possuem os mesmos valores que na representação UTF-8 da string (porque esses Unicode escalares representam caracteres ASCII ).
O quarto valor codeUnit(8252) é um equivalente decimal do valor hexadecimal 203C, que representa o Unicode escalar U+203C para o caractere DUPLO EXCLAMATION MARK. Este caractere pode ser representado como uma única unidade de código no UTF-16.

O quinto e o sexto valores codeUnit (55357 e 56374) são uma representação em par UTF-16 do caractere . Esses valores são um valor de substituição para U+D83D (valor decimal 55357) e outro para U+DC36 (valor decimal 56374).

Representação Unicode escalar

Você pode acessar uma representação Unicode escalar de um valor do tipo Stringiterando sobre sua propriedade unicodeScalars. Esta propriedade é do tipo UnicodeScalarView, que é uma coleção de valores do tipo UnicodeScalar.
Cada UnicodeScalarpossui uma propriedade value que retorna o valor de 21 bits do scalar, representado por um valor UInt32:


As propriedades value para os três primeiros valores UnicodeScalar(68, 111, 103) representam mais uma vez os caracteres D, o e g .
O quarto valor codeUnit (8252) é novamente um equivalente decimal do valor hexadecimal 203C, que representa o Unicode escalar U+203C para o caractere DOUBLE EXCLAMATION MARK.
A propriedade val do quinto e final UnicodeScalar128054 é um equivalente decimal do valor hexadecimal 1F436, que representa o Unicode scalar U+1F436para o caractere DOG FACE.
Como uma alternativa à consulta de suas propriedades value, cada valor UnicodeScalar também pode ser usado para construir uma nova string, como com a interpolação de strings:

results matching ""

    No results matching ""