Iniciando sua jornada em programação com Swift

Jvitormergulho
Apple Developer Academy | UFPE
13 min readApr 11, 2024

Neste artigo você terá contato os conceitos de:
O que é Programação
Compiladores e Interpretadores
Variáveis e Constantes
Tipos opcionais
Coleções
Estruturas Condicionais
Estruturas de Repetição,
simbora?

O que é Programação?

Computadores são ferramentas extremamente poderosas… e devem ser usadas corretamente.

Primeiramente, é importante entender que o computador em si não é dotado de inteligência. Para que ele faça todas as coisas interessantes que nós usamos no dia a dia (aplicativos de trocas de mensagens, streaming de vídeos, jogos etc.) é necessário que alguém o programe.

Programar é basicamente dizer o que o computador tem que fazer, passo a passo, de forma clara e sem ambiguidades. Afinal, diferente das pessoas, as máquinas não vão entender instruções confusas e fora de ordem.

Você provavelmente já ouviu a ideia de que um algoritmo é uma espécie de “receita de bolo” para o nosso computador. Bem, é mais ou menos essa a pegada.

Para conversar com o computador e informá-lo dos passos que devem ser seguidos, nós usamos linguagens de programação. De forma bem simplificada, essas linguagens são traduzidas para linguagem/código de máquina (código binário, os famosos zeros e uns), que são “entendidos” pelo processador dos nossos amigos metálicos.

O processador é como o cérebro do computador, capaz de executar instruções escritas em código de máquina. Porém, esses códigos não são nem um pouco amigáveis para humanos (imagina ter que programar com zeros e uns…). Por isso, usamos linguagens de “nível mais alto”, que abstraem muitas das complexidades do hardware e nos permitem codificar com rapidez sem perder a precisão que as máquinas requerem.

Elaboração do Autor

No geral, essa tradução (da linguagem de programação para código de máquina) pode se dar antes da execução do programa, traduzindo todo o código de uma vez (por meio de compiladores), ou linha por linha à medida que o programa é executado (por meio dos interpretadores). Há vantagens e desvantagens para as duas abordagens, mas ambas estão presentes em linguagens muito usadas: python é interpretado, enquanto C++ e Swift são linguagens compiladas.

Assim como as linguagens naturais usadas por nós no dia a dia (português, inglês, espanhol etc), há diversas linguagens de programação que surgiram em contextos específicos e que se diferenciam bastante. No entanto, a maioria das linguagens seguem padrões e princípios básicos. Desse modo, o essencial na jornada de programação é entender a lógica por trás dos códigos que você desenvolve.

Mas sabemos que no início é muito comum ficar perdido sobre qual linguagem escolher para começar a aprender, afinal, qual a escolha certa dentre tantas opções populares: Python, Java, Javascript, C, Swift?

Elaboração do Autor

Bem, a resposta é que no fim a escolha não importa tanto, pois os conceitos aprendidos ao longo do caminho são mais relevantes: quando se aprende uma linguagem de programação e se internaliza bem a lógica de programação, você consegue aprender outras linguagens rapidamente.

Programando em Swift

Porém, esse texto é focado em Swift!

Elaboração do Autor

Swift é uma linguagem criada pela Apple em 2014. Atualmente ela suporta todas as plataformas Apple e Linux, mas há muito trabalho sendo feito para expandir ainda mais. Ela é uma linguagem simples e moderna que conta com uma ótima integração com o Xcode, um ambiente de desenvolvimento integrado (IDE) intuitivo e amigável para iniciantes, que traz diversas ferramentas e recursos que auxiliam no desenvolvimento dos seus projetos. Também existem várias ferramentas de aprendizado voltadas para a linguagem, como o SwiftPlaygrounds, que ensina programação em Swift de forma visual e dinâmica. Além de Swift estar crescendo no mercado e ser a melhor linguagem para começar a desenvolver aplicativos para iOS e macOS!

Essas características fazem com que Swift seja uma ótima escolha como primeira linguagem de programação.

Variáveis e Constantes

Podemos entender variáveis e constantes como pequenas caixas na memória do nosso computador que nomeamos para facilitar a escrita dos nossos programas.

Como a própria nomenclatura diz, variáveis são caixas que podemos alterar o valor que armazenam, já as constantes, uma vez que atribuímos valores a elas, não podemos modificar: elas se tornam algo fixo.

Cada variável e constante em Swift armazena um único tipo de dado. Alguns dos tipos fundamentais disponíveis são: Int (números inteiros), Double (números decimais), Bool (valores booleamos, i.e., true ou false) e String (texto).

Elaboração do Autor

Antes de se utilizar variáveis e constantes, devemos declará-las no nosso código. Usamos a palavra “var” para variáveis e “let” para constantes.

var idade = 20
let animal = "gato"

A variável idade armazena dados do tipo inteiro, sendo 20 seu valor atual. A constante animal armazena a string “gato” e, por se tratar de uma constante, não pode ser modificada.

Como idade e animal foram inicializadas (atribuímos um valor a elas utilizando o “símbolo de igual”) assim que foram declaradas, não foi preciso falar explicitamente qual o tipo de dado de cada uma, pois o compilador Swiftinfere essa informação. Mas se quiséssemos declarar uma variável ou constante sem inicializar (sem um valor inicial), então é preciso dizer qual seu tipo de dado.

var altura: Double
let nome: String

Em Swift isso é feito da maneira mostrada acima, com o tipo explicitado após os dois pontos ao final do nome da variável ou constante.

Cada tipo de dado dá suporte a uma série de operações, além de métodos e propriedades específicas. Sem entrar em muitos detalhes, propriedades são como valores que nos dão informações sobre o nosso dado e métodos são operações especiais que podemos realizar com o dado sem nos preocupar com sua implementação (os desenvolvedores da linguagem já deixaram tudo certo para nós). Nós podemos acessar propriedades e métodos ao colocar um ponto depois do nome da nossa variável ou constante.

var int1 = 10
var int2 = -4

var soma = int1 + int2 // 10
var sub = int1 - int2 // 14
var mult = int1 * int2 // -40
int2.mag // 4
int1.isMultiple(of: 5) // true

Como esperado, podemos realizar operações aritméticas com o tipo Int (assim como com Double e "entre" Double e Int).

O exemplo também mostra a propriedade mag, que é usada para se obter o valor absoluto do número inteiro (é como se desconsiderássemos o sinal). Na outra linha usamos isMultiple(), que serve para checar se o número é múltiplo de outro, retornando true no caso positivo e false no negativo.

var palavra1 = "Hello"
var palavra2 = "World"

var frase = palavra1 + " " + palavra2 // "Hello Swift"
palavra1.count // 5
palavra2.upperCased() // WORLD

No caso de strings, nós usamos o símbolo “+” para concatenar, isto é, juntar strings em uma nova, como é exemplificado ao formar “Hello World”, texto armazenado na variável frase. Uma propriedade muito usada é o count, que nos diz a quantidade de letras da string. O último método usado, upperCased(), retorna uma nova string com todos as letras maiúsculas.

Tipos opcionais

Uma das principais preocupações do Swift é com a segurança e boas práticas de programação. Dessa forma, uma das características da linguagem é impedir o uso de objetos que podem assumir o valor nil, similar ao conceito de null em outras linguagens que, de forma simplificada, seria como “vazio” (ou a ausência de um valor válido com o qual poderíamos trabalhar).

Para lidar com isso, existem os chamados tipo opcionais, ou optionals, que são variáveis ou constantes que podem conter valores válidos (uma String, um Int, um Bool etc.) ou nil, que tem o potencial de causar bastante confusão se não for tratado corretamente.

var entrada: String?
entrada = readline()

A variável entrada foi criada como uma string opcional (o que é simbolizado pelo “?” após a declaração de tipo de dado da variável).

Elaboração do Autor

Algumas funções embutidas do Swift retornam tipos opcionais, como no caso do readline(), que serve para ler uma entrada (input) do terminal. Como não temos certeza se o valor lido será uma string válida, ele retorna um opcional, nos alertando para possibilidade de ser nil.

print("A sua entrada foi " + entrada!)

Podemos usar a variável entrada como uma string se colocarmos o símbolo “!” logo após a variável. O print acima não funciona sem a exclamação pois não podemos concatenar uma string com algo que pode ser nil.

A exclamação faz um unwrapping, ou seja, retira o valor que está no tipo opcional e nos permite utilizá-lo como se tivéssemos certeza que ele não é nil. Assim, “entrada!” pode ser tratada como uma string comum (concreta, que existe!) no nosso código.

Uma forma fácil de entender esses conceitos é ver a interrogação como uma incerteza (você não sabe se a variável receberá nil) e a exclamação como um voto de confiança (pode ir em frente, essa variável não assume o valor nil).

Mas muito cuidado!

Existem maneiras mais seguras de fazer um unwrap, pois o operador “!” pode fazer com que seu código compile, mas, se por acaso a variável em que você utilizou a exclamação estiver como nil, haverá um erro em tempo de execução, os famosos runtime Errors. O que pode ser muito mais prejudicial e levar a uma série de comportamentos inesperados.

Uma maneira mais adequada de se lidar com opcionais é comentada após a sessão de estruturas condicionais deste artigo.

Observação: outras operações que retornam opcionais são conversões entre alguns tipos de dados. A esse processo de conversão nós damos o nome de type-casting.

var palavra = "sete"
var numero = 7.7

var stringParaDouble = Double(palavra)
var doubleParaInt = Int(numero)

A conversão de string para double retorna o tipo opcional “Double?”, pois não é certeza que a string tem um número decimal correspondente. No exemplo dado, stringParaDouble é opcional e é inicializada como nil, pois a string “sete” não pode ser convertida para double.

Já doubleParaInt é do tipo Int, não sendo opcional, pois toda conversão de Double para Int é certa: para converter um número decimal para um inteiro, Swift apenas despreza o que tem depois da vírgula e retorna a parte inteira.

Coleções

Muitas vezes queremos armazenar vários valores que se relacionam, sem necessariamente ter que criar uma variável ou constante para cada um separadamente. Nesse caso, é interessante usar um tipo de coleção.

Algumas das coleções disponíveis em Swift são array (também chamado de vetor), tupla, dicionário, e conjunto (set).

A mais simples e usada das coleções é o array. Podemos entender um array como uma lista enumerada que armazena elementos de um único tipo de dado e em que o primeiro item está no índice 0.

var lista: [String]
lista = ["leite", "queijo"]

lista.append("pão")

No caso acima, declaramos um array que armazena strings e depois o inicializamos com os valores “leite”, e “queijo” (índices 0 e 1 respectivamente). O método append na última linha serve para adicionar o elemento “pão” ao final da lista (criando o elemento de índice 2).

var primeiroItem = lista[0] // leite
var terceiroItem = lista[2] // pão

Usamos os índices numéricos entre colchetes para acessar itens específicos armazenados no nosso array. Vemos que lista[0] retorna o valor “leite”, que se trata do primeiro item da nossa lista. Assim, ele pode ser armazenado em outra variável e manipulado separadamente.

lista[1] = "tomate" // substitui "queijo" por "tomate"

Uma maneira de modificar os conteúdos da lista é como mostrado acima, atribuindo um novo valor à posição do array especificada, sobrescrevendo o que estava armazenado anteriormente.

Há diversas outras operações que podemos fazer com cada tipo de coleção. Além disso, cada coleção tem características próprias, sendo mais adequadas para propósitos específicos:

  • Podemos usar tuplas para armazenar valores (de tipos diferentes ou não) em um grupo onde a ordem dos elementos geralmente está ligada a um significado, isto é, a posição dos elementos na tupla é extremamente importante.
  • Os sets armazenam valores distintos do mesmo tipo sem definir uma ordem específica.
  • Com dicionários podemos fazer um mapeamento entre uma chave e um valor — que podem ser de tipos distintos.

Estruturas Condicionais

Em nossos programas é muito comum ter que tomar decisões: se algo acontecer vá por esse caminho, caso contrário faça outra coisa. Assim como caminhos em uma estrada que devem ser seguidos para se chegar a certo destino.

Elaboração do Autor

Justamente para nos auxiliar nesse sentido existem as estruturas condicionais.

A estrutura condicional mais usada é o if-else. Ela funciona da seguinte maneira:

if <condição> { bloco de código no caso perdadeiro }

else { bloco de código no caso falso }

if num > 100{
print("Maior que 100")
} else {
print("Menor que 100")
}

O código dentro das chaves após o if só é executado caso a condição seja verdadeira, ou seja, se seu valor for true. Daí, percebemos que a condição deve ser composta por algo que retorna um dado do tipo Bool e que, desse modo, pode ser “valorado” como true ou false.

Condições podem ser criadas utilizando operadores lógicos, como o maior-que do exemplo. Poderíamos checar uma igualdade, desigualdade, menor-que, menor-ou-igual, etc. Além disso também é possível criar expressões mais complexas ao utilizar operadores lógicos como “&” E “||”, que são as operações de E e OU respectivamente.

Outra possibilidade é switch. Uma forma fácil de entender essa estrutura é pensar em vários ifs, um seguido do outro.

var fruta = "banana"
let descricao: String

if num == "banana" {
descricao = "rica em potácio"
}
if num == "limão" {
descricao = "muito cítrica"
}
if num == "uva" {
descricao = "impossível comer só uma"
}
else {
descricao = "não conheço essa fruta"
}

Ao invés da construção acima, podemos utilizar switch e simplificar bastante as coisas.

var fruta = "banana"
let descricao: String

switch fruta {
case "banana":
descricao = "rica em potácio"
case "limão":
descricao = "muito cítrica"
case "uva":
descricao = "impossível comer só uma"
default:
descricao = "não conheço essa fruta"
}

O valor após o switch, onde está a variável fruta no exemplo, é comparado com cada um dos valores dos cases e se a comparação for verdadeira (se os valores forem iguais), então o código após o case correspondente é executado. Se o valor de nenhum case for correspondente, então o código do default, o caso padrão, é executado. Assim, o default funciona como o else em um if, sendo utilizado se nenhuma comparação foi verdadeira.

Extra: if-let, uma forma segura de fazer o unwrap

Agora que vimos estruturas condicionais podemos falar sobre o “if-let”, uma estrutura especial que nos permite lidar com tipos opcionais e realizar o unwrap de forma segura.

O “if-let” evita erros que podem ser causados ao se usar “!” para lidar com opcionais, pois ele só permite que o unwrap ocorra se o opcional não for nil.

let entrada = readline()

if let entradaCerta = entrada {
print("A sua entrada foi " + entradaCerta)
} else {
print("Ocorreu um erro")
}

O código acima checa se a entrada é diferente de nil e, somente nesse caso, faz o unwrap, atribuindo o valor que estava em entrada para a constante entradaCerta (do tipo String), que pode ser manipulada sem riscos dentro do bloco do if e contém o mesmo conteúdo de entrada.

Estruturas de repetição

Quando estamos programando buscamos sempre simplificar nossa vida. Então se você precisa repetir o mesmo conjunto de operações por um número determinado de vezes ou até que certa condição seja atendida, saiba que existe uma estrutura de repetição perfeita para você.

Com estruturas de repetição, os chamados loops, nós repetimos nosso código sem a necessidade de copiar e colar toda vez!

A estrutura for-in itera sobre uma sequência, como por exemplo um array.

lista = ["leite", "queijo", "pão"]

Print("Preciso comprar: ")
for item in lista{
print(item)
}

O for acima faz com que print(item) seja executado 3 vezes (3 iterações) e a cada repetição/iteração a variável item assume o valor de um dos elementos do array, na ordem que eles estão organizados na coleção.

for numero in 1...10{ // itera de 1 a 10
print(numero)
}

for numero in 1..<10{ // itera de 1 a 9
print(numero)
}

Estruturas for-in também podem ser usadas para iterar sobre sequências numéricas. No exemplo acima, definimos um intervalo fechado de 1 a 10 no primeiro for e um intervalo aberto no segundo, o que faz com que ele itere 9 vezes, com a variável numero assumindo os valores de 1 a 9.

Elaboração do Autor

Nós usamos a estrutura while para repetir um bloco de código enquanto uma condição for verdadeira. A condição é avaliada antes de cada nova iteração e o código só é executado caso ela seja true.

var numero = 5

while numero < 7 {
print("O valor é \\(valor)")
numero = Int.random(in: 1...10)
}

O while é muito útil quando não sabemos ao certo quantas vezes o código se repetirá. No exemplo acima, vemos o print na tela pelo menos uma vez, pois a variável numero inicia com o valor 5, o que faz com que a condição numero < 7 seja verdadeira. Porém, não dá para saber quantas iteração ocorrerão, já que ao fim de cada iteração é atribuído um valor inteiro aleatório entre 1 e 10 (usamos o método random, que existe por padrão no tipo Int) à variável numero. O programa só chega ao fim quando um inteiro maior que 7 for escolhido.

--

--

Jvitormergulho
Apple Developer Academy | UFPE

I'm a Computer Science student at UFPE. I'm also currently part of the Apple Developer Academy, where I learn about innovation, design and programming.