Skip to content

Instantly share code, notes, and snippets.

@mateuspestana
Created July 13, 2022 19:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mateuspestana/12f047a18738191aaa06e2b1342c3a64 to your computer and use it in GitHub Desktop.
Save mateuspestana/12f047a18738191aaa06e2b1342c3a64 to your computer and use it in GitHub Desktop.
/*
Funções
*/
import Foundation
// Funções são úteis para reciclar código.
// Em uma função como
let roll = Int.random(in: 1...20)
// Temos que o in: é um argumento, um parâmetro dessa função. Funções tem parâmetros (ou não).
func printTimesTables(number: Int) {
for i in 1...12 {
print("\(i) x \(number) é \(i * number)")
}
}
printTimesTables(number: 9)
// number, aqui, é um parâmetro. No Swift precisamos digitar o parâmetro, ele não é posicional, como no R.
func printTimesTables(number: Int, end: Int) {
for i in 1...end {
print("\(i) x \(number) é \(i * number)")
}
}
printTimesTables(number: 5, end: 20)
// IMPORTANTE: os parâmetros, mesmo nomeados, precisam ser dados na ORDEM.
// RETURN VALUES DE UMA FUNÇÃO
// O output de uma função é dado por -> <tipo> depois de ()
func rollDice() -> Int {
return Int.random(in: 1...6)
}
let result = rollDice()
print(result)
// Desafio: letras presentes?
func letrasPresentes(string1: String, string2: String) -> Bool {
return string1.sorted() == string2.sorted()
}
// PODEMOS OMITIR O RETURN! Pois o Swift sabe que a função precisa retornar algo (stá presente no -> Bool). Isso só funciona em funções com uma única linha de código.
print(letrasPresentes(string1: "cab", string2: "abdc"))
func pitágoras(a: Double, b: Double) -> Double {
let input = a * a + b * b
let root = sqrt(input)
return root
}
let c = pitágoras(a: 3, b: 4)
print (c)
// Se nomearmos o parâmetro como _ o swift não exige que o nomeemos. Ou seja, poderíamos ocultar um nome. Isso é interessante quando nossa função é um verbo e o argumento um predicado.
// Podemos transformar em uma linha se for também um operador ternário:
func greet(name: String) -> String {
name == "Taylor Swift" ? "Shake it off":"Oi, \(name)"
}
// E se eu quisesse retornar dois ou mais valores de uma função? Posso usar um array...
func getUser() -> [String] {
["Taylor", "Swift"]
}
let user = getUser()
print("Nome: \(user[0]) \(user[1])")
// ... um dicionário...
func getUser_dic() -> [String: String] {
["firstName":"Taylor",
"lastName":"Swift"]
}
let user_dic = getUser_dic()
print("Nome: \(user_dic["firstName", default: "Anônimo"]) \(user_dic["lastName", default: "Anônimo"])")
// O problema do dicionário é que precisamos dar um argumento default, pro caso do valor não existir.
// ... tuplas!
func getUser_tuples() -> (firstName: String, lastName: String) {
(firstName: "Taylor", lastName: "Swift")
}
let user_tuples = getUser_tuples()
print("Nome: \(user_tuples.firstName) \(user_tuples.lastName)")
// Tuplas tem uma vantagem em relação a dicionários: nós especificamos os valores que nela existem e os seus respectivos tipos, exclusivamente, e eles de fato existem. No dicionário, nao necessariamente.
// As tuplas, quando tem um nome, podem ser referenciadas por sua posiçõa (user.0, user.1), como também não precisam ter o nome na área de return: o Swift entende.
func getUser2() -> (firstName: String, lastName: String) {
("Taylor", "Swift")
}
func getUser3() -> (String, String) {
("Taylor", "Swift")
}
let user3 = getUser3()
print("Name: \(user3.0) \(user3.1)")
// Também podemos agir assim:
let (firstName, lastName) = getUser_tuples()
print("Name: \(firstName) \(lastName)")
// Se eu não quiser usar um dos argumentos de uma tupla:
let (firstName2, _) = getUser_tuples()
print("Name: \(firstName2)")
/* Quando usar array, set, dicionário, ou tupla?
Set: quando eu quero armazenar uma lista, sem duplicatas, cuja ordem não importa (ex: lista de artigos lidos pelo usuário)
Array: armazenar uma lista se a ordem importar (lista de scores em um jogo: pode ter duplicata e tudo bem, ou uma lista de mercado)
Tupla: Se preciso armazenar duas strings, ou duas strings e um inteiro, ou três booleanos, ou similar, eu devo usar uma tupla.
Dicionário: quando eu quiser armazenar itens que tenham uma chave. Tais itens podem ou não ter algum valor.
*/
func rolaDado(lados: Int, vezes: Int) -> [Int] {
var rolls = Array<Int>()
for _ in 1...vezes {
let roll = Int.random(in: 1...lados)
rolls.append(roll)
}
return rolls
}
let rolls = rolaDado(lados: 6, vezes: 15)
print(rolls)
// Nomear argumentos é importante pois podemos fazer muitas funções com o mesmo nome, mas fazendo coisas distintas (métodos distintos)
/* Isso é normal no Swift:
func hireEmployee(name: String) { }
func hireEmployee(title: String) { }
func hireEmployee(location: String) { }
*/
// Funções também podem ter nomes internos de parâmetros, enquanto os nomes externos são outros:
func printTimesTables(for number: Int) {
for i in 1...12 {
print("\(i) x \(number) is \(i * number)")
}
}
printTimesTables(for: 5)
// Acima, o for é o nome externo, e o number: é o interno (pois não podemos ter um for internamente)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment