From bb457d24a9d42061b9a8d9bc5632f5707f2150f3 Mon Sep 17 00:00:00 2001 From: fnscoder Date: Wed, 4 Oct 2017 22:03:41 -0300 Subject: fix names in pt-pt --- pt-pt/bf-pt.html.markdown | 85 ++++++ pt-pt/bf.html.markdown | 85 ------ pt-pt/swift-pt.html.markdown | 609 +++++++++++++++++++++++++++++++++++++++++++ pt-pt/swift.html.markdown | 609 ------------------------------------------- 4 files changed, 694 insertions(+), 694 deletions(-) create mode 100644 pt-pt/bf-pt.html.markdown delete mode 100644 pt-pt/bf.html.markdown create mode 100644 pt-pt/swift-pt.html.markdown delete mode 100644 pt-pt/swift.html.markdown diff --git a/pt-pt/bf-pt.html.markdown b/pt-pt/bf-pt.html.markdown new file mode 100644 index 00000000..13c22387 --- /dev/null +++ b/pt-pt/bf-pt.html.markdown @@ -0,0 +1,85 @@ +--- +language: brainfuck +filename: brainfuck-pt.bf +contributors: + - ["Prajit Ramachandran", "http://prajitr.github.io/"] + - ["Mathias Bynens", "http://mathiasbynens.be/"] +translators: + - ["Joao Marques", "http://github.com/mrshankly"] +lang: pt-pt +--- + +Brainfuck (não capitalizado excepto no início de uma frase) é uma linguagem de +programação Turing-completa extremamente simples com apenas 8 comandos. + +``` +Qualquer caractere excepto "><+-.,[]" (não contar com as aspas) é ignorado. + +Brainfuck é representado por um vector com 30 000 células inicializadas a zero +e um ponteiro de dados que aponta para a célula actual. + +Existem 8 comandos: ++ : Incrementa o valor da célula actual em 1. +- : Decrementa o valor da célula actual em 1. +> : Move o ponteiro de dados para a célula seguinte (célula à direita). +< : Move o ponteiro de dados para a célula anterior (célula à esquerda). +. : Imprime o valor ASCII da célula actual. (ex. 65 = 'A'). +, : Lê um único caractere para a célula actual. +[ : Se o valor da célula actual for zero, salta para o ] correspondente. + Caso contrário, passa para a instrução seguinte. +] : Se o valor da célula actual for zero, passa para a instrução seguinte. + Caso contrário, volta para a instrução relativa ao [ correspondente. + +[ e ] formam um ciclo while. Obviamente, devem ser equilibrados. + +Vejamos alguns programas básicos de brainfuck. + +++++++ [ > ++++++++++ < - ] > +++++ . + +Este programa imprime a letra 'A'. Primeiro incrementa a célula #1 para 6. +A célula #1 será usada num ciclo. Depois é iniciado o ciclo ([) e move-se +o ponteiro de dados para a célula #2. Incrementa-se o valor da célula #2 10 +vezes, move-se o ponteiro de dados de volta para a célula #1, e decrementa-se +a célula #1. Este ciclo acontece 6 vezes (são necessários 6 decrementos para +a célula #1 chegar a 0, momento em que se salta para o ] correspondente, +continuando com a instrução seguinte). + +Nesta altura encontramo-nos na célula #1, cujo valor é 0, enquanto a célula #2 +tem o valor 60. Movemos o ponteiro de dados para a célula #2, incrementa-se 5 +vezes para um valor final de 65, é então impresso o valor da célula #2. Ao valor +65 corresponde o caractere 'A' em ASCII, 'A' é então impresso para o terminal. + +, [ > + < - ] > . + +Este programa lê um caractere e copia o seu valor para a célula #1. Um ciclo é +iniciado. Movemos o ponteiro de dados para a célula #2, incrementamos o valor na +célula #2, movemos o ponteiro de dados de volta para a célula #1, finalmente +decrementamos o valor na célula #1. Isto continua até o valor na célula #1 ser +igual a 0 e a célula #2 ter o antigo valor da célula #1. Como o ponteiro de +dados está a apontar para a célula #1 no fim do ciclo, movemos o ponteiro para a +célula #2 e imprimimos o valor em ASCII. + +Os espaços servem apenas para tornar o programa mais legível. Podemos escrever +o mesmo programa da seguinte maneira: + +,[>+<-]>. + +Tenta descobrir o que este programa faz: + +,>,< [ > [ >+ >+ << -] >> [- << + >>] <<< -] >> + +Este programa lê dois números e multiplica-os. + +Basicamente o programa pede dois caracteres ao utilizador. Depois é iniciado um +ciclo exterior controlado pelo valor da célula #1. Movemos o ponteiro de dados +para a célula #2 e inicia-se o ciclo interior controlado pelo valor da célula +#2, incrementando o valor da célula #3. Contudo, existe um problema, no final do +ciclo interior a célula #2 tem o valor 0. Para resolver este problema o valor da +célula #4 é também incrementado e copiado para a célula #2. +``` + +Fica então explicado brainfuck. Simples, não? Por divertimento podes escrever os +teus próprios programas em brainfuck, ou então escrever um interpretador de +brainfuck noutra linguagem. O interpretador é relativamente fácil de se +implementar, mas se fores masoquista, tenta escrever um interpretador de +brainfuck… em brainfuck. diff --git a/pt-pt/bf.html.markdown b/pt-pt/bf.html.markdown deleted file mode 100644 index 13c22387..00000000 --- a/pt-pt/bf.html.markdown +++ /dev/null @@ -1,85 +0,0 @@ ---- -language: brainfuck -filename: brainfuck-pt.bf -contributors: - - ["Prajit Ramachandran", "http://prajitr.github.io/"] - - ["Mathias Bynens", "http://mathiasbynens.be/"] -translators: - - ["Joao Marques", "http://github.com/mrshankly"] -lang: pt-pt ---- - -Brainfuck (não capitalizado excepto no início de uma frase) é uma linguagem de -programação Turing-completa extremamente simples com apenas 8 comandos. - -``` -Qualquer caractere excepto "><+-.,[]" (não contar com as aspas) é ignorado. - -Brainfuck é representado por um vector com 30 000 células inicializadas a zero -e um ponteiro de dados que aponta para a célula actual. - -Existem 8 comandos: -+ : Incrementa o valor da célula actual em 1. -- : Decrementa o valor da célula actual em 1. -> : Move o ponteiro de dados para a célula seguinte (célula à direita). -< : Move o ponteiro de dados para a célula anterior (célula à esquerda). -. : Imprime o valor ASCII da célula actual. (ex. 65 = 'A'). -, : Lê um único caractere para a célula actual. -[ : Se o valor da célula actual for zero, salta para o ] correspondente. - Caso contrário, passa para a instrução seguinte. -] : Se o valor da célula actual for zero, passa para a instrução seguinte. - Caso contrário, volta para a instrução relativa ao [ correspondente. - -[ e ] formam um ciclo while. Obviamente, devem ser equilibrados. - -Vejamos alguns programas básicos de brainfuck. - -++++++ [ > ++++++++++ < - ] > +++++ . - -Este programa imprime a letra 'A'. Primeiro incrementa a célula #1 para 6. -A célula #1 será usada num ciclo. Depois é iniciado o ciclo ([) e move-se -o ponteiro de dados para a célula #2. Incrementa-se o valor da célula #2 10 -vezes, move-se o ponteiro de dados de volta para a célula #1, e decrementa-se -a célula #1. Este ciclo acontece 6 vezes (são necessários 6 decrementos para -a célula #1 chegar a 0, momento em que se salta para o ] correspondente, -continuando com a instrução seguinte). - -Nesta altura encontramo-nos na célula #1, cujo valor é 0, enquanto a célula #2 -tem o valor 60. Movemos o ponteiro de dados para a célula #2, incrementa-se 5 -vezes para um valor final de 65, é então impresso o valor da célula #2. Ao valor -65 corresponde o caractere 'A' em ASCII, 'A' é então impresso para o terminal. - -, [ > + < - ] > . - -Este programa lê um caractere e copia o seu valor para a célula #1. Um ciclo é -iniciado. Movemos o ponteiro de dados para a célula #2, incrementamos o valor na -célula #2, movemos o ponteiro de dados de volta para a célula #1, finalmente -decrementamos o valor na célula #1. Isto continua até o valor na célula #1 ser -igual a 0 e a célula #2 ter o antigo valor da célula #1. Como o ponteiro de -dados está a apontar para a célula #1 no fim do ciclo, movemos o ponteiro para a -célula #2 e imprimimos o valor em ASCII. - -Os espaços servem apenas para tornar o programa mais legível. Podemos escrever -o mesmo programa da seguinte maneira: - -,[>+<-]>. - -Tenta descobrir o que este programa faz: - -,>,< [ > [ >+ >+ << -] >> [- << + >>] <<< -] >> - -Este programa lê dois números e multiplica-os. - -Basicamente o programa pede dois caracteres ao utilizador. Depois é iniciado um -ciclo exterior controlado pelo valor da célula #1. Movemos o ponteiro de dados -para a célula #2 e inicia-se o ciclo interior controlado pelo valor da célula -#2, incrementando o valor da célula #3. Contudo, existe um problema, no final do -ciclo interior a célula #2 tem o valor 0. Para resolver este problema o valor da -célula #4 é também incrementado e copiado para a célula #2. -``` - -Fica então explicado brainfuck. Simples, não? Por divertimento podes escrever os -teus próprios programas em brainfuck, ou então escrever um interpretador de -brainfuck noutra linguagem. O interpretador é relativamente fácil de se -implementar, mas se fores masoquista, tenta escrever um interpretador de -brainfuck… em brainfuck. diff --git a/pt-pt/swift-pt.html.markdown b/pt-pt/swift-pt.html.markdown new file mode 100644 index 00000000..9462ee1c --- /dev/null +++ b/pt-pt/swift-pt.html.markdown @@ -0,0 +1,609 @@ +--- +language: swift +filename: learnswift-pt.swift +contributors: + - ["Grant Timmerman", "http://github.com/grant"] + - ["Christopher Bess", "http://github.com/cbess"] + - ["Joey Huang", "http://github.com/kamidox"] + - ["Anthony Nguyen", "http://github.com/anthonyn60"] + - ["Clayton Walker", "https://github.com/cwalk"] +translators: + - ["João Costa", "https://github.com/joaofcosta"] +lang: pt-pt +--- + +Swift é uma linguagem de programação criada pela Apple para o desenvolvimento em iOS e OS X. +Desenhada de forma a coexistir com Objective-C e ser mais resiliente contra código errôneo, a linguagem Swift foi introduzida em 2014 na conferência para desenvolvedores WWDC da Apple. +Swift usa o compilador LLVM incluido no XCode 6+. + +O livro oficial [Swift Programming Language](https://itunes.apple.com/us/book/swift-programming-language/id881256329) da Apple está agora disponivel via iBooks. + +Consulta também o [guia de iniciação](https://developer.apple.com/library/prerelease/ios/referencelibrary/GettingStarted/DevelopiOSAppsSwift/) da Apple, que contêm um tutorial completo em Swift. + +```swift +// importar um módulo +import UIKit + +// +// MARK: Básico +// + +// O Xcode suporta landmarks para anotação de código e lista-as na jump bar +// MARK: Marco de secção (MARK) +// TODO: Algo a fazer em breve +// FIXME: Reparar este código + +// Em Swift 2, println e print foram unidos num só método print. O print automaticamente acrescenta uma nova linha. +print("Hello, world") // println mudou para print +print("Hello, world", appendNewLine: false) // imprimir sem acrescentar uma nova linha + +// variáveis (var) podem ser modificadas depois de inicializadas +// constantes (let) NÂO podem ser modificadas depois de inicializadas + +var myVariable = 42 +let øπΩ = "value" // nomes de variáveis em unicode +let π = 3.1415926 +let convenience = "keyword" // nome de variável contextual +let weak = "keyword"; let override = "another keyword" // expressões podem ser separadas com ';' +let `class` = "keyword" // plicals permitem que keywords sejam usadas como nomes de vartiáveis +let explicitDouble: Double = 70 +let intValue = 0007 // 7 +let largeIntValue = 77_000 // 77000 +let label = "some text " + String(myVariable) // Casting +let piText = "Pi = \(π), Pi 2 = \(π * 2)" // interpolação de Strings + +// Valores especificos à build +// usam a configuração de build -D +#if false + print("Not printed") + let buildValue = 3 +#else + let buildValue = 7 +#endif +print("Build value: \(buildValue)") // Build value: 7 + +/* + Optionals são um dos recursos de Swift, Optionals tanto podem conter + um valor ou conter nil (sem valor) que indica que não existe um valor. + Adicionar um ponto de exclamção (?) após definir o tipo declara + esse valor como um Optional. + + Como Swift requere que todas as propriedades tenham um valor, até nil + tem que ser explicitamente guardado como um valor Optional. + + Optional é uma enumeração. +*/ +var someOptionalString: String? = "optional" // Pode assumir o valor nil +// Igual ao de cima, mas ? é um operando pósfixo (açúcar sintático) +var someOptionalString2: Optional = "optional" + +if someOptionalString != nil { + // Não sou nil + if someOptionalString!.hasPrefix("opt") { + print("has the prefix") + } + + let empty = someOptionalString?.isEmpty +} +someOptionalString = nil + +/* + Tentar usar ! para aceder a Optional com valor não existente, ou seja, nil, + causa em erro de execução. + É necessário ter sempre a certeza que um Optional não tem valor nil + antes de usar ! para fazer 'force-unwrap' ao seu valor. +*/ + +// Optional implicitamente desembrulhado +var unwrappedString: String! = "Value is expected." +// O mesmo de cima, mas ! é um operando pósfixo (mais açúcar sintático) +var unwrappedString2: ImplicitlyUnwrappedOptional = "Value is expected." + +if let someOptionalStringConstant = someOptionalString { + // Tem um valor diferente de nil + if !someOptionalStringConstant.hasPrefix("ok") { + // Não tem o prefixo + } +} + +// Swift tem suporte para guardar valores de qualquer tipo. +// AnyObject == id +// Ao contrátio do `id` de Objective-C, AnyObject funciona com qualquer valor (Class, Int, struct, etc.) +var anyObjectVar: AnyObject = 7 +anyObjectVar = "Changed value to a string, not good practice, but possible." + +/* + Comentar aqui + + /* + Também é possível fazer comentários aninhados + */ +*/ + +// +// MARK: Coleções (Collections) +// + +/* + Os tipos Array e Dictionary são structs e, portanto, `let` e `var` + também indicam se eles são mutáveis (var) or imutáveis (let) + na altura em que se declaram estes tipos. +*/ + +// Array +var shoppingList = ["catfish", "water", "lemons"] +shoppingList[1] = "bottle of water" +let emptyArray = [String]() // let == imutável +let emptyArray2 = Array() // mesmo de cima +var emptyMutableArray = [String]() // var == mutável + + +// Dictionary +var occupations = [ + "Malcolm": "Captain", + "kaylee": "Mechanic" +] +occupations["Jayne"] = "Public Relations" +let emptyDictionary = [String: Float]() // let == imutável +let emptyDictionary2 = Dictionary() // mesmo de cima +var emptyMutableDictionary = [String: Float]() // var == mutável + + +// +// MARK: Controlo de Fluxo (Control Flow) +// + +// for loop (array) +let myArray = [1, 1, 2, 3, 5] +for value in myArray { + if value == 1 { + print("One!") + } else { + print("Not one!") + } +} + +// for loop (dictionary) +var dict = ["one": 1, "two": 2] +for (key, value) in dict { + print("\(key): \(value)") +} + +// ciclo for (limite) +for i in -1...shoppingList.count { + print(i) +} +shoppingList[1...2] = ["steak", "peacons"] +// usar ..< para excluir o último número + +// ciclo while +var i = 1 +while i < 1000 { + i *= 2 +} + +// ciclo do-whie +do { + print("hello") +} while 1 == 2 + +// Switch +// Muito poderoso, imagine `if`s com açúcar sintático +// Funciona para String, instâncias de objectos e primitivas (Int, Double, etc.) +let vegetable = "red pepper" +switch vegetable { +case "celery": + let vegetableComment = "Add some raisins and make ants on a log." +case "cucumber", "watercress": + let vegetableComment = "That would make a good tea sandwich." +case let localScopeValue where localScopeValue.hasSuffix("pepper"): + let vegetableComment = "Is it a spicy \(localScopeValue)?" +default: // obrigatório (de forma a cobrir todos os possíveis inputs) + let vegetableComment = "Everything tastes good in soup." +} + + +// +// MARK: Funções (Functions) +// + +// Funções são tipos de primeira classe, o que significa que podem ser +// aninhadas dentro de outras funções e passadas como argumento + +// Função em Swift com documentação no header + +/** + Função de cumprimento. + + - Um ponto em documentação + - Outro ponto na documentação + + :param: nome Um nome + :param: dia Um dia + :returns: Uma string com um cumprimento contendo o nome e o dia. +*/ +func greet(nome: String, dia: String) -> String { + return "Hello \(nome), today is \(dia)." +} +greet("Bob", "Tuesday") + +// Semelhante ao método de cima excepto ao comportamento dos argumentos +func greet2(#nomeObrigatório: String, nomeArgumentoExterno nomeArgumentoLocal: String) -> String { + return "Hello \(nomeObrigatório), the day is \(nomeArgumentoLocal)" +} +greet2(nomeObrigatório:"John", nomeArgumentoExterno: "Sunday") + +// Função que devolve vários itens num tuplo +func getGasPrices() -> (Double, Double, Double) { + return (3.59, 3.69, 3.79) +} +let pricesTuple = getGasPrices() +let price = pricesTuple.2 // 3.79 +// Ignorar tuplos ou outros valores usando _ (underscore) +let (_, price1, _) = pricesTuple // price1 == 3.69 +print(price1 == pricesTuple.1) // true +print("Gas price: \(price)") + +// Argumentos variáveis +func setup(numbers: Int...) { + // é um array + let number = numbers[0] + let argCount = numbers.count +} + +// Passar e devolver funções +func makeIncrementer() -> (Int -> Int) { + func addOne(number: Int) -> Int { + return 1 + number + } + return addOne +} +var increment = makeIncrementer() +increment(7) + +// Passar por referência (inout) +func swapTwoInts(inout a: Int, inout b: Int) { + let tempA = a + a = b + b = tempA +} +var someIntA = 7 +var someIntB = 3 +swapTwoInts(&someIntA, &someIntB) +print(someIntB) // 7 + + +// +// MARK: Closures +// +var numbers = [1, 2, 6] + +// Funções são casos especiais de closures ({}) + +// Exemplo de um Closure. +// `->` separa o argumento e o tipo de retorno. +// `in` separa o cabeçalho do closure do corpo do closure. +numbers.map({ + (number: Int) -> Int in + let result = 3 * number + return result +}) + +// Quando o tipo é conhecido, como em cima, podemos fazer o seguinte +numbers = numbers.map({ number in 3 * number }) +// Ou até mesmo isto +//numbers = numbers.map({ $0 * 3 }) + +print(numbers) // [3, 6, 18] + +// Closure à direita (Trailing closure) +numbers = sorted(numbers) { $0 > $1 } + +print(numbers) // [18, 6, 3] + +// Super curto, pois o operador < consegue inferir o tipo + +numbers = sorted(numbers, < ) + +print(numbers) // [3, 6, 18] + +// +// MARK: Estruturas (Structures) +// + +// Estruturas (struct) e classes (class) têm capacidades muito semelhantes +struct NamesTable { + let names = [String]() + + // Custom subscript + subscript(index: Int) -> String { + return names[index] + } +} + +// Estruturas têm um inicializador implicito que é automaticamente gerado +let namesTable = NamesTable(names: ["Me", "Them"]) +let name = namesTable[1] +print("Name is \(name)") // Name is Them + +// +// MARK: Classes +// + +// Classes, estruturas e os seus membros têm três níveis de controlo de acesso +// Nomeadamente: interno (predefinição)(internal) , público (public), privado (private) + +public class Shape { + public func getArea() -> Int { + return 0; + } +} + +// Todos os métodos e propriedades de uma classe são públicos. +// Se só for necessário guarda dados num +// objecto estruturado, então é melhor usar uma `struct` + +internal class Rect: Shape { + var sideLength: Int = 1 + + // Propriedade getter e setter personalizado + private var perimeter: Int { + get { + return 4 * sideLength + } + set { + // `newValue` é uma variável implicita disponível aos setters + sideLength = newValue / 4 + } + } + + // Carregar preguiçosamente uma propriedade + // subShape permanece a nil (unintialized) até o getter ser invocado + lazy var subShape = Rect(sideLength: 4) + + // Se não for necessário um getter e setter personalizado, + // mas se quiser correr o código antes e depois de modificar ou aceder + // uma propriedade, é possível usar `willSet` e `didSet` + var identifier: String = "defaultID" { + // o argumento de `willSet` é o nome da variável para o novo valor + willSet(someIdentifier) { + print(someIdentifier) + } + } + + init(sideLength: Int) { + self.sideLength = sideLength + // invocar super.init no final do método de inicialização + super.init() + } + + func shrink() { + if sideLength > 0 { + sideLength -= 1 + } + } + + override func getArea() -> Int { + return sideLength * sideLength + } +} + +// A class `Square` estende (extends) a classe `Rect` (hierarquia) +class Square: Rect { + convenience init() { + self.init(sideLength: 5) + } +} + +var mySquare = Square() +print(mySquare.getArea()) // 25 +mySquare.shrink() +print(mySquare.sideLength) // 4 + +// Cast de uma instância de `Square` para `Shape` +let aShape = mySquare as Shape + +// Compara instâncias, não é igual a == , visto que == compara objects (igual a) +if mySquare === mySquare { + print("Yep, it's mySquare") +} + +// Inicializador (init) com Optional +class Circle: Shape { + var radius: Int + override func getArea() -> Int { + return 3 * radius * radius + } + + // Colocar um ponto de interrpgação depois de `init` cria um inicializador + // Optional, o qual pode retornar nil + init?(radius: Int) { + self.radius = radius + super.init() + + if radius <= 0 { + return nil + } + } +} + +var myCircle = Circle(radius: 1) +print(myCircle?.getArea()) // Optional(3) +print(myCircle!.getArea()) // 3 +var myEmptyCircle = Circle(radius: -1) +print(myEmptyCircle?.getArea()) // "nil" +if let circle = myEmptyCircle { + // Não vai executar pois a variável myEmptyCircle é igual a nil + print("circle is not nil") +} + + +// +// MARK: Enumerações (Enums) +// + +// Enums pode opcionalmente ser um tipo especifico ou não. +// Enums podem conter métodos tal como as classes. + +enum Suit { + case Spades, Hearts, Diamonds, Clubs + func getIcon() -> String { + switch self { + case .Spades: return "♤" + case .Hearts: return "♡" + case .Diamonds: return "♢" + case .Clubs: return "♧" + } + } +} + +// Os valores de Enum permitem syntax reduzida, não é preciso escrever o tipo do enum +// quando a variável é explicitamente definida. +var suitValue: Suit = .Hearts + +// Enums que não sejam inteiros obrigam a atribuições valor bruto (raw value) diretas +enum BookName: String { + case John = "John" + case Luke = "Luke" +} +print("Name: \(BookName.John.rawValue)") + +// Enum com valores associados +enum Furniture { + // Associar com um inteiro (Int) + case Desk(height: Int) + // Associar com uma String e um Int + case Chair(String, Int) + + func description() -> String { + switch self { + case .Desk(let height): + return "Desk with \(height) cm" + case .Chair(let brand, let height): + return "Chair of \(brand) with \(height) cm" + } + } +} + +var desk: Furniture = .Desk(height: 80) +print(desk.description()) // "Desk with 80 cm" +var chair = Furniture.Chair("Foo", 40) +print(chair.description()) // "Chair of Foo with 40 cm" + + +// +// MARK: Protocolos (Protocols) +// + +// Protocolos (`protcol`s) obrigam a que os tipos tenham +// propriedades de instância, métodos de instância, métodos de tipo, +// operadores e subscripts específicos. + +protocol ShapeGenerator { + var enabled: Bool { get set } + func buildShape() -> Shape +} + +// Protocolos definidos com @objc permitem funções com optional +// que permitem verificar se existem conformidade +@objc protocol TransformShape { + optional func reshaped() + optional func canReshape() -> Bool +} + +class MyShape: Rect { + var delegate: TransformShape? + + func grow() { + sideLength += 2 + + // Coloca um ponto de interrogação após uma propriedade opcional, método + // ou subscript para graciosamente ignorar um valor nil e retornar nil + // em vez de provoar um erro em tempo de execução ("optional chaining"). + if let allow = self.delegate?.canReshape?() { + // testar o delegate e depois o método + self.delegate?.reshaped?() + } + } +} + + +// +// MARK: Outro +// + +// extensões (`extension`s): Adiciona funcionalidade extra a um tipo já existente. + +// Square agora "conforma" com o protocolo `Printable` +extension Square: Printable { + var description: String { + return "Area: \(self.getArea()) - ID: \(self.identifier)" + } +} + +print("Square: \(mySquare)") + +// Também é possível extender tipos já embutidos +extension Int { + var customProperty: String { + return "This is \(self)" + } + + func multiplyBy(num: Int) -> Int { + return num * self + } +} + +print(7.customProperty) // "This is 7" +print(14.multiplyBy(3)) // 42 + +// Generics: Semelhante a Java e C#. Usa a palavra-chave `where` para +// especificar requisitos do `generics`. + +func findIndex(array: [T], valueToFind: T) -> Int? { + for (index, value) in enumerate(array) { + if value == valueToFind { + return index + } + } + return nil +} +let foundAtIndex = findIndex([1, 2, 3, 4], 3) +print(foundAtIndex == 2) // true + +// Operadores: +// Operadores personalizados podem começar com caracteres: +// / = - + * % < > ! & | ^ . ~ +// ou +// Caracteres Unicode matemáticos, símbolos, setas, dingbat e +// caracteres de desenho linha/caixa. +operador prefixo !!! {} + +// Um operador prefixo que triplica o comprimento do lado quando usado +prefix func !!! (inout shape: Square) -> Square { + shape.sideLength *= 3 + return shape +} + +// valor atual +print(mySquare.sideLength) // 4 + +// muda o comprimento deste lado usando o operador personalizado !!!, aumenta +// o comprimento 3x +!!!mySquare +print(mySquare.sideLength) // 12 + +// Operadores também podem ser generics +infix operator <-> {} +func <-> (inout a: T, inout b: T) { + let c = a + a = b + b = c +} + +var foo: Float = 10 +var bar: Float = 20 + +foo <-> bar +print("foo is \(foo), bar is \(bar)") // "foo is 20.0, bar is 10.0" +``` diff --git a/pt-pt/swift.html.markdown b/pt-pt/swift.html.markdown deleted file mode 100644 index 9462ee1c..00000000 --- a/pt-pt/swift.html.markdown +++ /dev/null @@ -1,609 +0,0 @@ ---- -language: swift -filename: learnswift-pt.swift -contributors: - - ["Grant Timmerman", "http://github.com/grant"] - - ["Christopher Bess", "http://github.com/cbess"] - - ["Joey Huang", "http://github.com/kamidox"] - - ["Anthony Nguyen", "http://github.com/anthonyn60"] - - ["Clayton Walker", "https://github.com/cwalk"] -translators: - - ["João Costa", "https://github.com/joaofcosta"] -lang: pt-pt ---- - -Swift é uma linguagem de programação criada pela Apple para o desenvolvimento em iOS e OS X. -Desenhada de forma a coexistir com Objective-C e ser mais resiliente contra código errôneo, a linguagem Swift foi introduzida em 2014 na conferência para desenvolvedores WWDC da Apple. -Swift usa o compilador LLVM incluido no XCode 6+. - -O livro oficial [Swift Programming Language](https://itunes.apple.com/us/book/swift-programming-language/id881256329) da Apple está agora disponivel via iBooks. - -Consulta também o [guia de iniciação](https://developer.apple.com/library/prerelease/ios/referencelibrary/GettingStarted/DevelopiOSAppsSwift/) da Apple, que contêm um tutorial completo em Swift. - -```swift -// importar um módulo -import UIKit - -// -// MARK: Básico -// - -// O Xcode suporta landmarks para anotação de código e lista-as na jump bar -// MARK: Marco de secção (MARK) -// TODO: Algo a fazer em breve -// FIXME: Reparar este código - -// Em Swift 2, println e print foram unidos num só método print. O print automaticamente acrescenta uma nova linha. -print("Hello, world") // println mudou para print -print("Hello, world", appendNewLine: false) // imprimir sem acrescentar uma nova linha - -// variáveis (var) podem ser modificadas depois de inicializadas -// constantes (let) NÂO podem ser modificadas depois de inicializadas - -var myVariable = 42 -let øπΩ = "value" // nomes de variáveis em unicode -let π = 3.1415926 -let convenience = "keyword" // nome de variável contextual -let weak = "keyword"; let override = "another keyword" // expressões podem ser separadas com ';' -let `class` = "keyword" // plicals permitem que keywords sejam usadas como nomes de vartiáveis -let explicitDouble: Double = 70 -let intValue = 0007 // 7 -let largeIntValue = 77_000 // 77000 -let label = "some text " + String(myVariable) // Casting -let piText = "Pi = \(π), Pi 2 = \(π * 2)" // interpolação de Strings - -// Valores especificos à build -// usam a configuração de build -D -#if false - print("Not printed") - let buildValue = 3 -#else - let buildValue = 7 -#endif -print("Build value: \(buildValue)") // Build value: 7 - -/* - Optionals são um dos recursos de Swift, Optionals tanto podem conter - um valor ou conter nil (sem valor) que indica que não existe um valor. - Adicionar um ponto de exclamção (?) após definir o tipo declara - esse valor como um Optional. - - Como Swift requere que todas as propriedades tenham um valor, até nil - tem que ser explicitamente guardado como um valor Optional. - - Optional é uma enumeração. -*/ -var someOptionalString: String? = "optional" // Pode assumir o valor nil -// Igual ao de cima, mas ? é um operando pósfixo (açúcar sintático) -var someOptionalString2: Optional = "optional" - -if someOptionalString != nil { - // Não sou nil - if someOptionalString!.hasPrefix("opt") { - print("has the prefix") - } - - let empty = someOptionalString?.isEmpty -} -someOptionalString = nil - -/* - Tentar usar ! para aceder a Optional com valor não existente, ou seja, nil, - causa em erro de execução. - É necessário ter sempre a certeza que um Optional não tem valor nil - antes de usar ! para fazer 'force-unwrap' ao seu valor. -*/ - -// Optional implicitamente desembrulhado -var unwrappedString: String! = "Value is expected." -// O mesmo de cima, mas ! é um operando pósfixo (mais açúcar sintático) -var unwrappedString2: ImplicitlyUnwrappedOptional = "Value is expected." - -if let someOptionalStringConstant = someOptionalString { - // Tem um valor diferente de nil - if !someOptionalStringConstant.hasPrefix("ok") { - // Não tem o prefixo - } -} - -// Swift tem suporte para guardar valores de qualquer tipo. -// AnyObject == id -// Ao contrátio do `id` de Objective-C, AnyObject funciona com qualquer valor (Class, Int, struct, etc.) -var anyObjectVar: AnyObject = 7 -anyObjectVar = "Changed value to a string, not good practice, but possible." - -/* - Comentar aqui - - /* - Também é possível fazer comentários aninhados - */ -*/ - -// -// MARK: Coleções (Collections) -// - -/* - Os tipos Array e Dictionary são structs e, portanto, `let` e `var` - também indicam se eles são mutáveis (var) or imutáveis (let) - na altura em que se declaram estes tipos. -*/ - -// Array -var shoppingList = ["catfish", "water", "lemons"] -shoppingList[1] = "bottle of water" -let emptyArray = [String]() // let == imutável -let emptyArray2 = Array() // mesmo de cima -var emptyMutableArray = [String]() // var == mutável - - -// Dictionary -var occupations = [ - "Malcolm": "Captain", - "kaylee": "Mechanic" -] -occupations["Jayne"] = "Public Relations" -let emptyDictionary = [String: Float]() // let == imutável -let emptyDictionary2 = Dictionary() // mesmo de cima -var emptyMutableDictionary = [String: Float]() // var == mutável - - -// -// MARK: Controlo de Fluxo (Control Flow) -// - -// for loop (array) -let myArray = [1, 1, 2, 3, 5] -for value in myArray { - if value == 1 { - print("One!") - } else { - print("Not one!") - } -} - -// for loop (dictionary) -var dict = ["one": 1, "two": 2] -for (key, value) in dict { - print("\(key): \(value)") -} - -// ciclo for (limite) -for i in -1...shoppingList.count { - print(i) -} -shoppingList[1...2] = ["steak", "peacons"] -// usar ..< para excluir o último número - -// ciclo while -var i = 1 -while i < 1000 { - i *= 2 -} - -// ciclo do-whie -do { - print("hello") -} while 1 == 2 - -// Switch -// Muito poderoso, imagine `if`s com açúcar sintático -// Funciona para String, instâncias de objectos e primitivas (Int, Double, etc.) -let vegetable = "red pepper" -switch vegetable { -case "celery": - let vegetableComment = "Add some raisins and make ants on a log." -case "cucumber", "watercress": - let vegetableComment = "That would make a good tea sandwich." -case let localScopeValue where localScopeValue.hasSuffix("pepper"): - let vegetableComment = "Is it a spicy \(localScopeValue)?" -default: // obrigatório (de forma a cobrir todos os possíveis inputs) - let vegetableComment = "Everything tastes good in soup." -} - - -// -// MARK: Funções (Functions) -// - -// Funções são tipos de primeira classe, o que significa que podem ser -// aninhadas dentro de outras funções e passadas como argumento - -// Função em Swift com documentação no header - -/** - Função de cumprimento. - - - Um ponto em documentação - - Outro ponto na documentação - - :param: nome Um nome - :param: dia Um dia - :returns: Uma string com um cumprimento contendo o nome e o dia. -*/ -func greet(nome: String, dia: String) -> String { - return "Hello \(nome), today is \(dia)." -} -greet("Bob", "Tuesday") - -// Semelhante ao método de cima excepto ao comportamento dos argumentos -func greet2(#nomeObrigatório: String, nomeArgumentoExterno nomeArgumentoLocal: String) -> String { - return "Hello \(nomeObrigatório), the day is \(nomeArgumentoLocal)" -} -greet2(nomeObrigatório:"John", nomeArgumentoExterno: "Sunday") - -// Função que devolve vários itens num tuplo -func getGasPrices() -> (Double, Double, Double) { - return (3.59, 3.69, 3.79) -} -let pricesTuple = getGasPrices() -let price = pricesTuple.2 // 3.79 -// Ignorar tuplos ou outros valores usando _ (underscore) -let (_, price1, _) = pricesTuple // price1 == 3.69 -print(price1 == pricesTuple.1) // true -print("Gas price: \(price)") - -// Argumentos variáveis -func setup(numbers: Int...) { - // é um array - let number = numbers[0] - let argCount = numbers.count -} - -// Passar e devolver funções -func makeIncrementer() -> (Int -> Int) { - func addOne(number: Int) -> Int { - return 1 + number - } - return addOne -} -var increment = makeIncrementer() -increment(7) - -// Passar por referência (inout) -func swapTwoInts(inout a: Int, inout b: Int) { - let tempA = a - a = b - b = tempA -} -var someIntA = 7 -var someIntB = 3 -swapTwoInts(&someIntA, &someIntB) -print(someIntB) // 7 - - -// -// MARK: Closures -// -var numbers = [1, 2, 6] - -// Funções são casos especiais de closures ({}) - -// Exemplo de um Closure. -// `->` separa o argumento e o tipo de retorno. -// `in` separa o cabeçalho do closure do corpo do closure. -numbers.map({ - (number: Int) -> Int in - let result = 3 * number - return result -}) - -// Quando o tipo é conhecido, como em cima, podemos fazer o seguinte -numbers = numbers.map({ number in 3 * number }) -// Ou até mesmo isto -//numbers = numbers.map({ $0 * 3 }) - -print(numbers) // [3, 6, 18] - -// Closure à direita (Trailing closure) -numbers = sorted(numbers) { $0 > $1 } - -print(numbers) // [18, 6, 3] - -// Super curto, pois o operador < consegue inferir o tipo - -numbers = sorted(numbers, < ) - -print(numbers) // [3, 6, 18] - -// -// MARK: Estruturas (Structures) -// - -// Estruturas (struct) e classes (class) têm capacidades muito semelhantes -struct NamesTable { - let names = [String]() - - // Custom subscript - subscript(index: Int) -> String { - return names[index] - } -} - -// Estruturas têm um inicializador implicito que é automaticamente gerado -let namesTable = NamesTable(names: ["Me", "Them"]) -let name = namesTable[1] -print("Name is \(name)") // Name is Them - -// -// MARK: Classes -// - -// Classes, estruturas e os seus membros têm três níveis de controlo de acesso -// Nomeadamente: interno (predefinição)(internal) , público (public), privado (private) - -public class Shape { - public func getArea() -> Int { - return 0; - } -} - -// Todos os métodos e propriedades de uma classe são públicos. -// Se só for necessário guarda dados num -// objecto estruturado, então é melhor usar uma `struct` - -internal class Rect: Shape { - var sideLength: Int = 1 - - // Propriedade getter e setter personalizado - private var perimeter: Int { - get { - return 4 * sideLength - } - set { - // `newValue` é uma variável implicita disponível aos setters - sideLength = newValue / 4 - } - } - - // Carregar preguiçosamente uma propriedade - // subShape permanece a nil (unintialized) até o getter ser invocado - lazy var subShape = Rect(sideLength: 4) - - // Se não for necessário um getter e setter personalizado, - // mas se quiser correr o código antes e depois de modificar ou aceder - // uma propriedade, é possível usar `willSet` e `didSet` - var identifier: String = "defaultID" { - // o argumento de `willSet` é o nome da variável para o novo valor - willSet(someIdentifier) { - print(someIdentifier) - } - } - - init(sideLength: Int) { - self.sideLength = sideLength - // invocar super.init no final do método de inicialização - super.init() - } - - func shrink() { - if sideLength > 0 { - sideLength -= 1 - } - } - - override func getArea() -> Int { - return sideLength * sideLength - } -} - -// A class `Square` estende (extends) a classe `Rect` (hierarquia) -class Square: Rect { - convenience init() { - self.init(sideLength: 5) - } -} - -var mySquare = Square() -print(mySquare.getArea()) // 25 -mySquare.shrink() -print(mySquare.sideLength) // 4 - -// Cast de uma instância de `Square` para `Shape` -let aShape = mySquare as Shape - -// Compara instâncias, não é igual a == , visto que == compara objects (igual a) -if mySquare === mySquare { - print("Yep, it's mySquare") -} - -// Inicializador (init) com Optional -class Circle: Shape { - var radius: Int - override func getArea() -> Int { - return 3 * radius * radius - } - - // Colocar um ponto de interrpgação depois de `init` cria um inicializador - // Optional, o qual pode retornar nil - init?(radius: Int) { - self.radius = radius - super.init() - - if radius <= 0 { - return nil - } - } -} - -var myCircle = Circle(radius: 1) -print(myCircle?.getArea()) // Optional(3) -print(myCircle!.getArea()) // 3 -var myEmptyCircle = Circle(radius: -1) -print(myEmptyCircle?.getArea()) // "nil" -if let circle = myEmptyCircle { - // Não vai executar pois a variável myEmptyCircle é igual a nil - print("circle is not nil") -} - - -// -// MARK: Enumerações (Enums) -// - -// Enums pode opcionalmente ser um tipo especifico ou não. -// Enums podem conter métodos tal como as classes. - -enum Suit { - case Spades, Hearts, Diamonds, Clubs - func getIcon() -> String { - switch self { - case .Spades: return "♤" - case .Hearts: return "♡" - case .Diamonds: return "♢" - case .Clubs: return "♧" - } - } -} - -// Os valores de Enum permitem syntax reduzida, não é preciso escrever o tipo do enum -// quando a variável é explicitamente definida. -var suitValue: Suit = .Hearts - -// Enums que não sejam inteiros obrigam a atribuições valor bruto (raw value) diretas -enum BookName: String { - case John = "John" - case Luke = "Luke" -} -print("Name: \(BookName.John.rawValue)") - -// Enum com valores associados -enum Furniture { - // Associar com um inteiro (Int) - case Desk(height: Int) - // Associar com uma String e um Int - case Chair(String, Int) - - func description() -> String { - switch self { - case .Desk(let height): - return "Desk with \(height) cm" - case .Chair(let brand, let height): - return "Chair of \(brand) with \(height) cm" - } - } -} - -var desk: Furniture = .Desk(height: 80) -print(desk.description()) // "Desk with 80 cm" -var chair = Furniture.Chair("Foo", 40) -print(chair.description()) // "Chair of Foo with 40 cm" - - -// -// MARK: Protocolos (Protocols) -// - -// Protocolos (`protcol`s) obrigam a que os tipos tenham -// propriedades de instância, métodos de instância, métodos de tipo, -// operadores e subscripts específicos. - -protocol ShapeGenerator { - var enabled: Bool { get set } - func buildShape() -> Shape -} - -// Protocolos definidos com @objc permitem funções com optional -// que permitem verificar se existem conformidade -@objc protocol TransformShape { - optional func reshaped() - optional func canReshape() -> Bool -} - -class MyShape: Rect { - var delegate: TransformShape? - - func grow() { - sideLength += 2 - - // Coloca um ponto de interrogação após uma propriedade opcional, método - // ou subscript para graciosamente ignorar um valor nil e retornar nil - // em vez de provoar um erro em tempo de execução ("optional chaining"). - if let allow = self.delegate?.canReshape?() { - // testar o delegate e depois o método - self.delegate?.reshaped?() - } - } -} - - -// -// MARK: Outro -// - -// extensões (`extension`s): Adiciona funcionalidade extra a um tipo já existente. - -// Square agora "conforma" com o protocolo `Printable` -extension Square: Printable { - var description: String { - return "Area: \(self.getArea()) - ID: \(self.identifier)" - } -} - -print("Square: \(mySquare)") - -// Também é possível extender tipos já embutidos -extension Int { - var customProperty: String { - return "This is \(self)" - } - - func multiplyBy(num: Int) -> Int { - return num * self - } -} - -print(7.customProperty) // "This is 7" -print(14.multiplyBy(3)) // 42 - -// Generics: Semelhante a Java e C#. Usa a palavra-chave `where` para -// especificar requisitos do `generics`. - -func findIndex(array: [T], valueToFind: T) -> Int? { - for (index, value) in enumerate(array) { - if value == valueToFind { - return index - } - } - return nil -} -let foundAtIndex = findIndex([1, 2, 3, 4], 3) -print(foundAtIndex == 2) // true - -// Operadores: -// Operadores personalizados podem começar com caracteres: -// / = - + * % < > ! & | ^ . ~ -// ou -// Caracteres Unicode matemáticos, símbolos, setas, dingbat e -// caracteres de desenho linha/caixa. -operador prefixo !!! {} - -// Um operador prefixo que triplica o comprimento do lado quando usado -prefix func !!! (inout shape: Square) -> Square { - shape.sideLength *= 3 - return shape -} - -// valor atual -print(mySquare.sideLength) // 4 - -// muda o comprimento deste lado usando o operador personalizado !!!, aumenta -// o comprimento 3x -!!!mySquare -print(mySquare.sideLength) // 12 - -// Operadores também podem ser generics -infix operator <-> {} -func <-> (inout a: T, inout b: T) { - let c = a - a = b - b = c -} - -var foo: Float = 10 -var bar: Float = 20 - -foo <-> bar -print("foo is \(foo), bar is \(bar)") // "foo is 20.0, bar is 10.0" -``` -- cgit v1.2.3