Funções Genéricas
Parte da seção Programação Orientada a Objetos do Journey de Swift da Coddy. Lição 34 de 57.
Uma função genérica funciona com qualquer tipo. O marcador entre colchetes angulares, geralmente T, representa o tipo usado pelo chamador, e o Swift o preenche em cada chamada:
func firstAndLast<T>(_ items: [T]) -> [T] {
guard let first = items.first, let last = items.last else { return [] }
return [first, last]
}
print(firstAndLast([3, 8, 1]))
print(firstAndLast(["a", "b", "c"]))Saída:
[3, 1]
["a", "c"]Dentro da função, nada se sabe sobre T, portanto somente são permitidas operações que funcionam para todos os tipos. Uma restrição como T: Comparable permite mais operações; neste caso, o operador <:
func largest<T: Comparable>(_ items: [T]) -> T? {
guard var best = items.first else { return nil }
for item in items where item > best { best = item }
return best
}
print(largest([4, 9, 2])!)
print(largest(["pear", "apple", "zucchini"])!)Saída:
9
zucchiniOs genéricos mantêm o tipo exato, ao contrário de Any. O resultado de largest em [Int] é um Int?, então pode ser usado em operações aritméticas sem conversão de tipo:
func largest<T: Comparable>(_ items: [T]) -> T? {
items.max()
}
let top = largest([3, 7, 5]) ?? 0
print(top * 10)Saída:
70Uma função pode ter vários marcadores de posição, e as restrições podem nomear protocolos próprios:
protocol Scored { var score: Int { get } }
struct Player: Scored { let name: String; let score: Int }
struct Team: Scored { let score: Int }
func total<T: Scored>(_ items: [T]) -> Int {
items.reduce(0) { $0 + $1.score }
}
func pair<A, B>(_ a: A, _ b: B) -> String { "\(a) & \(b)" }
print(total([Player(name: "a", score: 3), Player(name: "b", score: 4)]))
print(total([Team(score: 10)]))
print(pair(1, "one"))Saída:
7
10
1 & oneDesafio
FácilEscreva a função genérica countWhere(_:_:) que recebe um array de qualquer tipo e um predicado (T) -> Bool e retorna quantos elementos o satisfazem, e mostCommon(_:) que recebe um array de qualquer tipo Hashable e retorna seu elemento mais frequente (aquele que aparece primeiro no array quando há empate nas contagens), ou nil para um array vazio.
O código fornecido lê uma linha de palavras separadas por vírgulas e uma linha de números. Ele imprime o número de palavras com mais de 3 caracteres, a palavra mais comum, o número de números pares e o número mais comum.
Seu código deve ser inserido em Functions.swift. main.swift contém o código fornecido de entrada/saída e não pode ser editado.
Experimente você mesmo
// Código de entrada/saída fornecido: mantenha-o como está
var input: [String] = []
while let line = readLine() { input.append(line) }
let words = input[0].split(separator: ",").map(String.init)
let numbers = input[1].split(separator: ",").map { Int($0)! }
print(countWhere(words) { $0.count > 3 })
print(mostCommon(words) ?? "none")
print(countWhere(numbers) { $0 % 2 == 0 })
print(mostCommon(numbers).map { String($0) } ?? "none")
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação Orientada a Objetos
1Classes e Objetos
Trabalhando com ArquivosDefinindo ClassesMétodos e selfInicializadoresClasses são ReferênciasRevisão - Cartão da Biblioteca4Encapsulamento
Controle de AcessoSomente Leitura ExternaProtegendo o EstadoInicializadores que Podem FalharRevisão - Conta Bancária7Polimorfismo e Genéricos
PolimorfismoConversão de TiposFunções GenéricasTipos GenéricosRevisão - Calculadora de Formas2Structs e Tipos de Valor
StructsSemântica de ValorMétodos MutáveisStruct ou ClasseRecapitulação - Item de Inventário5Herança
SubclassesSobrescrita de métodosInicializadores e superfinal e hierarquiasRecapitulação - Hierarquia de funcionários8Protocolos Padrão
CustomStringConvertibleEquatableComparableHashableRecapitulação - Ordenação Personalizada11Projeto: Gerenciamento de Biblioteca
Livros e MembrosEmpréstimo de LivrosPratique por conta própria: Playground de Swift