diff options
Diffstat (limited to 'es-es')
| -rw-r--r-- | es-es/brainfuck-es.html.markdown | 18 | ||||
| -rw-r--r-- | es-es/git-es.html.markdown | 14 | ||||
| -rw-r--r-- | es-es/javascript-es.html.markdown | 20 | ||||
| -rw-r--r-- | es-es/json-es.html.markdown | 16 | ||||
| -rw-r--r-- | es-es/python3-es.html.markdown | 8 | ||||
| -rw-r--r-- | es-es/ruby-es.html.markdown | 6 | ||||
| -rw-r--r-- | es-es/swift-es.html.markdown | 596 | 
7 files changed, 638 insertions, 40 deletions
| diff --git a/es-es/brainfuck-es.html.markdown b/es-es/brainfuck-es.html.markdown index e33d672d..550511da 100644 --- a/es-es/brainfuck-es.html.markdown +++ b/es-es/brainfuck-es.html.markdown @@ -9,8 +9,10 @@ lang: es-es  ---  Brainfuck (con mayúscula sólo al inicio de una oración) es un -lenguaje de programación mínimo, computacionalmente universal -en tamaño con sólo 8 comandos. +lenguaje de programación extremadamente pequeño, Turing completo con sólo 8 comandos. + +Puedes probar brainfuck en tu navegador con [brainfuck-visualizer](http://fatiherikli.github.io/brainfuck-visualizer/). +  ``` @@ -18,7 +20,7 @@ Cualquier caracter que no sea "><+-.,[]" (sin incluir las comillas)  será ignorado.  Brainfuck es representado por un arreglo de 30,000 celdas inicializadas -en cero y un apuntador en la celda actual. +en cero y un puntero apuntando la celda actual.  Existen ocho comandos: @@ -26,7 +28,7 @@ Existen ocho comandos:  - : Decrementa 1 al valor de la celda actual.  > : Mueve el apuntador a la siguiente celda. (a la derecha)  < : Mueve el apuntador a la celda anterior. (a la izquierda) -. : Imprime el valor en ASCII de la celda actual (i.e. 65 = 'A') +. : Imprime el valor en ASCII de la celda actual (p.e. 65 = 'A')  , : Lee un caracter como input y lo escribe en la celda actual.  [ : Si el valor en la celda actual es cero mueve el apuntador  	hasta el primer ']' que encuentre. Si no es cero sigue a la @@ -37,7 +39,7 @@ Existen ocho comandos:  [ y ] forman un while. Obviamente, deben estar balanceados. -Ahora unos ejemplos de programas escritos con brainfuck. +Estos son algunos ejemplos de programas escritos con brainfuck.  ++++++ [ > ++++++++++ < - ] > +++++ . @@ -63,7 +65,7 @@ Esto continúa hasta que la celda #1 contenga un cero. Cuando #1 contenga un  cero la celda #2 tendrá el valor inicial de #1. Como este ciclo siempre  terminara en la celda #1 nos movemos a la celda #2 e imprimimos (.). -Ten en mente que los espacios son sólo para fines de legibilidad. +Ten en cuenta que los espacios son sólo para fines de legibilidad.  Es lo mismo escribir el ejemplo de arriba que esto:  ,[>+<-]>. @@ -81,7 +83,7 @@ hasta la próxima vez. Para resolver este problema también incrementamos la  celda #4 y luego copiamos la celda #4 a la celda #2. La celda #3 contiene  el resultado.  ``` -Y eso es brainfuck. ¿No tan difícil o sí? Como diversión, puedes escribir +Y eso es brainfuck. No es tan difícil, ¿verdad? Como diversión, puedes escribir  tu propio intérprete de brainfuck o tu propio programa en brainfuck. El  intérprete es relativamente sencillo de hacer, pero si eres masoquista, -intenta construir tu proprio intérprete de brainfuck... en brainfuck. +puedes intentar construir tu propio intérprete de brainfuck... en brainfuck. diff --git a/es-es/git-es.html.markdown b/es-es/git-es.html.markdown index 18b544b4..4e1e68ba 100644 --- a/es-es/git-es.html.markdown +++ b/es-es/git-es.html.markdown @@ -18,11 +18,11 @@ versionar y administrar nuestro código fuente.  ## Versionamiento, conceptos. -### Qué es el control de versiones? +### ¿Qué es el control de versiones?  El control de versiones es un sistema que guarda todos los cambios realizados en  uno o varios archivos, a lo largo del tiempo. -### Versionamiento centralizado vs Versionamiento Distribuido. +### Versionamiento centralizado vs versionamiento distribuido.  + El versionamiento centralizado se enfoca en sincronizar, rastrear, y respaldar    archivos. @@ -33,9 +33,9 @@ uno o varios archivos, a lo largo del tiempo.  [Información adicional](http://git-scm.com/book/es/Empezando-Acerca-del-control-de-versiones) -### Por qué usar Git? +### ¿Por qué usar Git? -* Se puede trabajar sin conexion. +* Se puede trabajar sin conexión.  * ¡Colaborar con otros es sencillo!.  * Derivar, crear ramas del proyecto (aka: Branching) es fácil.  * Combinar (aka: Merging) @@ -47,7 +47,7 @@ uno o varios archivos, a lo largo del tiempo.  ### Repositorio  Un repositorio es un conjunto de archivos, directorios, registros, cambios (aka: -comits), y encabezados (aka: heads). Imagina que un repositorio es una clase, +commits), y encabezados (aka: heads). Imagina que un repositorio es una clase,  y que sus atributos otorgan acceso al historial del elemento, además de otras  cosas. @@ -62,12 +62,12 @@ y mas.  ### Directorio de trabajo (componentes del repositorio) -Es basicamente los directorios y archivos dentro del repositorio. La mayoría de +Es básicamente los directorios y archivos dentro del repositorio. La mayoría de  las veces se le llama "directorio de trabajo".  ### Índice (componentes del directorio .git) -El índice es el área de inicio en git. Es basicamente la capa que separa el +El índice es el área de inicio en git. Es básicamente la capa que separa el  directorio de trabajo del repositorio en git. Esto otorga a los desarrolladores  más poder sobre lo que se envía y se recibe del repositorio. diff --git a/es-es/javascript-es.html.markdown b/es-es/javascript-es.html.markdown index d475cf42..9ef0c63e 100644 --- a/es-es/javascript-es.html.markdown +++ b/es-es/javascript-es.html.markdown @@ -30,7 +30,7 @@ Aunque JavaScript no sólo se limita a los navegadores web: Node.js, Un proyecto  // Cada sentencia puede ser terminada con punto y coma ;  hazAlgo(); -// ... aunque no es necesario, ya que el punto y coma se agrega automaticamente +// ... aunque no es necesario, ya que el punto y coma se agrega automáticamente  // cada que se detecta una nueva línea, a excepción de algunos casos.  hazAlgo() @@ -109,7 +109,7 @@ null == undefined; // = true  null === undefined; // false  // Los Strings funcionan como arreglos de caracteres -// Puedes accesar a cada caracter con la función charAt() +// Puedes acceder a cada caracter con la función charAt()  "Este es un String".charAt(0);  // = 'E'  // ...o puedes usar la función substring() para acceder a pedazos más grandes @@ -186,7 +186,7 @@ miObjeto.miLlave; // = "miValor"  // agregar nuevas llaves.  miObjeto.miTerceraLlave = true; -// Si intentas accesar con una llave que aún no está asignada tendrás undefined. +// Si intentas acceder con una llave que aún no está asignada tendrás undefined.  miObjeto.miCuartaLlave; // = undefined  /////////////////////////////////// @@ -301,7 +301,7 @@ i; // = 5 - en un lenguaje que da ámbitos por bloque esto sería undefined, per  //inmediatamente", que preveé variables temporales de fugarse al ámbito global  (function(){      var temporal = 5; -    // Podemos accesar al ámbito global asignando al 'objeto global', el cual +    // Podemos acceder al ámbito global asignando al 'objeto global', el cual      // en un navegador siempre es 'window'. El objeto global puede tener      // un nombre diferente en ambientes distintos, por ejemplo Node.js .      window.permanente = 10; @@ -321,7 +321,7 @@ function decirHolaCadaCincoSegundos(nombre){          alert(texto);      }      setTimeout(interna, 5000); -    // setTimeout es asíncrono, así que la funcion decirHolaCadaCincoSegundos  +    // setTimeout es asíncrono, así que la función decirHolaCadaCincoSegundos       // terminará inmediatamente, y setTimeout llamará a interna() a los cinco segundos      // Como interna está "cerrada dentro de" decirHolaCadaCindoSegundos, interna todavía tiene      // acceso a la variable 'texto' cuando es llamada. @@ -339,7 +339,7 @@ var miObjeto = {  };  miObjeto.miFuncion(); // = "¡Hola Mundo!" -// Cuando las funciones de un objeto son llamadas, pueden accesar a las variables  +// Cuando las funciones de un objeto son llamadas, pueden acceder a las variables   // del objeto con la palabra clave 'this'.  miObjeto = {      miString: "¡Hola Mundo!", @@ -401,11 +401,11 @@ var MiConstructor = function(){  miNuevoObjeto = new MiConstructor(); // = {miNumero: 5}  miNuevoObjeto.miNumero; // = 5 -// Todos los objetos JavaScript tienen un 'prototipo'. Cuando vas a accesar a una +// Todos los objetos JavaScript tienen un 'prototipo'. Cuando vas a acceder a una  // propiedad en un objeto que no existe en el objeto el intérprete buscará en  // el prototipo. -// Algunas implementaciones de JavaScript te permiten accesar al prototipo de  +// Algunas implementaciones de JavaScript te permiten acceder al prototipo de   // un objeto con la propiedad __proto__. Mientras que esto es útil para explicar  // prototipos, no es parte del estándar; veremos formas estándar de usar prototipos  // más adelante. @@ -440,7 +440,7 @@ miPrototipo.sentidoDeLaVida = 43;  miObjeto.sentidoDeLaVida; // = 43  // Mencionabamos anteriormente que __proto__ no está estandarizado, y que no  -// existe una forma estándar de accesar al prototipo de un objeto. De todas formas. +// existe una forma estándar de acceder al prototipo de un objeto. De todas formas.  // hay dos formas de crear un nuevo objeto con un prototipo dado.  // El primer método es Object.create, el cual es una adición reciente a JavaScript, @@ -476,7 +476,7 @@ typeof miNumero; // = 'number'  typeof miNumeroObjeto; // = 'object'  miNumero === miNumeroObjeyo; // = false  if (0){ -    // Este código no se ejecutara porque 0 es false. +    // Este código no se ejecutará porque 0 es false.  }  // Aún así, los objetos que envuelven y los prototipos por defecto comparten diff --git a/es-es/json-es.html.markdown b/es-es/json-es.html.markdown index fff678eb..c98049f9 100644 --- a/es-es/json-es.html.markdown +++ b/es-es/json-es.html.markdown @@ -21,22 +21,22 @@ JSON en su forma más pura no tiene comentarios, pero la mayoría de los parsead    "llaves": "siempre debe estar entre comillas (ya sean dobles o simples)",    "numeros": 0,    "strings": "Høla, múndo. Todo el unicode está permitido, así como \"escapar\".", -  "soporta booleanos?": true, -  "vacios": null, +  "¿soporta booleanos?": true, +  "vacíos": null,    "numero grande": 1.2e+100,    "objetos": { -    "comentario": "La mayoria de tu estructura vendra de objetos.", +    "comentario": "La mayoría de tu estructura vendrá de objetos.",      "arreglo": [0, 1, 2, 3, "Los arreglos pueden contener cualquier cosa.", 5],      "otro objeto": { -      "comentario": "Estas cosas pueden estar anidadas, muy util." +      "comentario": "Estas cosas pueden estar anidadas, muy útil."      }    }, -  "tonteria": [ +  "tontería": [      {        "fuentes de potasio": ["bananas"]      }, @@ -50,10 +50,10 @@ JSON en su forma más pura no tiene comentarios, pero la mayoría de los parsead    "estilo alternativo": {      "comentario": "Mira esto!" -  , "posicion de la coma": "no importa - mientras este antes del valor, entonces sera valido" -  , "otro comentario": "que lindo" +  , "posición de la coma": "no importa - mientras este antes del valor, entonces sera válido" +  , "otro comentario": "qué lindo"    }, -  "eso fue rapido": "Y, estas listo. Ahora sabes todo lo que JSON tiene para ofrecer." +  "eso fue rapido": "Y, estás listo. Ahora sabes todo lo que JSON tiene para ofrecer."  }  ``` diff --git a/es-es/python3-es.html.markdown b/es-es/python3-es.html.markdown index 1c69481a..05fd7065 100644 --- a/es-es/python3-es.html.markdown +++ b/es-es/python3-es.html.markdown @@ -97,7 +97,7 @@ not False  # => True  None  # => None  # No uses el símbolo de igualdad `==` para comparar objetos con None -# Usa `is` en lugar de +# Usa `is` en su lugar  "etc" is None #=> False  None is None  #=> True @@ -383,7 +383,7 @@ def keyword_args(**kwargs):  keyword_args(pie="grande", lago="ness") #=> {"pie": "grande", "lago": "ness"} -# You can do both at once, if you like# Puedes hacer ambas a la vez si quieres +# Puedes hacer ambas a la vez si quieres  def todos_los_argumentos(*args, **kwargs):      print args      print kwargs @@ -478,7 +478,7 @@ Humano.roncar() #=> "*roncar*"  # Puedes importar módulos  import math -print(math.sqrt(16)) #=> 4 +print(math.sqrt(16)) #=> 4.0  # Puedes obtener funciones específicas desde un módulo  from math import ceil, floor @@ -511,7 +511,7 @@ def duplicar_numeros(iterable):      for i in iterable:          yield i + i -# Un generador cera valores sobre la marcha. +# Un generador crea valores sobre la marcha.  # En vez de generar y retornar todos los valores de una vez, crea uno en cada iteración.  # Esto significa que valores más grandes que 15 no serán procesados en 'duplicar_numeros'.  # Fíjate que 'range' es un generador. Crear una lista 1-900000000 tomaría mucho tiempo en crearse. diff --git a/es-es/ruby-es.html.markdown b/es-es/ruby-es.html.markdown index d8b67fe7..e3e43c18 100644 --- a/es-es/ruby-es.html.markdown +++ b/es-es/ruby-es.html.markdown @@ -29,7 +29,7 @@ Nadie los usa.  Tu tampoco deberías  =end -# Lo primero y principal: Todo es un objeto +# En primer lugar: Todo es un objeto  # Los números son objetos @@ -128,7 +128,7 @@ ruta = '/mal/nombre/'  # Los símbolos (son objetos)  # Los símbolos son inmutables, constantes reusables representadas internamente por un -# valor entero. Son usalmente usados en vez de strings para expresar eficientemente +# valor entero. Son normalmente usados en vez de strings para expresar eficientemente  # valores específicos y significativos  :pendiente.class #=> Symbol @@ -156,7 +156,7 @@ arreglo[0] #=> 1  arreglo.first #=> 1  arreglo[12] #=> nil -# Tal como la aritmética, el acceso como variable[índice] +# Al igual que en aritmética, el acceso como variable[índice]  # es sólo azúcar sintáctica  # para llamar el método [] de un objeto  arreglo.[] 0 #=> 1 diff --git a/es-es/swift-es.html.markdown b/es-es/swift-es.html.markdown new file mode 100644 index 00000000..c04ab02b --- /dev/null +++ b/es-es/swift-es.html.markdown @@ -0,0 +1,596 @@ +--- +language: 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"] +translators: +    - ["David Hsieh", "http://github.com/deivuh"] +lang: es-es +filename: learnswift-es.swift +--- + +Swift es un lenguaje de programación para el desarrollo en iOS y OS X creado +por Apple. Diseñado para coexistir con Objective-C y ser más resistente contra  +el código erroneo, Swift fue introducido en el 2014 en el WWDC, la conferencia +de desarrolladores de Apple. + +Véase también la guía oficial de Apple, [getting started guide](https://developer.apple.com/library/prerelease/ios/referencelibrary/GettingStarted/DevelopiOSAppsSwift/), el cual tiene un completo tutorial de Swift. + + +```swift +// Importar un módulo +import UIKit + +// +// MARK: Básicos +// + +// XCode soporta referencias para anotar tu código y agregarlos a lista de la  +// barra de saltos. +// MARK: Marca de sección +// TODO: Hacer algo pronto +// FIXME: Arreglar este código + +// En Swift 2, println y print fueron combinados en un solo método print.  +// Print añade una nueva línea automáticamente. +print("Hola, mundo") // println ahora es print +print("Hola, mundo", appendNewLine: false) // print sin agregar nueva línea + +// Valores de variables (var) pueden cambiar después de ser asignados +// Valores de constrantes (let) no pueden cambiarse después de ser asignados + +var myVariable = 42 +let øπΩ = "value" // nombres de variable unicode +let π = 3.1415926 +let convenience = "keyword" // nombre de variable contextual +// Las declaraciones pueden ser separadas por punto y coma (;) +let weak = "keyword"; let override = "another keyword"  +// Los acentos abiertos (``) permiten utilizar palabras clave como nombres de  +// variable +let `class` = "keyword"  +let explicitDouble: Double = 70 +let intValue = 0007 // 7 +let largeIntValue = 77_000 // 77000 +let label = "some text " + String(myVariable) // Conversión (casting) +let piText = "Pi = \(π), Pi 2 = \(π * 2)" // Interpolación de string  + +// Valores específicos de la compilación (build) +// utiliza la configuración -D  +#if false +    print("No impreso") +    let buildValue = 3 +#else +    let buildValue = 7 +#endif +print("Build value: \(buildValue)") // Build value: 7 + +/* +    Las opcionales son un aspecto del lenguaje Swift que permite el  +    almacenamiento de un valor `Some` (algo) o `None` (nada). +     +    Debido a que Swift requiere que cada propiedad tenga un valor,  +    hasta un valor 'nil' debe de ser explicitamente almacenado como un  +    valor opcional. +     +    Optional<T> es un enum. +*/ +var someOptionalString: String? = "opcional" // Puede ser nil +// Al igual que lo anterior, pero ? es un operador postfix (sufijo) +var someOptionalString2: Optional<String> = "opcional" + +if someOptionalString != nil { +    // No soy nil +    if someOptionalString!.hasPrefix("opt") { +        print("Tiene el prefijo") +    } +     +    let empty = someOptionalString?.isEmpty +} +someOptionalString = nil + +// Opcional implícitamente desenvuelto +var unwrappedString: String! = "Un valor esperado." +// Al igual que lo anterior, pero ! es un operador postfix (sufijo) +var unwrappedString2: ImplicitlyUnwrappedOptional<String> = "Un valor esperado." + +if let someOptionalStringConstant = someOptionalString { +    // tiene valor `Some` (algo), no nil +    if !someOptionalStringConstant.hasPrefix("ok") { +        // No tiene el prefijo +    } +} + +// Swift tiene soporte de almacenamiento para cualquier tipo de valor. +// AnyObject == id +// A diferencia de Objective-C `id`, AnyObject funciona con cualquier  +// valor (Class, Int, struct, etc) +var anyObjectVar: AnyObject = 7 +anyObjectVar = "Cambiado a un valor string, no es buena práctica, pero posible." + +/* +    Comentar aquí +     +    /* +        Comentarios anidados también son soportados +    */ +*/ + +// +// MARK: Colecciones +// + +/* +    Tipos Array (arreglo) y Dictionary (diccionario) son structs (estructuras).  +    Así que `let` y `var` también indican si son mudables (var) o  +    inmutables (let) durante la declaración de sus tipos.     +*/ + +// Array (arreglo) +var shoppingList = ["catfish", "water", "lemons"] +shoppingList[1] = "bottle of water" +let emptyArray = [String]() // let == inmutable +let emptyArray2 = Array<String>() // igual que lo anterior +var emptyMutableArray = [String]() // var == mudable + + +// Dictionary (diccionario) +var occupations = [ +    "Malcolm": "Captain", +    "kaylee": "Mechanic" +] +occupations["Jayne"] = "Public Relations" +let emptyDictionary = [String: Float]() // let == inmutable +let emptyDictionary2 = Dictionary<String, Float>() // igual que lo anterior +var emptyMutableDictionary = [String: Float]() // var == mudable + + +// +// MARK: Flujo de control +// + +// Ciclo for (array) +let myArray = [1, 1, 2, 3, 5] +for value in myArray { +    if value == 1 { +        print("Uno!") +    } else { +        print("No es uno!") +    } +} + +// Ciclo for (dictionary) +var dict = ["uno": 1, "dos": 2] +for (key, value) in dict { +    print("\(key): \(value)") +} + +// Ciclo for (range) +for i in -1...shoppingList.count { +    print(i) +} +shoppingList[1...2] = ["steak", "peacons"] +// Utilizar ..< para excluir el último valor + +// Ciclo while  +var i = 1 +while i < 1000 { +    i *= 2 +} + +// Ciclo do-while +do { +    print("Hola") +} while 1 == 2 + +// Switch +// Muy potente, se puede pensar como declaraciones `if` con _azúcar sintáctico_ +// Soportan String, instancias de objetos, y primitivos (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: // obligatorio (se debe cumplir con todos los posibles valores de entrada) +    let vegetableComment = "Everything tastes good in soup." +} + + +// +// MARK: Funciones +// + +// Funciones son un tipo de primera-clase, quiere decir que pueden ser anidados +// en funciones y pueden ser pasados como parámetros + +// Función en documentación de cabeceras Swift (formato reStructedText) + +/** +    Una operación de saludo + +    - Una viñeta en la documentación +    - Otra viñeta en la documentación + +    :param: name Un nombre +    :param: day Un día +    :returns: Un string que contiene el valor de name y day +*/ +func greet(name: String, day: String) -> String { +    return "Hola \(name), hoy es \(day)." +} +greet("Bob", "Martes") + +// Similar a lo anterior, a excepción del compartamiento de los parámetros  +// de la función +func greet2(requiredName: String, externalParamName localParamName: String) -> String { +    return "Hola \(requiredName), hoy es el día \(localParamName)" +} +greet2(requiredName:"John", externalParamName: "Domingo") + +// Función que devuelve múltiples valores en una tupla +func getGasPrices() -> (Double, Double, Double) { +    return (3.59, 3.69, 3.79) +} +let pricesTuple = getGasPrices() +let price = pricesTuple.2 // 3.79 +// Ignorar tupla (u otros) valores utilizando _ (guión bajo) +let (_, price1, _) = pricesTuple // price1 == 3.69 +print(price1 == pricesTuple.1) // true +print("Gas price: \(price)") + +// Cantidad variable de argumentos +func setup(numbers: Int...) { +    // Es un arreglo +    let number = numbers[0] +    let argCount = numbers.count +} + +// Pasando y devolviendo funciones +func makeIncrementer() -> (Int -> Int) { +    func addOne(number: Int) -> Int { +        return 1 + number +    } +    return addOne +} +var increment = makeIncrementer() +increment(7) + +// Pasando como referencia +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 (Clausuras) +// +var numbers = [1, 2, 6] + +// Las funciones son un caso especial de closure ({}) + +// Ejemplo de closure. +// `->` Separa los argumentos del tipo de retorno +// `in` Separa la cabecera del cuerpo del closure +numbers.map({ +    (number: Int) -> Int in +    let result = 3 * number +    return result +}) + +// Cuando se conoce el tipo, como en lo anterior, se puede hacer esto +numbers = numbers.map({ number in 3 * number }) +// o esto +//numbers = numbers.map({ $0 * 3 }) + +print(numbers) // [3, 6, 18] + +// Closure restante +numbers = sorted(numbers) { $0 > $1 } + +print(numbers) // [18, 6, 3] + +// Bastante corto, debido a que el operador < infiere los tipos + +numbers = sorted(numbers, < ) + +print(numbers) // [3, 6, 18] + +// +// MARK: Estructuras +// + +// Las estructuras y las clases tienen capacidades similares +struct NamesTable { +    let names = [String]() +     +    // Subscript personalizado +    subscript(index: Int) -> String { +        return names[index] +    } +} + +// Las estructuras tienen un inicializador designado autogenerado (implícitamente) +let namesTable = NamesTable(names: ["Me", "Them"]) +let name = namesTable[1] +print("Name is \(name)") // Name is Them + +// +// MARK: Clases +// + +// Las clases, las estructuras y sus miembros tienen tres niveles de control de acceso +// Éstos son: internal (predeterminado), public, private + +public class Shape { +    public func getArea() -> Int { +        return 0; +    } +} + +// Todos los métodos y las propiedades de una clase son public (públicas) +// Si solo necesitas almacenar datos en un objecto estructurado, +// debes de utilizar `struct` + +internal class Rect: Shape { +    var sideLength: Int = 1 +     +    // Getter y setter personalizado +    private var perimeter: Int { +        get { +            return 4 * sideLength +        } +        set { +            // `newValue` es una variable implícita disponible para los setters +            sideLength = newValue / 4 +        } +    } +     +    // Lazily loading (inicialización bajo demanda) a una propiedad  +    // subShape queda como nil (sin inicializar) hasta que getter es llamado +    lazy var subShape = Rect(sideLength: 4) +     +    // Si no necesitas un getter y setter personalizado +    // pero aún quieres ejecutar código antes y después de hacer get o set  +    // a una propiedad, puedes utilizar `willSet` y `didSet`     +    var identifier: String = "defaultID" { +        // El argumento `willSet` será el nombre de variable para el nuevo valor +        willSet(someIdentifier) { +            print(someIdentifier) +        } +    } +     +    init(sideLength: Int) { +        self.sideLength = sideLength +        // Siempre poner super.init de último al momento de inicializar propiedades  +        // personalizadas +        super.init() +    } +     +    func shrink() { +        if sideLength > 0 { +            --sideLength +        } +    } +     +    override func getArea() -> Int { +        return sideLength * sideLength +    } +} + +// Una clase simple `Square` que extiende de `Rect` +class Square: Rect { +    convenience init() { +        self.init(sideLength: 5) +    } +} + +var mySquare = Square() +print(mySquare.getArea()) // 25 +mySquare.shrink() +print(mySquare.sideLength) // 4 + +// Conversión de tipo de instancia +let aShape = mySquare as Shape + +// Comparar instancias, no es igual a == que compara objetos (equal to) +if mySquare === mySquare { +    print("Yep, it's mySquare") +} + +// Inicialización (init) opcional +class Circle: Shape { +    var radius: Int +    override func getArea() -> Int { +        return 3 * radius * radius +    } +     +    // Un signo de interrogación como sufijo después de `init` es un init opcional +    // que puede devolver 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 { +    // no será ejecutado debido a que myEmptyCircle es nil +    print("circle is not nil") +} + + +// +// MARK: Enums +// + + +// Los enums pueden ser opcionalmente de un tipo específico o de su propio tipo +// Al igual que las clases, pueden contener métodos + +enum Suit { +    case Spades, Hearts, Diamonds, Clubs +    func getIcon() -> String { +        switch self { +        case .Spades: return "♤" +        case .Hearts: return "♡" +        case .Diamonds: return "♢" +        case .Clubs: return "♧" +        } +    } +} + +// Los valores de enum permite la sintaxis corta, sin necesidad de poner  +// el tipo del enum cuando la variable es declarada de manera explícita +var suitValue: Suit = .Hearts + +// Enums de tipo no-entero requiere asignaciones de valores crudas directas  +enum BookName: String { +    case John = "John" +    case Luke = "Luke" +} +print("Name: \(BookName.John.rawValue)") + +// Enum con valores asociados +enum Furniture { +    // Asociación con Int +    case Desk(height: Int) +    // Asociación con String e 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 +// + +// `protocol` puede requerir que los tipos tengan propiedades +// de instancia específicas, métodos de instancia, métodos de tipo,  +// operadores, y subscripts + + +protocol ShapeGenerator { +    var enabled: Bool { get set } +    func buildShape() -> Shape +} + +// Protocolos declarados con @objc permiten funciones opcionales, +// que te permite evaluar conformidad +@objc protocol TransformShape { +    optional func reshaped() +    optional func canReshape() -> Bool +} + +class MyShape: Rect { +    var delegate: TransformShape? +     +    func grow() { +        sideLength += 2 + +        // Pon un signo de interrogación después de la propiedad opcional,  +        // método, o subscript para ignorar un valor nil y devolver nil  +        // en lugar de  tirar un error de tiempo de ejecución  +        // ("optional chaining")         +        if let allow = self.delegate?.canReshape?() { +            // test for delegate then for method +            self.delegate?.reshaped?() +        } +    } +} + + +// +// MARK: Otros +// + +// `extension`: Agrega funcionalidades a tipos existentes + +// Square ahora se "conforma" al protocolo `Printable`  +extension Square: Printable { +    var description: String { +        return "Area: \(self.getArea()) - ID: \(self.identifier)" +    } +} + +print("Square: \(mySquare)") + +// También puedes hacer extend a tipos prefabricados (built-in) +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: Similar Java y C#. Utiliza la palabra clave `where` para +// especificar los requerimientos de los genéricos. + +func findIndex<T: Equatable>(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 puede empezar con los siguientes caracteres: +//      / = - + * % < > ! & | ^ . ~ +// o +// Caracteres unicode: math, symbol, arrow, dingbat, y line/box. +prefix operator !!! {} + +// Un operador prefix que triplica la longitud del lado cuando es utilizado +prefix func !!! (inout shape: Square) -> Square { +    shape.sideLength *= 3 +    return shape +} + +// Valor actual +print(mySquare.sideLength) // 4 + +// Cambiar la longitud del lado utilizando el operador !!!,  +// incrementa el tamaño por 3 +!!!mySquare +print(mySquare.sideLength) // 12 +``` | 
