Professional Documents
Culture Documents
NOTA
Para obtener la documentacin preliminar de una futura actualizacin de la lengua
Swift, ver El Swift Lenguaje de Programacin .
Swift es un nuevo lenguaje de programacin para iOS y OS X aplicaciones que se basa
en la mejor de C y Objective-C, sin las limitaciones de compatibilidad C. Swift adopta
patrones de programacin seguras y aade caractersticas modernas para hacer la
programacin ms fcil, ms flexible y ms divertido. Borrn y cuenta nueva de Swift,
respaldadas por los maduros y los marcos de cacao y cacao Touch muy querida, es una
oportunidad para re-imaginar cmo funciona el desarrollo de software.
Swift ha estado aos en la fabricacin. Manzana sent las bases de Swift por el avance
de nuestro compilador, depurador, y la infraestructura marco existente. Hemos
simplificado la gestin de memoria con el recuento de referencias automtico
(ARC). Nuestra pila marco, construido sobre la base slida de la Fundacin y el Cacao,
se ha modernizado y estandarizada en todo. Objective-C en s ha evolucionado para
soportar bloques, literales coleccin, y los mdulos, lo que permite la adopcin marco
de las tecnologas lingsticas modernas sin interrupciones. Gracias a este trabajo
preliminar, ahora podemos introducir un nuevo lenguaje para el futuro del desarrollo de
software de Apple.
Swift se siente familiar para los desarrolladores de Objective-C. Adopta la legibilidad
de los parmetros con nombre de Objective-C y el poder del modelo de objeto dinmico
de Objective-C. Proporciona un acceso transparente a los marcos existentes de cacao y
mezclar y combinar la interoperabilidad con cdigo de Objective-C. La construccin de
esta base comn, Swift introduce muchas nuevas caractersticas y unifica las partes
procesales y orientados a objetos del lenguaje.
Swift es amigable para los nuevos programadores. Es el primer lenguaje de
programacin de sistemas de calidad industrial que es tan expresiva y agradable como
un lenguaje de script. Es compatible con juegos infantiles, una caracterstica innovadora
que permite a los programadores para experimentar con el cdigo Swift y ver los
resultados inmediatamente, sin la sobrecarga de la creacin y ejecucin de una
aplicacin.
Swift combina lo mejor del pensamiento lengua moderna con la sabidura de la cultura
de ingeniera de Apple en general. El compilador est optimizado para el rendimiento, y
el idioma se ha optimizado para el desarrollo, sin comprometer a ambos. Est diseado
para escalar de "hola, mundo" a todo un sistema operativo. Todo esto hace que Swift
una inversin de futuro slido para los desarrolladores y para Apple.
Swift es una fantstica manera de escribir iOS y OS X aplicaciones, y seguir
evolucionando con nuevas caractersticas y capacidades. Nuestras metas para Swift son
ambiciosos. No podemos esperar a ver lo que creas con l.
A Swift tour
La tradicin sugiere que el primer programa en un nuevo idioma debe imprimir las
palabras "Hola, mundo!" En la pantalla. En Swift, esto se puede hacer en una sola lnea:
println ( "Hola, mundo!" )
Si ha escrito cdigo en C o Objective-C, esta sintaxis se parece familiar a usted-en
Swift, esta lnea de cdigo es un programa completo. No es necesario importar una
biblioteca independiente para la funcionalidad como de entrada / salida o manejo de
cadenas. El cdigo escrito en el mbito mundial se utiliza como punto de entrada para el
programa, por lo que no es necesario un principal funcin. Tambin no es necesario
escribir un punto y coma al final de cada sentencia.
Este tour le da suficiente informacin para empezar a escribir cdigo en Swift
mostrando cmo lograr una variedad de tareas de programacin. No se preocupe si
usted no entiende algo, todo lo presentado en este tour se explica en detalle en el resto
de este libro.
NOTA
Para una mejor experiencia, abra este captulo como un parque infantil en
Xcode. Parques infantiles permiten editar los listados de cdigo y ver el resultado
inmediatamente.
Descargar juegos
Los valores simples
Utilice dejar de hacer una constante y var para hacer una variable. El valor de una
constante no necesita ser conocido en tiempo de compilacin, pero usted debe asignarle
un valor exactamente una vez. Esto significa que puede usar constantes para nombrar un
valor que se determina una vez, pero utiliza en muchos lugares.
var myVariable = 42
myVariable = 50
let myConstant = 42
Una constante o variable deben tener el mismo tipo que el valor que se desea asignar a
la misma. Sin embargo, no siempre se tiene que escribir el tipo
explcitamente. Proporcionar un valor cuando se crea una constante o variable permite
al compilador deducir su tipo. En el ejemplo anterior, el compilador infiere
quemyVariable es un nmero entero debido a que su valor inicial es un nmero
entero.
Si el valor inicial no proporciona suficiente informacin (o si no hay valor inicial),
especificar el tipo de escritura que despus de la variable, separados por dos puntos.
let implicitInteger = 70
let width = 94
2
let apples = 3
let oranges = 5
var occupations = [
"Malcolm": "Captain",
"Kaylee": "Mechanic",
shoppingList = []
occupations = [:]
Control de flujo
Utilice si y cambiar para hacer los condicionales, y utilizar para en , para , mientras , y hacer - mientras quepara hacer bucles. Los
parntesis alrededor de la variable de condicin o bucle son opcionales. Se requieren los
apoyos de todo el cuerpo.
var teamScore = 0
if score > 50 {
teamScore += 3
} else {
teamScore += 1
teamScore
NOTA
En el cdigo anterior, teamScore se escribe en una lnea por s mismo. Esta es una
manera simple de ver el valor de una variable dentro de un parque infantil.
En un caso de declaracin, la condicin debe ser una expresin-este Booleano
significa que el cdigo comosi la puntuacin {...} es un error, no una
comparacin implcita a cero.
Usted puede utilizar si y dejar juntos para trabajar con valores que pudieran
faltar. Estos valores se representan como opcionales. Un valor opcional o bien contiene
un valor o contiene cero para indicar que el valor no est presente. Escriba un signo de
interrogacin ( ? ) despus de que el tipo de un valor para marcar el valor como
opcional.
optionalString == nil
}
EXPERIMENTO
Cambie optionalName a nil . Lo saludo Qu se obtiene? Aadir
una cosa clusula que establece un saludo diferente si optionalName es nula .
Si el valor opcional es nula , el condicional es falsa y el cdigo entre llaves se
omite. De lo contrario, el valor opcional se desenvuelve y se asigna a la constante
despus de let , lo que hace que el valor envolver disponible dentro del bloque de
cdigo.
Switches soportan cualquier tipo de datos y una amplia variedad de operaciones de
comparacin-que no se limitan a nmeros enteros y las pruebas para la igualdad.
switch vegetable {
case "celery":
default:
}
EXPERIMENTO
Trate de no incluir el caso por defecto. Qu error Qu se obtiene?
Ntese cmo dejar que se puede utilizar en un patrn para asignar el valor que
coincide con esa parte de un patrn a una constante.
Despus de ejecutar el cdigo dentro de la caja del interruptor que haca juego, el
programa sale de la sentencia switch. Ejecucin no contina al siguiente caso, lo que no
hay necesidad de romper explcitamente del interruptor al final del cdigo de cada caso.
Se utiliza para - en iterar sobre los elementos de un diccionario, proporcionando un
par de nombres a utilizar para cada par clave-valor. Los diccionarios son una coleccin
desordenada, por lo que sus claves y valores se repiten a lo largo en un orden arbitrario.
let interestingNumbers = [
var largest = 0
largest = number
largest
EXPERIMENTO
Aadir otra variable para realizar un seguimiento de qu tipo de nmero es el ms
grande, as como lo que mayor nmero era.
Utilice mientras que repetir un bloque de cdigo hasta que una condicin cambia. El
estado de un bucle puede estar en el extremo en su lugar, asegurando que el bucle se
ejecuta al menos una vez.
var n = 2
n=n*2
var m = 2
do {
m=m*2
m
Usted puede mantener un ndice en un bucle, ya sea mediante el uso de .. < para
hacer una serie de ndices o escribiendo un explcito inicializacin, condicin, y el
incremento. Estos dos lazos hacen lo mismo:
var firstForLoop = 0
for i in 0..<4 {
firstForLoop += i
firstForLoop
var secondForLoop = 0
secondForLoop += i
secondForLoop
Utilice .. < para hacer una serie que omite su valor superior, y usar ... para hacer
una gama que incluye ambos valores.
Funciones y cierres
Utilice func para declarar una funcin. Llamar a una funcin siguiendo su nombre con
una lista de argumentos entre parntesis. Uso -> para separar los nombres de los
parmetros y tipos de tipo de retorno de la funcin.
greet("Bob", "Tuesday")
EXPERIMENTO
Retire el da parmetro. Agregar un parmetro para incluir el almuerzo especial de hoy
en el saludo.
Utilice una tupla para hacer un ejemplo de valor para el compuesto, para devolver
varios valores de una funcin. Los elementos de una tupla se pueden denominar por su
nombre o por nmero.
func calculateStatistics(scores: [Int]) -> (min: Int, max: Int, sum: Int) {
var sum = 0
max = score
min = score
sum += score
statistics.sum
statistics.2
Las funciones tambin pueden tomar un nmero variable de argumentos, a su recogida
en una matriz.
var sum = 0
sum += number
return sum
sumOf()
var y = 10
func add() {
y += 5
add()
return y
returnFifteen()
Las funciones son un tipo de primera clase. Esto significa que una funcin puede
devolver otra funcin como su valor.
return 1 + number
return addOne
increment(7)
Una funcin puede tener otra funcin como uno de sus argumentos.
if condition(item) {
return true
return false
hasAnyMatches(numbers, lessThanTen)
Las funciones son en realidad un caso especial de cierres: bloques de cdigo que se
pueden llamar ms tarde. El cdigo en un cierre tiene acceso a cosas como las variables
y funciones que estaban disponibles en el mbito donde se cre el cierre, incluso si el
cierre es en un mbito diferente cuando se ejecuta-que viste un ejemplo de esto ya con
funciones anidadas. Usted puede escribir un cierre sin nombre rodeando cdigo con
llaves ( {} ). Utilice en separar los argumentos y el tipo de retorno del cuerpo.
numbers.map({
return result
})
EXPERIMENTO
Vuelva a escribir el cierre para volver a cero para todos los nmeros impares.
Usted tiene varias opciones para la escritura de los cierres de forma ms
concisa. Cuando el tipo de un cierre que ya se conoce, por ejemplo, la devolucin de
llamada de un delegado, se puede omitir el tipo de sus parmetros, el tipo de retorno, o
ambos. Cierres sola instruccin implcitamente devuelven el valor de su nica
declaracin.
mappedNumbers
Se puede hacer referencia a los parmetros de nmero en vez de por su nombre-este
enfoque es especialmente til en los cierres muy cortos. Un cierre pasado como el
ltimo argumento de la funcin puede aparecer inmediatamente despus del parntesis.
sortedNumbers
Objetos y clases
Utilice la clase seguido del nombre de la clase para crear una clase. Una
declaracin de propiedad en una clase se escribe de la misma manera como una
declaracin de constante o variable, excepto que es en el contexto de una clase. De igual
forma, mtodo y funcin declaraciones se escriben de la misma manera.
class Shape {
var numberOfSides = 0
}
EXPERIMENTO
Aadir una propiedad constante con let , y aadir otro mtodo que toma un
argumento.
Crear una instancia de una clase, poniendo entre parntesis despus del nombre de la
clase. Utilice la sintaxis con punto para acceder a las propiedades y mtodos de la
instancia.
shape.numberOfSides = 7
class NamedShape {
init(name: String) {
self.name = name
}
Observe cmo auto se utiliza para distinguir el nombre de la propiedad
del nombre de argumento para el inicializador. Los argumentos para el inicializador
se pasan como una llamada a la funcin cuando se crea una instancia de la clase. Cada
propiedad necesita un valor asignado, ya sea en su declaracin (como
connumberOfSides ) o en el inicializador (como con el nombre ).
Utilice deinit para crear un deinitializer si es necesario realizar alguna tarea de
limpieza antes de que se cancela la asignacin del objeto.
Las subclases incluyen su nombre despus de su superclase nombre de la clase,
separados por dos puntos.No hay ningn requisito para las clases subclase cualquier
clase raz estndar, por lo que puede incluir u omitir una superclase, segn sea
necesario.
Los mtodos en una subclase que anulan la implementacin de la superclase estn
marcados con el override-overriding un mtodo por el accidente, sin anulacin ,
es detectado por el compilador como un error. El compilador tambin detecta con
mtodos de anulacin que en realidad no anulan cualquier mtodo en la superclase.
self.sideLength = sideLength
super.init(name: name)
numberOfSides = 4
10
test.area()
test.simpleDescription()
EXPERIMENTO
Haga otra subclase de NamedShape llamado Crculo que tiene un radio y un
nombre como argumentos a su inicializador. Implementar un rea y
un simpleDescription mtodo en el Crculo de clase.
Adems de las propiedades simples que se almacenan, las propiedades pueden tener un
getter y un setter.
self.sideLength = sideLength
super.init(name: name)
numberOfSides = 3
get {
set {
11
triangle.perimeter
triangle.perimeter = 9.9
triangle.sideLength
En la incubadora de permetro , el nuevo valor tiene el nombre
implcito nuevoValor . Puede proporcionar un nombre explcito entre parntesis
despus de conjunto .
Observe que el inicializador para la EquilateralTriangle clase tiene tres etapas
diferentes:
1. Establecer el valor de las propiedades que la subclase declara.
2. Llamando inicializador de la superclase.
3. Cambiar el valor de las propiedades definidas por la superclase. Cualquier trabajo de
configuracin adicional que utiliza mtodos getters o setters tambin se puede hacer
en este momento.
Si no es necesario para calcular la propiedad, pero todava tiene que proporcionar el
cdigo que se ejecuta antes y despus de fijar un nuevo valor,
utilice willSet y didSet . Por ejemplo, la clase a continuacin se asegura de que la
longitud del lado de su tringulo es siempre la misma que la longitud del lado de su
cuadrado.
class TriangleAndSquare {
willSet {
square.sideLength = newValue.sideLength
willSet {
triangle.sideLength = newValue.sideLength
triangleAndSquare.square.sideLength
triangleAndSquare.triangle.sideLength
12
triangleAndSquare.triangle.sideLength
Los mtodos de las clases tienen una diferencia importante de funciones. Los nombres
de parmetros en funciones slo se utilizan dentro de la funcin, pero los parmetros
nombres en los mtodos tambin se utilizan cuando se llama al mtodo (excepto para el
primer parmetro). Por defecto, un mtodo tiene el mismo nombre para sus parmetros
cuando se llama a ella y dentro del mtodo en s. Se puede especificar un segundo
nombre, que se utiliza dentro del mtodo.
class Counter {
counter.incrementBy(2, numberOfTimes: 7)
Cuando se trabaja con valores opcionales, puede escribir ? antes de las operaciones,
como los mtodos, propiedades y subndices. Si el valor antes de la ? es nula , todo
despus de la ? se ignora y el valor de toda la expresin es nula . De lo contrario, el
valor es opcional sin envolver, y todo despus de la ? acta sobre el valor de
envolver. En ambos casos, el valor de toda la expresin es un valor opcional.
case Ace = 1
case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten
switch self {
case .Ace:
return "ace"
case .Jack:
return "jack"
case .Queen:
return "queen"
case .King:
13
return "king"
default:
return String(self.toRaw())
}
Los valores de los miembros de una enumeracin son valores reales, no slo otra
manera de escribir sus valores brutos. De hecho, en los casos donde no hay un valor en
bruto significativo, usted no tiene que proporcionar una.
enum Suit {
switch self {
case .Spades:
return "spades"
case .Hearts:
return "hearts"
case .Diamonds:
return "diamonds"
case .Clubs:
return "clubs"
14
struct Card {
enum ServerResponse {
case Error(String)
15
switch success {
}
EXPERIMENTO
Aadir un tercer caso a ServerResponse y para el interruptor.
Observe cmo se extraen las horas de salida y puesta del sol desde
el ServerResponse valor como parte de hacer coincidir el valor contra los casos de
conmutacin.
Protocolos y Extensiones
Utilice el protocolo para declarar un protocolo.
protocol ExampleProtocol {
}
Las clases, enumeraciones y estructuras de todo pueden adoptar protocolos.
func adjust() {
var a = SimpleClass()
a.adjust()
16
var b = SimpleStructure()
b.adjust()
self += 42
7.simpleDescription
EXPERIMENTO
Escribe una extensin para el doble tipo, que aade un absoluteValue propiedad.
Puede utilizar un nombre de protocolo al igual que cualquier otro ejemplo de tipo de
llamada, para crear una coleccin de objetos que tienen diferentes tipos, sino que todos
cumplir con un protocolo nico. Cuando se trabaja con valores cuyo tipo es un tipo de
protocolo, los mtodos fuera de la definicin de protocolo no estn disponibles.
protocolValue.simpleDescription
for i in 0..<times {
17
result.append(item)
return result
repeat("knock", 4)
Usted puede hacer las formas genricas de las funciones y mtodos, as como las clases,
enumeraciones y estructuras.
// Reimplementar tipo opcional de la biblioteca estndar de
Swift
enum OptionalValue<T> {
case None
case Some(T)
possibleInteger = .Some(100)
Use where after the type name to specify a list of requirementsfor example, to require
the type to implement a protocol, to require two types to be the same, or to require a
class to have a particular superclass.
if lhsItem == rhsItem {
return true
return false
anyCommonElements ([ 1 , 2 , 3 ], [ 3 ])
EXPERIMENTO
Modifique el anyCommonElements funcin para realizar una funcin que devuelve
una matriz de los elementos que las dos secuencias tienen en comn.
En los casos sencillos, se puede omitir cuando y simplemente escriba el nombre del
protocolo o de clase despus de dos puntos. Escribiendo <T: equatable> es lo
mismo que escribir <T donde T: equatable> .
18
Los Fundamentos
En esta pgina
Swift es un nuevo lenguaje de programacin para iOS y OS X de desarrollo de
aplicaciones. No obstante, muchas partes de Swift estarn familiarizados desde su
experiencia en el desarrollo en C y Objective-C.
Swift proporciona sus propias versiones de todos los tipos C y Objective-C
fundamentales, incluido Int para enteros, doble y flotador para los valores de
punto flotante, Bool para valores booleanos y de cadena para los datos
textuales. Swift tambin ofrece versiones potentes de los dos tipos de recoleccin
primaria, matriz yDiccionario , como se describe en Tipos Collection .
Al igual que C, Swift utiliza variables para almacenar y hacer referencia a los valores
por un nombre de identificacin. Swift tambin hace un amplio uso de variables cuyos
valores no se pueden cambiar. Estos son conocidos como constantes, y son mucho ms
poderosos que las constantes en C. Las constantes se utilizan a lo largo Swift para hacer
el cdigo ms seguro y ms clara en su intencin cuando se trabaja con valores que no
tienen que cambiar.
Adems de los tipos conocidos, Swift presenta tipos avanzadas que no se encuentran en
Objective-C, como tuplas. Tuples le permiten crear y pasar alrededor de agrupaciones
de valores. Puede usar una tupla para devolver varios valores de una funcin como un
valor nico compuesto.
Swift tambin introduce tipos opcionales, que se encargan de la ausencia de un
valor. Opcionales dicen bien "no es un valor, y que es igual a x "o" no , no es un valor
en absoluto ". Opcionales son similares al uso de nilcon punteros en Objective-C, pero
trabajan para cualquier tipo, no slo a las clases. Opcionales son ms seguros y ms
expresiva que nil punteros en Objective-C y estn en el centro de muchas de las
caractersticas ms poderosas de Swift.
Opcionales son un ejemplo del hecho de que Swift es un seguro de tipo de
idioma. Swift le ayuda a ser claro acerca de los tipos de valores de su cdigo puede
trabajar. Si parte de su cdigo espera una cuerda , la seguridad de tipos le impide
pasndole un Int por error. Esta restriccin le permite capturar y corregir los errores lo
antes posible en el proceso de desarrollo.
Constantes y Variables
Constantes y variables asociar un nombre
(como maximumNumberOfLoginAttempts o WelcomeMessage ) con un valor
de un tipo concreto (por ejemplo, el nmero 10 o la cadena "Hola" ). El valor de
una constante no se puede cambiar una vez que se establece, mientras que una variable
de puede ajustarse a un valor diferente en el futuro.
Declaracin de constantes y variables
Constantes y variables deben ser declaradas antes de ser utilizadas. Usted declara
constantes con la let de palabras clave y las variables con la var palabra clave. He
aqu un ejemplo de cmo las constantes y las variables se pueden utilizar para realizar el
seguimiento del nmero de intentos de inicio de sesin de un usuario ha hecho:
let maximumNumberOfLoginAttempts = 10
var currentLoginAttempt = 0
Este cdigo se puede leer como:
19
20
let = 3.14159
let = ""
let
= "dogcow"
Los nombres de constantes y variables no pueden contener espacios en blanco, smbolos
matemticos, flechas, de uso privado (o no vlidos) los puntos de cdigo Unicode o
caracteres de lnea y caja de dibujo.Tampoco pueden comenzar con un nmero, aunque
las cifras pueden ser incluidos en otro lugar dentro del nombre.
Una vez que se ha declarado una constante o variable de un cierto tipo, no se puede
redeclare de nuevo con el mismo nombre, o cambiarlo para almacenar valores de un
tipo diferente. Tampoco se puede cambiar una constante en una variable o una variable
en una constante.
NOTA
Si usted necesita dar una constante o variable el mismo nombre que una palabra clave
reservada Swift, rodear la palabra clave con la espalda garrapatas ( ` ) cuando se utiliza
como un nombre. Sin embargo, evite el uso de palabras clave como nombres a menos
que tenga absolutamente ninguna opcin.
Puede cambiar el valor de una variable existente a otro valor de un tipo compatible. En
este ejemplo, el valor de friendlyWelcome se cambia
de "Hola!" a "Bonjour!" :
friendlyWelcome = "Bonjour!"
languageName = "Swift++"
println(friendlyWelcome)
// prints "Bonjour!"
println es una funcin global que imprime un valor, seguido por un salto de lnea, a
una salida apropiada. En Xcode, por ejemplo, println imprime su salida en el panel
de "consola" de Xcode. (Una segunda funcin, la impresin , realiza la misma
tarea sin anexar un salto de lnea al final del valor que se va a imprimir.)
El println funcin imprime cualquier Cadena de valor se pasa a la misma:
println("This is a string")
21
// Esto es un comentario
Los comentarios multilnea empiezan con una barra inclinada seguida de un asterisco
( / * ) y terminan con un asterisco seguido de una barra diagonal ( * / ):
22
23
pequeos que se pueden almacenar en unint . Swift proporciona dos tipos de nmeros
de punto flotante firmados:
Doble representa un nmero de punto flotante de 64 bits. selo cuando los valores
de punto flotante deben ser muy grandes o particularmente precisa.
Float representa un nmero de punto flotante de 32 bits. selo cuando los valores
de punto flotante no requieren precisin de 64 bits.
NOTA
Doble tiene una precisin de al menos 15 dgitos decimales, mientras que la precisin
de flotador puede ser tan poco como 6 dgitos decimales. El tipo de punto flotante
apropiado utilizar depende de la naturaleza y el rango de valores que necesita para
trabajar en su cdigo.
Escriba Seguridad y tipo de inferencia
Swift es un seguro de tipo de idioma. Un lenguaje de tipo seguro anima a ser claro
acerca de los tipos de valores de su cdigo puede trabajar. Si parte de su cdigo espera
una cuerda , no se puede pasar un int por error.
Debido Swift es un tipo seguro, realiza escribir cheques al compilar el cdigo y
banderas cualesquiera tipos no coincidentes como errores. Esto le permite capturar y
corregir los errores lo antes posible en el proceso de desarrollo.
Tipo de comprobacin le ayuda a evitar errores cuando se trabaja con diferentes tipos de
valores. Sin embargo, esto no significa que usted tiene que especificar el tipo de cada
constante y variable que se declara. Si no se especifica el tipo de valor que necesita,
Swift utiliza la inferencia de tipos para calcular el tipo apropiado. La inferencia de tipos
permite un compilador para deducir el tipo de una expresin concreta de forma
automtica cuando se compila el cdigo, simplemente mediante el examen de los
valores suministrados por el usuario.
Debido a la inferencia de tipos, Swift requiere muchos menos declaraciones de tipo que
lenguajes como C o Objective-C. Constantes y variables todava se escriben de forma
explcita, pero gran parte del trabajo de especificar su tipo est hecho para usted.
La inferencia de tipos es particularmente til cuando se declara una constante o variable
con un valor inicial.Esto se suele hacer mediante la asignacin de un valor
literal (o literal ) a la constante o variable en el punto que se declara. (Un valor literal es
un valor que aparece directamente en el cdigo fuente, como 42 y 3,14159en los
ejemplos a continuacin.)
Por ejemplo, si se asigna un valor literal de 42 a una nueva constante sin decir de qu
tipo es, Swift infiere que desea que la constante de ser un int , porque usted ha
inicializado con un nmero que se ve como un entero:
let meaningOfLife = 42
let pi = 3.14159
24
let decimalInteger = 17
Los literales numricos pueden contener un formato extra para que sean ms fciles de
leer. Ambos nmeros enteros y flotadores pueden ser rellenados con ceros adicionales y
pueden contener guiones bajos para ayudar con la lectura. Ningn tipo de formato afecta
el valor subyacente de la literal:
25
26
Debido a que ambos lados de la adicin son ahora de tipo UInt16 , se permite la
adicin. La constante de salida ( twoThousandAndOne ) se infiere a ser de
tipo UInt16 , porque es la suma de dos UINT16 valores.
SomeType (ofInitialValue) es la forma predeterminada para llamar al
inicializador de tipo Swift y pase un valor inicial. Detrs de las escenas, UInt16 tiene
un inicializador que acepta un Uint8 valor, y por lo que este inicializador se utiliza
para hacer un nuevo UInt16 de una existente Uint8 . No se puede pasar
en cualquiertipo aqu, sin embargo, tiene que ser un tipo para el
que UInt16 proporciona un inicializador. La extensin de los tipos existentes para
proporcionar inicializadores que acepten nuevos tipos (incluyendo sus propias
definiciones de tipos) que se cubre en las extensiones .
Entero y en coma flotante Conversin
Las conversiones entre nmeros enteros y de punto flotante tipos numricos deben
hacerse explcitas:
let three = 3
// MaxAmplitudeFound es ahora 0
Aqu, AudioSample se define como un alias para UInt16 . Debido a que es un alias,
la llamada aAudioSample.min llama en realidad UInt16.min , que proporciona
un valor inicial de 0 para el maxAmplitudeFoundvariable.
Booleanos
Swift tiene un bsico de Boole tipo, llamado Bool . Los valores booleanos se les
conoce como lgica , ya que slo alguna vez pueden ser verdaderas o falsas. Swift
proporciona dos valores constantes booleanas,verdaderas y falsas :
if turnipsAreDelicious {
} else {
let i = 1
if i {
}
Sin embargo, el ejemplo alternativo a continuacin es vlido:
let i = 1
if i == 1 {
}
El resultado de la i == 1 comparacin es de tipo Bool , y por lo que este segundo
ejemplo del tipo pasa-cheque. Las comparaciones como i == 1 se discuten
en Operadores bsicos .
28
Al igual que con otros ejemplos de tipo de seguridad en Swift, este enfoque evita
errores accidentales y asegura que la intencin de una seccin particular de cdigo es
siempre clara.
Las tuplas
Las tuplas grupo de valores mltiples en un nico valor compuesto. Los valores dentro
de una tupla pueden ser de cualquier tipo y no tienen que ser del mismo tipo que la otra.
En este ejemplo, (404, "Not Found") es una tupla que describe un cdigo de
estado HTTP . Un cdigo de estado HTTP es un valor especial retornado por un
servidor web cada vez que solicita una pgina web. Un cdigo de estado de 404 Not
Found se devuelve si usted solicita una pgina web que no existe.
29
30
serverResponseCode = nil
if convertedNumber != nil {
31
opcin sin duda tiene un valor; por favor use "Esto se conoce como.desenvolver
forzado del valor de la opcin:
if convertedNumber != nil {
statements
}
Puede volver a escribir la possibleNumber ejemplo del Opcionales seccin para
utilizar opcional desenvolver vinculante y no forzada:
} else {
32
if assumedString != nil {
println(assumedString)
}
33
println(definiteString)
let age = -3
34
35
Operadores bsicos
En esta pgina
Un operador es un smbolo especial o una frase que se utiliza para comprobar, cambiar
o combinar los valores. Por ejemplo, el operador de suma ( + ) suma dos nmeros juntos
(como en let i = 1 + 2 ). Ejemplos ms complejos incluyen el operador lgico
AND && (como en el caso de enteredDoorCode && passedRetinaScan)
y el operador de incremento ++ i , que es un acceso directo para aumentar el valor
de i por 1 .
Swift es compatible con los operadores de C ms estndar y mejora varias funciones
para eliminar los errores comunes de codificacin. El operador de asignacin ( = ) no
devuelve un valor, para evitar que sea utilizado por error cuando el operador igual a
( == ) se destina. Los operadores aritmticos ( + , - , * , / , % , etc) y no permiten
detectar desbordamiento valor, para evitar resultados inesperados cuando se trabaja con
los nmeros que se convierten en mayor o menor que el rango de valores permitido del
tipo que los almacena.Usted puede optar por el comportamiento de desbordamiento de
valor mediante el uso de operadores de desbordamiento de Swift, como se describe
en Operadores de desbordamiento .
A diferencia de C, Swift le permite realizar resto ( % ) clculos sobre nmeros de punto
flotante. Swift tambin proporciona dos operadores de rango ( un .. <b y a ...
b ) que no se encuentran en C, como un acceso directo para expresar un rango de
valores.
En este captulo se describen los operadores comunes en Swift. Operadores
avanzados cubre operadores avanzados de Swift, y describe cmo definir sus propios
operadores personalizados e implementar los operadores estndar para sus propios tipos
personalizados.
Terminologa
Los operadores son unarios, binarios o ternarios:
Unarios operadores operan en un solo objetivo (tales como :
una ). Unarios prefijo operadores aparecen inmediatamente antes de su destino
(como ! b ), y unarios postfix operadores aparecen inmediatamente despus de su
objetivo (tales como i ++ ).
Binarias operadores funcionan con dos objetivos (como 2 + 3 ) y
son infijo porque aparecen en entre sus dos objetivos.
Ternarios operadores operan en tres objetivos. Al igual que C, Swift tiene un solo
operador ternario, el operador condicional ternario ( a b: c ).
Los valores que afectan a los operadores estn operando . En la expresin 1 + 2 ,
la + smbolo es un operador binario y sus dos operandos son los valores 1 y 2 .
Operador de asignacin
El operador de asignacin ( a = b ) inicializa o actualiza el valor de una con el valor
de b :
let b = 10
var a = 5
a=b
// a is now equal to 10
36
Si el lado derecho de la asignacin es una tupla con mltiples valores, sus elementos se
pueden descomponer en varias constantes o variables a la vez:
if x = y {
}
Esta funcin evita que el operador de asignacin ( = ) se utilice por accidente cuando el
operador igual a ( == ) se destina en realidad. Al hacer si x = y no vlida, Swift le
ayuda a evitar este tipo de errores en el cdigo.
Operadores aritmticos
Swift es compatible con los cuatro estndares operadores aritmticos para todos los
tipos de nmeros:
Suma ( + )
Resta ( - )
Multiplicacin ( * )
Divisin ( / )
1 + 2 // equals 3
5 - 3 // equals 2
2 * 3 // equals 6
37
Puede
encajar
dos
4
s
interior
9
,
y
el
resto
es
1
(se
muestra
en
color
naranja).
En
Swift,
esto
se
escribe
como:
9 % 4 // equals 1
Para
determinar
la
respuesta
para
a% b
,
el
%
del
operador
calcula
la
siguiente
ecuacin
y
devuelve
restocomo
salida:
Los operadores de incremento y decremento
Al igual que C, Swift ofrece un operador de incremento ( ++ ) y un operador de
decremento ( - ) como un acceso directo para aumentar o disminuir el valor de una
variable numrica por 1 . Puede utilizar estos operadores con variables de cualquier
nmero entero o tipo de punto flotante.
38
var i = 0
var a = 0
let b = ++a
let c = a++
let three = 3
39
let minusSix = -6
var a = 1
a += 2
// a es ahora igual a 3
La expresin a + = 2 es la abreviatura de a = a + 2 . Efectivamente, la adicin y
la asignacin se combinan en un operador que realiza ambas tareas al mismo tiempo.
NOTA
Los operadores de asignacin compuestos no devuelven un valor. No se puede
escribir al B = a + = 2 , por ejemplo. Este comportamiento es diferente de los
operadores de incremento y decremento mencionados anteriormente.
Una lista completa de operadores de asignacin compuestos se puede encontrar en las
expresiones .
Operadores de comparacin
Swift es compatible con todos los C estndar operadores de comparacin :
Igual a ( a == b )
No es igual a ( a! = b )
Mayor que ( a> b )
Menos de ( a <b )
Mayor o igual a ( a> = b )
Menor o igual a ( a <= b )
NOTA
Swift tambin proporciona dos operadores de identidad ( === y ! == ), que se utiliza
para probar si dos referencias a objetos tanto se refieren a la misma instancia de
objeto. Para obtener ms informacin, veaClases y Estructuras .
Cada uno de los operadores de comparacin devuelve un Bool valor para indicar si la
declaracin es verdadera:
40
if name == "world" {
println("hello, world")
} else {
if question {
answer1
} else {
answer2
}
He aqu un ejemplo, que calcula la altura de una fila de tabla. La altura de la fila debe
ser de 50 puntos ms alto que la altura del contenido si la fila tiene una cabecera, y 20
puntos ms alto si la fila no tiene un encabezado:
dejar que contentHeight = 40
// RowHeight es igual a 90
El ejemplo anterior es una abreviatura para el cdigo de abajo:
let contentHeight = 40
if hasHeader {
rowHeight = rowHeight + 50
} else {
rowHeight = rowHeight + 20
}
41
// RowHeight es igual a 90
El primer uso del ejemplo del operador condicional ternario significa
que rowHeight se puede establecer en el valor correcto en una sola lnea de
cdigo. Esto es ms conciso que el segundo ejemplo, y elimina la necesidad
de rowHeight a una variable, porque su valor no necesita ser modificado dentro de
un sideclaracin.
El operador condicional ternario proporciona una taquigrafa eficiente para decidir cul
de las dos expresiones a considerar. Utilice el operador condicional ternario con
cuidado, sin embargo. Su concisin puede conducir al cdigo difcil de leer si se
abusa. Evite combinar varias instancias del operador condicional ternario en una
sentencia compuesta.
Ninguna Coalescente Operador
El operador de coalescencia nula ( a ?? b ) desenvuelve opcional un si contiene un
valor, o devuelve un valor predeterminado b si una es nula . La
expresin una siempre es de un tipo opcional. La expresin b debe coincidir con el tipo
que se almacena dentro de una .
El operador de coalescencia nil es un atajo para el cdigo de abajo:
a != nil ? a! : b
El cdigo anterior utiliza el operador condicional ternario y desenvolver forzada
( una! ) para acceder al valor envuelto en una cuando una no es nula , ya
regresar b lo contrario. El operador de coalescencia nil ofrece una forma ms elegante
para encapsular esta comprobacin condicional y desenvolver de una forma concisa y
fcil de leer.
NOTA
Si el valor de una es no nulo , el valor de b no se evala. Esto se conoce
como evaluacin de corto-circuito .
El ejemplo siguiente utiliza el operador de coalescencia nil que elegir entre un nombre
de color por defecto y un nombre de color definido por el usuario opcional:
42
userDefinedColorName = "green"
43
Operadores Range
Swift incluye dos operadores de rango , que son atajos para expresar un rango de
valores.
Cerrado operador Range
El operador de rango cerrado ( un ... b ) define un rango que va desde una a b , e
incluye los valores de una yb . El valor de un no debe ser mayor que b .
El operador de rango cerrado es til cuando se repite en un intervalo en el que desea que
todos los valores a utilizar, por ejemplo, con un para - en bucle:
// 1 times 5 is 5
// 2 times 5 is 10
// 3 times 5 is 15
// 4 times 5 is 20
// 5 times 5 is 25
Para ms informacin sobre por - en bucles, consulte Flujo de control .
La mitad-Open Operator Range
El operador entreabierta gama ( un .. <b ) define un rango que va desde una a b ,
pero no incluye b . Se dice que es la mitad-abierta , ya que contiene el primer valor,
pero no su valor final. Como con el operador de rango cerrado, el valor de un no debe
ser mayor que b .
Rangos medio abiertas son particularmente tiles cuando se trabaja con listas de cerobasado como matrices, en las que es til para contar hasta (pero sin incluir) la longitud
de la lista:
for i in 0..<count {
44
Operadores lgicos
Los operadores lgicos modificar o combinar los valores lgicos
booleanos true y false . Swift es compatible con los tres operadores lgicos
estndar que se encuentran en los idiomas basados en C:
Logical NOT (!a)
Logical AND (a && b)
Logical OR (a || b)
Logical NOT Operator
El operador lgico NOT ( ! a) invierte un valor booleano para que verdadera se
convierte en falsa , y falsase convierte en verdadera .
El operador lgico NOT es un operador prefijo, y aparece inmediatamente antes del
valor que opera en, sin ningn espacio en blanco. Se puede leer como "no una ", como
se ve en el siguiente ejemplo:
if !allowedEntry {
println("ACCESS DENIED")
println("Welcome!")
} else {
println("ACCESS DENIED")
45
Operador lgico OR
El operador lgico OR ( a || b ) es un operador infijo hecho a partir de dos
personajes de tuberas adyacentes. Se utiliza para crear expresiones lgicas en las que
slo uno de los dos valores tiene que serverdadera para la expresin general para
ser verdad .
Al igual que el operador lgico AND anterior, el operador lgico OR utiliza la
evaluacin de cortocircuito para considerar sus expresiones. Si el lado izquierdo de una
expresin lgica OR es verdadera , no se evala el lado derecho, porque no puede
cambiar el resultado de la expresin general.
En el siguiente ejemplo, la primera Bool valor ( hasDoorKey ) es falsa , pero el
segundo valor (knowsOverridePassword ) es verdadera . Debido a que un
valor es verdadero , la expresin general tambin se evala como verdadera , y
se permite el acceso:
if hasDoorKey || knowsOverridePassword {
println("Welcome!")
} else {
println("ACCESS DENIED")
// prints "Welcome!"
La combinacin de operadores lgicos
Puede combinar mltiples operadores lgicos para crear expresiones compuestas ms
largos:
println("Welcome!")
} else {
println("ACCESS DENIED")
// prints "Welcome!"
Este ejemplo utiliza mltiples && y || operadores para crear una expresin compuesta
por ms tiempo. Sin embargo, el && y || operadores siguen funcionando en slo dos
valores, por lo que este es en realidad tres expresiones ms pequeas encadenadas. El
ejemplo se puede leer como:
Si hemos entrado en el cdigo de la puerta correcta y pasamos el escner de la retina, o
si tenemos una llave de la puerta vlida, o si se conoce la contrasea de anulacin de
emergencia y permitir el acceso.
Basado en los valores de enteredDoorCode , passedRetinaScan ,
y hasDoorKey , los primeros dos mini-expresiones son falsas . Sin embargo, la
46
println("Welcome!")
} else {
println("ACCESS DENIED")
// prints "Welcome!"
Los parntesis, dejan claro que los dos primeros valores son considerados como parte de
un posible estado independiente en la lgica global. La salida de la expresin
compuesto no cambia, pero la intencin general es ms claro para el lector. La
legibilidad es siempre preferible a la brevedad; utilizar parntesis, donde ayudan a hacer
que sus intenciones claras.
Cuerdas y Personajes
Una cadena es una coleccin ordenada de caracteres, como "hola,
mundo" o "albatros" . Cuerdas Swift estn representados por la Cadena tipo, que
a su vez representa una coleccin de valores de caracteres de tipo.
De Swift de Cuerda y Carcter tipos proporcionan una manera rpida, compatible
con Unicode para trabajar con el texto en el cdigo. La sintaxis para la creacin de la
cadena y la manipulacin es ligero y fcil de leer, con una sintaxis literal de cadena que
es similar a C. concatenacin de cadenas es tan simple como la suma de dos cuerdas con
el + operador, y la mutabilidad cadena se gestiona mediante la eleccin entre una
constante o una variables, al igual que cualquier otro valor en Swift.
A pesar de esta simplicidad de la sintaxis, de Swift Cadena tipo es una aplicacin de
cadena rpida, moderna.Cada cadena se compone de caracteres Unicode
independientemente de la codificacin, y ofrece soporte para acceder a esos personajes
en diversas representaciones Unicode.
Tambin puede utilizar cadenas para insertar constantes, variables, literales y
expresiones en cadenas ms largas, en un proceso conocido como interpolacin de
cadenas. Esto hace que sea fcil crear valores de cadena personalizada para la
visualizacin, el almacenamiento y la impresin.
NOTA
De Swift Cadena tipo se tiende un puente a la perfeccin para la
Fundacin NSString clase. Si est trabajando con el marco de la Fundacin en Cocoa
o Cocoa Touch, todo el NSString API est disponible para llamar en
47
if emptyString.isEmpty {
48
println(character)
// D
// o
// g
// !
//
La for-in bucle se describe en los bucles for .
Como alternativa, crear una independiente de caracteres constante o variable de
una cadena de un solo carcter literal proporcionando un personaje anotacin de
tipo:
49
instruction += string2
welcome.append(exclamationMark)
let multiplier = 3
50
Unicode
Unicode es un estndar internacional para la codificacin, lo que representa, y
procesamiento de textos en diferentes sistemas de escritura. Se le permite representar
casi todos los caracteres de cualquier idioma en una forma estandarizada, y para leer y
escribir los caracteres ay desde una fuente externa, como un archivo de texto o una
pgina web. De Swift de Cuerda y Carcter tipos son totalmente compatible con
Unicode, como se describe en esta seccin.
Unicode escalares
Detrs de las escenas, nativo de Swift Cadena tipo se construye a partir de escalares
Unicode valores. Un escalar Unicode es un nmero de 21 bits nico para un personaje o
modificador, como U + 0061 paraMINSCULA A ( "a" ), o U + 1F425 para que
daba al frente POLLUELO DEL BEB ( " " ).
NOTA
Un escalar Unicode Unicode es cualquier punto de cdigo en el rango U + 0000 a U
+ D7FF incluido o U + E000 a U + 10FFFF inclusive. Escalares Unicode no
incluyen los Unicode par suplente puntos de cdigo, que son los puntos de cdigo en el
rango de U + D800 a U + DFFF inclusive.
Tenga en cuenta que no todos los escalares Unicode de 21 bits se asignan a un
personaje-algunos escalares estn reservados para la asignacin futura. Los escalares
que se han asignado a un carcter tpicamente tambin tienen un nombre,
como MINSCULA A y orientados hacia delante POLLUELO DEL
BEB en los ejemplos anteriores.
Caracteres Unicode especiales en literales de cadena
Los literales de cadena pueden incluir los siguientes caracteres especiales Unicode:
Los caracteres especiales escapados \ 0 (carcter nulo), \\ (barra invertida), \
t (tabulador horizontal),\ n (salto de lnea), \ r (retorno de carro), \ " (comillas
dobles) y \ ' (comilla simple )
Un escalar Unicode arbitraria, escrito como \ u { n } , donde n es entre uno y
ocho dgitos hexadecimales
El cdigo siguiente muestra cuatro ejemplos de estos caracteres
especiales. Los wisewords constantes contiene dos escaparon dos caracteres de
comillas. Los Dollarsign , Blackheart , y sparklingHeart constantes
demuestran el formato escalar Unicode:
51
// precomposed is , decomposed is
Racimos de grafema ampliada son una forma flexible para representar muchos
caracteres de alfabetos complejos como un solo personaje valor. Por ejemplo, las
slabas Hangul del alfabeto coreano se pueden representar como una secuencia
cualquiera precomposed o descompuesto. Ambas representaciones califican como un
solo personaje valor en Swift:
// precomposed is , decomposed is
// Precomposed es , descompuesto es
Racimos de grafema ampliada permiten escalares para encerrar marcas
(como COMBINAR adjuntando CIRCLE , o U + 20DD ) para encerrar otros
escalares Unicode como parte de una sola Carcter valor:
// enclosedEAcute is
Escalares Unicode para los smbolos indicadores regionales se pueden combinar en
parejas para hacer un solo personaje de valor, como esta combinacin
de REGIONAL INDICADOR SMBOLO LETRA U ( U + 1F1FA ) yREGIONAL
INDICADOR SMBOLO LETRA S ( U + 1F1F8 ):
// regionalIndicatorForUS is
Contando Personajes
Para recuperar un recuento de los caracteres en los valores de una cadena, llame al
mundial countElementsfuncin y pase una cadena como nico parmetro de la
funcin:
, Snail
, Penguin
, Dromedary
"
52
Por ejemplo, si inicializa una nueva cadena con la palabra de cuatro caracteres caf , y
luego aadir unaAGUDA ACCENT COMBINACIN ( U + 0301 ) al final de la
cadena, la cadena resultante va a tener un recuento de caracteres de 4 , con una cuarto
carcter de , no e :
if quotation == sameQuotation {
53
if eAcuteQuestion == combinedEAcuteQuestion {
if latinCapitalLetterA != cyrillicCapitalLetterA {
54
let romeoAndJuliet = [
]
Usted puede utilizar el hasPrefix mtodo con el romeoAndJuliet matriz para
contar el nmero de escenas en el acto 1 de la obra:
var act1SceneCount = 0
if scene.hasPrefix("Act 1 ") {
++act1SceneCount
var mansionCount = 0
var cellCount = 0
if scene.hasSuffix("Capulet's mansion") {
++mansionCount
++cellCount
55
print("\(codeUnit) ")
print("\n")
56
print("\(codeUnit) ")
print("\n")
print("\(scalar.value) ")
print("\n")
57
println("\(scalar) ")
// D
// o
// g
//
//
Tipos Collection
Swift proporciona dos tipos de coleccin , conocidas como matrices y diccionarios, para
almacenar colecciones de valores. Matrices tienda orden listas de valores del mismo
tipo. Diccionarios almacenar colecciones no ordenadas de valores del mismo tipo, que
puede ser referenciado y mir hacia arriba a travs de un identificador nico (tambin
conocido como una clave).
Arrays y diccionarios en Swift son siempre claras sobre los tipos de valores y claves que
pueden almacenar.Esto significa que no se puede insertar un valor de tipo incorrecto en
una matriz o diccionario por error.Tambin significa que usted puede estar seguro
acerca de los tipos de valores que va a recuperar de una matriz o diccionario. Uso de
Swift de colecciones escritas explcitamente garantiza que el cdigo es siempre claro
acerca de los tipos de valores que puede trabajar y le permite capturar cualquier tipo de
desajustes en el desarrollo temprano de su cdigo.
NOTA
Detrs de las escenas, la matriz y Diccionario tipos de Swift se implementan
como colecciones genricas .Para ms informacin sobre los tipos genricos y
colecciones, vea Genricos .
La mutabilidad de las Colecciones
Si crea una matriz o un diccionario y la asigna a una variable, la coleccin que se crea
ser mutable . Esto significa que usted puede cambiar (o mutar ) la coleccin despus
de que se crea al agregar, eliminar o cambiar elementos de la coleccin. Por el contrario,
si se asigna una matriz o un diccionario a una constante, esa matriz o diccionario
es inmutable , y su tamao y contenido no se pueden cambiar.
NOTA
Es una buena prctica para crear colecciones inmutables en todos los casos en que la
coleccin no necesita cambiar. Si lo hace, le permite al compilador Swift para optimizar
el rendimiento de las colecciones que se crean.
58
Arrays
Un array almacena varios valores del mismo tipo en una lista ordenada. El mismo valor
puede aparecer en una matriz varias veces en diferentes posiciones.
Arrays Swift son especficas sobre los tipos de valores que pueden almacenar. Se
diferencian de Objective-C de NSArray y NSMutableArray clases, que pueden
almacenar cualquier tipo de objeto y no proporcionan ninguna informacin sobre la
naturaleza de los objetos que regresan. En Swift, el tipo de valores que una matriz
particular puede almacenar siempre est claro, ya sea a travs de un tipo de anotacin
explcita, o por medio de la inferencia de tipos, y no tiene que ser un tipo de clase. Si se
crea una matriz de Int valores, por ejemplo, no se puede insertar cualquier valor que
no sea Int valores en la matriz. Arrays Swift son de tipo seguro, y siempre estn claros
acerca de lo que pueden contener.
Tipo de matriz Taquigrafa Sintaxis
El tipo de una matriz Swift est escrito en su totalidad como matriz <SomeType> ,
donde SomeType es el tipo que se permite que el conjunto de almacenar. Tambin
puede escribir el tipo de una matriz en forma abreviada como [SomeType] . Aunque
las dos formas son funcionalmente idnticos, se prefiere la forma abreviada, y se utiliza
en toda esta gua para referirse al tipo de una matriz.
Arreglos Literales
Puede inicializar una matriz con un literal de matriz , que es una forma abreviada de
escribir uno o ms valores como una coleccin de matriz. Un literal de matriz se escribe
como una lista de valores separados por comas, rodeado de un par de corchetes:
59
if shoppingList.isEmpty {
} else {
shoppingList.append("Flour")
// shoppingList now contains 3 items, and someone is making pancakes
Alternativamente, agregue un conjunto de uno o ms elementos compatibles con el
operador de asignacin de suma ( + = ):
60
firstItem = ShoppingList [ 0 ]
61
Interactuando sobre una matriz
Puede iterar sobre todo el conjunto de valores en una matriz con el de - en bucle:
println(item)
// Six eggs
// Milk
// Flour
// Baking Powder
// Bananas
Si usted necesita el ndice entero de cada elemento, as como su valor, utilice el
mundial enumerate funcin para repetir la matriz en
lugar. La enumeracin funcin devuelve una tupla para cada elemento del conjunto
formado por el ndice y el valor de ese elemento. Puede descomponerse en la tupla
constantes o variables temporales como parte de la iteracin:
// Item 2: Milk
// Item 3: Flour
// Item 5: Bananas
Para ms informacin sobre la para - en bucle, consulte Para Loops .
Creacin e inicializacin de una matriz
Puede crear una matriz vaca de un cierto tipo (sin establecer valores iniciales),
utilizando la sintaxis de inicializador:
62
someInts.append(3)
someInts = []
// sixDoubles is inferred as [Double], and equals [0.0, 0.0, 0.0, 2.5, 2.5, 2.5]
Diccionarios
Un diccionario es un contenedor que almacena varios valores del mismo tipo. Cada
valor se asocia con una nica tecla , que acta como un identificador para ese valor
dentro del diccionario. A diferencia de los elementos de un array, los elementos de un
diccionario no tienen un orden especfico. Se utiliza un diccionario cuando necesita
buscar valores en funcin de su identificador, casi de la misma manera que un
diccionario en el mundo real se utiliza para buscar la definicin de una palabra en
particular.
NOTA
63
Diccionarios Swift son especficas sobre los tipos de claves y valores que pueden
almacenar. Se diferencian de Objective-C
de NSDictionary y NSMutableDictionary clases, que pueden usar cualquier
tipo de objeto como sus claves y valores y no proporcionan ninguna informacin sobre
la naturaleza de esos objetos. En Swift, el tipo de claves y valores que un diccionario
particular puede almacenar siempre se pone de manifiesto, ya sea a travs de un tipo de
anotacin explcita oa travs de la inferencia de tipos.
Diccionario Tipo Taquigrafa Sintaxis
El tipo de un diccionario Swift est escrito en su totalidad como Dictionary
<KeyType, ValueType> , dondeKeyType es el tipo de valor que puede ser
utilizado como una clave de diccionario, y ValueType es el tipo de valor que las
tiendas Diccionario para esas llaves.
Tambin puede escribir el tipo de un diccionario en forma abreviada
como [KeyType: ValueType] . Aunque las dos formas son funcionalmente
idnticos, se prefiere la forma abreviada, y se utiliza en toda esta gua para referirse al
tipo de un diccionario.
Los literales Diccionario
Puede inicializar un diccionario con un diccionario literal , que tiene una sintaxis
similar a la matriz literal visto antes. Un literal diccionario es una forma abreviada de
escribir uno o ms pares clave-valor como unDiccionario coleccin.
Un par clave-valor es una combinacin de una clave y un valor. En un literal
diccionario, la clave y el valor de cada par clave-valor estn separados por dos
puntos. Los pares clave-valor se escriben como una lista, separada por comas, rodeado
de un par de corchetes:
El siguiente ejemplo crea un diccionario para almacenar los nombres de los aeropuertos
internacionales. En este diccionario, las claves son cdigos de tres letras de la
Asociacin Internacional de Transporte Areo, y los valores son los nombres de
aeropuertos:
64
diccionario con slo Cuerda llaves, y slo de Cuerda valores), por lo que la
asignacin del diccionario literal se permite como una manera de inicializar
los aeropuertos diccionario con dos artculos iniciales.
Al igual que con las matrices, usted no tiene que escribir el tipo del diccionario si ests
inicializar con un literal diccionario cuyas claves y valores tienen tipos coherente. La
inicializacin de los aeropuertos podra haber sido ser escrito en una forma ms
corta en su lugar:
if airports.isEmpty {
} else {
airports["LHR"] = "London"
65
devuelve el viejo valor despus de realizar una actualizacin. Esto le permite comprobar
si una actualizacin se llev a cabo.
El UpdateValue (forKey :) mtodo devuelve un valor opcional de valor tipo
del diccionario. Para un diccionario que almacena Cuerda valores, por ejemplo, el
mtodo devuelve un valor de tipo de cadena? , o "opcional Cadena". Este valor
opcional contiene el valor antiguo para esa clave, si es que exista antes de la
actualizacin, onil si exista ningn valor:
} else {
airports["APL"] = nil
} else {
}
66
println("\(airportCode): \(airportName)")
// TYO: Tokyo
Para ms informacin sobre la para - en bucle, consulte Para Loops .
Tambin puede recuperar una coleccin iterable de claves o valores de un diccionario
mediante el acceso a sus claves y valores propiedades:
println("\(airportCode): \(airportName)")
// TYO: Tokyo
For more about the for-in loop, see For Loops.
You can also retrieve an iterable collection of a dictionarys keys or values by accessing
its keys and valuesproperties:
67
namesOfIntegers [ 16 ] = "diecisis"
namesOfIntegers = [:]
68
// 1 times 5 is 5
// 2 times 5 is 10
// 3 times 5 is 15
// 4 times 5 is 20
// 5 times 5 is 25
La coleccin de artculos que se iterado es una gama cerrado de nmeros
de 1 a 5 inclusive, como se indica por el uso del operador de rango cerrado ( ... ). El
69
let base = 3
let power = 10
var answer = 1
for _ in 1...power {
answer *= base
println("Hello, \(name)!")
// Hello, Anna!
// Hello, Alex!
// Hello, Brian!
// Hello, Jack!
70
Tambin puede iterar sobre un diccionario para acceder a sus pares clave-valor. Cada
elemento en el diccionario se devuelve como un (clave, valor) tupla cuando se
itera el diccionario, y se puede descomponer el (valor llave) los miembros de la
tupla como constantes nombradas explcitamente para su uso dentro del cuerpo de
la para - en bucle. Aqu, las claves del diccionario se descomponen en una constante
llamadaanimalName , y los valores del diccionario se descomponen en una constante
llamada legCount :
println(character)
// H
// e
// l
// l
// o
For
Adems de para - en bucles, Swift apoya al estilo de C tradicional para bucles con
una condicin y un incrementador:
println("index is \(index)")
// index is 0
// index is 1
// index is 2
Heres the general form of this loop format:
71
statements
}
Los puntos y comas separan las tres partes de la definicin del bucle, como en C. Sin
embargo, a diferencia de C, Swift no necesita parntesis alrededor de toda la
inicializacin "; condicin; bloque de incremento ".
El bucle se ejecuta de la siguiente manera:
1. La primera vez que se entra en el bucle, la expresin de inicializacin se evala una
vez, para establecer cualquier constante o variables que se necesitan para el bucle.
2. La expresin de condicin es evaluada. Si se evala como falsa , el bucle termina,
y la ejecucin de cdigo contina despus de la de llave de cierre del bucle ( } ). Si
la expresin se evala comoverdadera , la ejecucin de cdigo contina
ejecutando las sentencias entre llaves.
3. Despus se ejecutan todas las declaraciones, la expresin de incremento se
evala. Puede aumentar o disminuir el valor de un contador, o establecer una de las
variables inicializadas a un nuevo valor basado en el resultado de las
declaraciones. Despus de la expresin de incremento ha sido evaluado, la ejecucin
vuelve al paso 2, y la expresin de condicin se evala otra vez.
El proceso de formato de bucle y la ejecucin descrita anteriormente es la abreviatura de
(y equivalente a) el siguiente esquema:
initialization
while condition {
statements
increment
}
Constantes y variables declaradas dentro de la expresin de inicializacin
(como ndice var = 0 ) slo son vlidos en el mbito de la de bucle en s. Para
recuperar el valor final del ndice despus de los extremos de bucle, debe declarar el
ndice antes de que comience el alcance del bucle:
println("index is \(index)")
// index is 0
// index is 1
// index is 2
72
While (Mientras)
Un while de bucle comienza evaluando un solo estado. Si la condicin
es verdadera , un conjunto de estados se repite hasta que la condicin se convierte
en falsa .
Aqu est la forma general de un while bucle:
while condition {
statements
73
Las reglas del juego son las siguientes:
El tablero tiene 25 cuadrados, y el objetivo es aterrizar en o ms all de la plaza 25.
Cada turno, tirar un dado de seis caras y jugada de ese nmero de plazas, siguiendo
el camino horizontal que indica la flecha punteada arriba.
Si su turno termina en la parte inferior de una escalera, que se asciende por la
escalera.
Si su turno termina a la cabeza de una serpiente, se mueve hacia abajo esa serpiente.
El tablero de juego est representado por una serie de Int valores. Su tamao se basa
en una constante llamada finalSquare , que se utiliza para inicializar la matriz y
tambin para comprobar si hay una condicin de victoria ms adelante en el ejemplo. La
junta se inicializa con cero 26 Int valores, no 25 (uno por cada uno en los ndices
de 0 a travs de 25 inclusive):
let finalSquare = 25
74
var square = 0
var diceRoll = 0
if ++diceRoll == 7 { diceRoll = 1 }
square += diceRoll
square += board[square]
println("Game over!")
En este ejemplo se utiliza un enfoque muy simple para tirar los dados. En lugar de un
generador de nmeros aleatorios, que comienza con un diceRoll valor de 0 . Cada
vez que a travs del tiempo de bucle, diceRoll se incrementa con el operador de
incremento prefijo ( ++ i ), y luego se comprueba para ver si se ha hecho demasiado
grande. El valor de retorno de ++ diceRoll es igual al valor de diceRoll despus
de que se incrementa. Cada vez que este valor de retorno es igual a 7 , la tirada se ha
vuelto demasiado grande, y se pone a un valor de 1 . Esto da una secuencia
de diceRoll valores que siempre es 1 , 2 , 3 , 4 , 5 , 6 , 1 , 2 y as sucesivamente.
Despus de tirar los dados, el jugador avanza por diceRoll cuadrados. Es posible que
la tirada de dados pudo haber movido el jugador ms all de la plaza 25, en cuyo caso el
juego ha terminado. Para hacer frente a este escenario, el cdigo comprueba que la
plaza es menor que el consejo de gama recuento propiedad antes de aadir el
valor almacenado en cartn [cuadrados] en la actual plaza de valor para
mover el jugador hacia arriba o hacia abajo las escaleras o las serpientes.
Si este cheque no se ha realizado, a bordo [cuadrado] podran tratar de acceder a
un valor fuera de los lmites de la placa de matriz, que daran lugar a un
error. Si cuadrado es ahora igual a 26 , el cdigo sera tratar de comprobar el valor
de la tabla de [26] , que es ms grande que el tamao de la matriz.
La corriente mientras que la ejecucin del bucle finaliza entonces, y la condicin
del bucle se comprueba para ver si el bucle debe ejecutarse de nuevo. Si el jugador ha
movido en o ms all de la plaza nmero 25 , la condicin del bucle se evala
como falsa , y el juego termina.
Un mientras bucle es apropiado en este caso porque la longitud del juego no est
claro en el comienzo de lamientras bucle. En cambio, el bucle se ejecuta hasta que
una condicin particular es satisfecho.
Do-While
La otra variacin de la while bucle, conocido como el do while bucle, realiza
una sola pasada a travs del bloque de bucle primero, antes de considerar la condicin
del bucle. A continuacin, sigue repitiendo el bucle hasta que la condicin es falsa .
75
statements
} while condition
Aqu est el juego de la oca ejemplo de nuevo, escrito como un do - mientras bucle
en lugar de una , mientras que bucle. Los valores
de finalSquare , tablero , cuadrados , y diceRoll se inicializan
exactamente de la misma manera que con un tiempo de bucle:
let finalSquare = 25
var square = 0
var diceRoll = 0
En esta versin del juego, la primera accin en el circuito es para comprobar si hay una
escalera o una serpiente. No Escalera en el tablero lleva al jugador directamente a la
plaza 25, por lo que no es posible ganar el juego al subir una escalera. Por lo tanto, es
seguro para comprobar si hay una serpiente o una escalera como la primera accin en el
circuito.
Al comienzo del juego, el jugador est en "cero plaza". tablero [0] siempre es
igual 0 , y no tiene efecto:
do {
square += board[square]
if ++diceRoll == 7 { diceRoll = 1 }
square += diceRoll
println("Game over!")
Despus de los controles de cdigo para serpientes y escaleras, los dados se rueda, y el
jugador se mueve hacia adelante por diceRoll cuadrados. La ejecucin del bucle de
corriente luego termina.
La condicin del bucle ( mientras cuadrado <finalSquare ) es el mismo que
antes, pero esta vez no se evala hasta que el final de la primera pasada por el bucle. La
estructura de la do - mientras bucle se adapta mejor a este juego que el tiempo de
bucle en el ejemplo anterior. En el do while bucle de arriba, cuadrado + =
bordo [cuadrado] siempre se ejecuta inmediatamente despus del bucle while
la condicin confirma que la plaza est todava en el tablero. Este comportamiento
76
var temperatureInFahrenheit = 30
if temperatureInFahrenheit <= 32
temperatureInFahrenheit = 40
if temperatureInFahrenheit <= 32 {
} else {
77
temperatureInFahrenheit = 90
if temperatureInFahrenheit <= 32 {
} else {
temperatureInFahrenheit = 72
if temperatureInFahrenheit <= 32 {
}
En este ejemplo, la temperatura no es ni demasiado fro ni demasiado caliente para
activar el si o ms si las condiciones, y as se imprime ningn mensaje.
Switch
Un switch declaracin considera un valor y lo compara contra varios patrones
coincidentes posibles.A continuacin, se ejecuta un bloque de cdigo apropiado, basado
en el primer patrn que coincida con xito.Un switch declaracin proporciona una
alternativa a la if la declaracin para responder a mltiples estados posibles.
En su forma ms simple, un switch declaracin compara un valor con uno o ms
valores del mismo tipo:
case value 1 :
respond to value 1
case value 2 ,
78
value 3 :
respond to value 2 or 3
default:
}
Cada switch de declaracin consiste en mltiples posibles casos , cada uno de los
cuales comienza con el caso de palabras clave. Adems de comparar con los valores
especficos, Swift ofrece varias maneras para cada caso para especificar patrones
coincidentes ms complejos. Estas opciones se describen ms adelante en esta seccin.
El cuerpo de cada interruptor de caso es una rama separada de la ejecucin de
cdigo, de manera similar a las ramas de un si declaracin. El interruptor de la
declaracin determina qu rama debe ser seleccionado.Esto se conoce
como conmutacin en el valor que se est considerando.
Cada switch de declaracin debe ser exhaustiva . Es decir, cada valor posible del
tipo que se est considerado debe ser igualada por uno de los de
conmutacin casos. Si no es apropiado para proporcionar un switch de caso para
cada valor posible, se puede definir un cajn de sastre caso por defecto para cubrir
cualquier valor que no se tratan de forma explcita. Este cajn de sastre caso se indica
con la palabra clavepor defecto , y debe aparecer siempre pasado.
En este ejemplo se utiliza un interruptor declaracin a considerar un nico carcter
en minscula llamadasomeCharacter :
switch someCharacter {
println("\(someCharacter) is a vowel")
case "b", "c", "d", "f", "g", "h", "j", "k", "l", "m",
"n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z":
println("\(someCharacter) is a consonant")
default:
79
No fallthrough Implcito
En contraste con el switch de declaraciones en C y Objective-C, switch
declaraciones en Swift no se pierdan en el fondo de cada caso y en la siguiente de forma
predeterminada. En lugar de ello, todo elconmutador de declaracin termina su
ejecucin tan pronto como la primera coincidencia interruptor se completa caso,
sin requerir una explcita break comunicado. Esto hace que el interruptor de la
declaracin ms seguro y ms fcil de usar que en C, y evita la ejecucin de ms de
un interruptor de caso por error.
NOTA
Aunque ruptura no se requiere en Swift, todava se puede utilizar
un descanso para que coincida con la declaracin y pasar por alto un caso particular,
o para salir de un caso emparejado antes de que el caso ha terminado su
ejecucin. Ver Rotura en una sentencia switch para ms detalles.
El cuerpo de cada caso debe contener al menos una sentencia ejecutable. No es vlido
para escribir el siguiente cdigo, debido a que el primer caso est vaca:
switch anotherCharacter {
case "a":
case "A":
default:
case value 1 ,
value 2 :
statements
}
NOTA
Para optar por fallthrough comportamiento para un determinado conmutador caso,
utilice el fallthrough palabra clave, como se describe en fallthrough .
80
GAMA A JUEGO
Los valores en los switch de los casos se puede comprobar por su inclusin en un
rango. Este ejemplo utiliza rangos de nmeros para proporcionar un recuento de
lenguaje natural para los nmeros de cualquier tamao:
switch count {
case 0:
naturalCount = "no"
case 1...3:
case 4...9:
naturalCount = "several"
case 10...99:
case 100...999:
case 1000...999_999:
default:
switch somePoint {
default:
El switch de declaracin determina si el punto est en el origen (0, 0); en el eje x de
color rojo; en el eje y naranja; dentro de la caja azul de 4 por 4 centrada en el origen; o
fuera de la caja.
A diferencia de C, Swift permite mltiples switch casos a considerar el mismo valor
o valores. De hecho, el punto (0, 0) pudo igualar todos cuatro de los casos en este
ejemplo. Sin embargo, si varias coincidencias son posibles, se utiliza siempre el primer
caso a juego. El punto (0, 0) se correspondera con case (0, 0) en primer lugar, y
as todos los dems casos coincidentes sera ignorado.
Vinculaciones Valor
Un switch de caso puede unir el valor o valores de que coincide con constantes o
variables temporales, para su uso en el cuerpo de la caja. Esto se conoce como valor de
unin , ya que los valores son "unido" a las constantes temporales o variables dentro del
cuerpo de la caja.
El siguiente ejemplo toma una (x, y) punto, expresado como una tupla de tipo (Int,
Int) y lo clasifica en el grfico que sigue:
switch anotherPoint {
82
El switch de declaracin determina si el punto est en el eje x de color rojo, en el eje
y naranja, o en otra parte, en ninguno de eje.
Los tres switch casos declaran de marcador de posicin constantes x e y , que toman
forma temporal en los valores de una o ambas tuplas de otroPunto . El primer
caso, caso (sea x, 0) , coincide con cualquier punto con una y el valor de 0 y
asigna del punto x valor de la constante temporal x . Del mismo modo, el segundo
caso, el caso (0, dejar y) , coincide con cualquier punto con una x valor
de 0 y asigna del punto yvalor de la constante temporal y .
Una vez que las constantes temporales se declaran, pueden ser utilizados dentro de
bloque de cdigo de la carcasa. Aqu, se utilizan como abreviatura para la impresin de
los valores con el println funcin.
Tenga en cuenta que este switch de declaracin no tiene un valor
predeterminado caso. El ltimo caso,let caso (x, y) , declara una tupla de
dos constantes de marcador de posicin que pueden coincidir con cualquier valor. Como
resultado de ello, de que coincide con todos los posibles valores restantes, y
undefecto no es necesario para hacer que el caso del switch declaracin
exhaustiva.
En el ejemplo anterior, x y y son declarados como constantes con el let palabra clave,
porque no hay necesidad de modificar sus valores dentro del cuerpo de la caja. Sin
embargo, podran haber sido declaradas como variables en su lugar, con la var palabra
clave. Si esto se hubiera hecho, se habra creado una variable temporal e inicializado
83
con el valor apropiado. Cualquier cambio en esa variable slo tendran un efecto en el
cuerpo de la caja.
Where
Un interruptor de caso puede utilizar una donde clusula para evaluar
afecciones adicionales.
El ejemplo siguiente cataloga un punto en el siguiente grfico (x, y):
switch yetAnotherPoint {
El switch de la declaracin determina si el punto est en la lnea diagonal verde
donde x == y , en la lnea diagonal prpura donde x == -y , o ninguno.
Los tres switch casos declaran de marcador de posicin constantes x e y , que toman
forma temporal en los dos valores de tupla de yetAnotherPoint . Estas constantes
se utilizan como parte de un donde clusula, para crear un filtro dinmico. El siwtch
de caso coincide con el valor actual del punto slo si el que la condicin de la
clusula se evala como verdadera para ese valor.
Como en el ejemplo anterior, el ltimo caso coincide con todos los posibles valores
restantes, y por lo que undefecto no es necesario para hacer que el caso del
interruptor declaracin exhaustiva.
84
switch character {
continue
default:
puzzleOutput.append(character)
println(puzzleOutput)
// prints "grtmndsthnklk"
El cdigo anterior llama al continue palabra clave cada vez que coincide con una
vocal o un espacio, provocando la iteracin actual del bucle a fin de inmediato y para
saltar directamente a la comienzo de la siguiente iteracin. Este comportamiento
permite que el bloque de interruptores para que coincida (e ignorar) slo los caracteres
de vocales y espaciales, en lugar de exigir el bloque para que coincida con cada
personaje que debe quedar impreso.
Break
La break declaracin finaliza la ejecucin de todo un estado de flujo de control
inmediatamente. La break declaracin se puede utilizar dentro de un switch o una
85
switch numberSymbol {
possibleIntegerValue = 1
possibleIntegerValue = 2
possibleIntegerValue = 3
possibleIntegerValue = 4
default:
86
break
} else {
let integerToDescribe = 5
switch integerToDescribe {
87
fallthrough
default:
println(description)
Declaraciones Etiquetada
Puede anidar bucles y cambiar estados dentro de otros bucles y cambiar estados en
Swift para crear estructuras de flujo de control complejos. Sin embargo, los lazos
y cambiar los estados pueden utilizar tanto laruptura declaracin al finalizar su
ejecucin antes de tiempo. Por lo tanto, a veces es til para ser explcito acerca de qu
lazo o interruptor declaracin quieres un descanso declaracin para
terminar. Del mismo modo, si usted tiene mltiples bucles anidados, puede ser til para
ser explcito acerca de lo que el buclecontinuar declaracin debera afectar.
Para alcanzar estos objetivos, puede marcar una sentencia de bucle
o cambiar declaracin con una etiqueta de declaracin , y el uso de esta etiqueta con
la ruptura declaracin o continuar declaracin para terminar o continuar la
ejecucin de la sentencia etiquetada.
88
statements
}
El ejemplo siguiente utiliza la ruptura y seguir las declaraciones con la
etiqueta mientras bucle de una versin adaptada de la Serpientes y Escaleras juego
que vimos anteriormente en este captulo. Esta vez, el juego tiene una regla adicional:
Para ganar, debes aterrizar exactamente en la plaza 25.
Si una tirada de dados particular, le tomara ms all de la plaza 25, debe tirar de nuevo
hasta que sacas el nmero exacto necesario para aterrizar en la plaza 25.
El tablero de juego es el mismo que antes:
Los valores de finalSquare , tablero , cuadrados , y diceRoll se
inicializan en la misma forma que antes:
let finalSquare = 25
var square = 0
var diceRoll = 0
Esta versin del juego utiliza un tiempo de bucle y un interruptor
de declaracin para implementar la lgica del juego. El tiempo de bucle tiene una
etiqueta llamada declaracin gameLoop , para indicar que es el bucle principal del
juego para el juego de Serpientes y Escaleras.
89
if ++diceRoll == 7 { diceRoll = 1 }
case finalSquare:
break gameLoop
continue gameLoop
default:
square += diceRoll
square += board[square]
println("Game over!")
Los dados se enrolla en el inicio de cada bucle. En lugar de mover el reproductor
inmediatamente, uninterruptor de sentencia se utiliza para tener en cuenta el
resultado de la medida, y para trabajar si se permite que el movimiento:
Si la tirada de dados se mover el jugador a la plaza final, el juego ha
terminado. Las vacaciones de gameLoop transferencias sentencia de control
a la primera lnea de cdigo fuera del tiempo de bucle, que termina el juego.
Si la tirada de dados se mover el jugador ms all de la plaza final, el movimiento
no es vlida, y el jugador tiene que tirar de nuevo. El continuar
gameLoop declaracin termina la actual , mientras que la iteracin de bucle
y comienza la siguiente iteracin del bucle.
En todos los dems casos, la tirada es un movimiento vlido. El jugador se mueve
hacia adelante pordiceRoll cuadrados y los controles de juego de lgica para
cualquier juego de la oca. El bucle se termina y el control vuelve al mismo
tiempo condicin para decidir si se requiere otro turno.
NOTA
Si la break afirmacin anterior no utiliz el gameLoop etiqueta, sera romper con
el interruptor de la declaracin, no el tiempo comunicado. Usando
el gameLoop etiqueta deja claro que controlar declaracin debe ser terminado.
Tenga en cuenta tambin que no es estrictamente necesario utilizar
el gameLoop etiqueta cuando llame acontinuar gameLoop para saltar a la
siguiente iteracin del bucle. Slo hay un bucle en el juego, y lo que no hay ambigedad
en cuanto a que el bucle continan declaracin afectar. Sin embargo, no hay ningn
dao en el uso de la gameLoop etiqueta con el continuar comunicado. Si lo hace,
90
return greeting
}
Toda esta informacin se rueda para arriba en funcin de la definicin , que se prefija
con la func palabra clave. Usted indica el tipo de la funcin de retorno con la flecha de
91
retorno -> (un guin seguido de un soporte en ngulo recto), que es seguido por el
nombre del tipo de volver.
La definicin describe lo que hace la funcin, lo que espera recibir, y lo devuelve
cuando se hace. La definicin hace que sea fcil para la funcin a ser llamada sin
ambigedades de su cdigo en otros lugares:
println(sayHello("Anna"))
println(sayHello("Brian"))
println(sayHelloAgain("Anna"))
92
println(halfOpenRangeLength(1, 10))
// prints "9"
println(sayHelloWorld())
println("Goodbye, \(personName)!")
sayGoodbye("Dave")
println(stringToPrint)
return countElements(stringToPrint)
printAndCount(stringToPrint)
printAndCount("hello, world")
printWithoutCounting("hello, world")
currentMin = value
currentMax = value
}
El MinMax funcin devuelve una tupla que contiene dos Int valores. Estos valores
estn etiquetados min y maxpara que puedan ser accedidos por su nombre cuando se
consulta el valor devuelto por la funcin.
El cuerpo de la MinMax funcin inicia estableciendo dos variables de trabajo
llamados currentMin y currentMaxal valor del primer nmero entero de la
matriz. La funcin entonces itera sobre los valores restantes de la matriz y comprueba
cada valor para ver si es menor o mayor que los valores
94
currentMin = value
currentMax = value
95
}
Sin embargo, estos nombres de parmetros slo se utilizan dentro del cuerpo de la
funcin de s mismo, y no se pueden utilizar cuando se llama a la funcin. Este tipo de
nombres de los parmetros se conocen comonombres de parmetros locales , ya que
slo estn disponibles para su uso dentro del cuerpo de la funcin.
Nombres de parmetros externos
A veces es til para nombrar cada parmetro cuando se llama a una funcin, para
indicar el propsito de cada argumento se pasa a la funcin.
Si desea que los usuarios de su funcin de proporcionar los nombres de parmetros que
llama a su funcin, definir un nombre de parmetro externo para cada parmetro,
adems del nombre del parmetro local. Usted escribe un nombre de parmetro externo
antes del nombre de parmetro local que da soporte, separadas por un espacio:
}
NOTA
Si proporciona un nombre de parmetro externo para un parmetro, el nombre externo
debe siempre ser utilizada cuando se llama a la funcin.
Como ejemplo, considere la siguiente funcin, que se une a dos cadenas mediante la
insercin de un tercer "carpintero" cuerda entre ellos:
return s1 + joiner + s2
}
Cuando se llama a esta funcin, el propsito de las tres cadenas que se pasa a la funcin
es clara:
96
func join(string s1: String, toString s2: String, withJoiner joiner: String)
-> String {
return s1 + joiner + s2
}
In En esta versin de la join a la funcin, el primer parmetro tiene un nombre
externo de cadena y un nombre local de s1 ; el segundo parmetro tiene un nombre
externo de toString y un nombre local de s2 ; y el tercer parmetro tiene un nombre
externo de withJoiner y un nombre local de joiner.
Ahora puede utilizar estos nombres de parmetros externos para llamar a la funcin sin
ambigedades:
if character == characterToFind {
return true
return false
97
return s1 + joiner + s2
}
Si un valor de cadena para el carpintero se proporciona cuando el unirse a la
funcin se llama, que valor de cadena se utiliza para unir las dos cadenas juntas, como
antes:
// returns "hello-world"
Sin embargo, si no hay ningn valor de carpintero se proporciona cuando se invoca
la funcin, el valor por defecto de un nico espacio ( "" ) se utiliza en su lugar:
98
func join(s1: String, s2: String, joiner: String = " ") -> String {
return s1 + joiner + s2
}
En este caso, Swift proporciona automticamente un nombre de parmetro externo para
el carpinteroparmetro. Por tanto, el nombre externo se debe proporcionar al llamar
a la funcin, por lo que el propsito del parmetro claro e inequvoco:
// returns "hello-world"
NOTA
Usted puede optar por salir de este comportamiento escribiendo un guin bajo ( _ ) en
lugar de un nombre externo explcito al definir el parmetro. Sin embargo, se prefieren
los nombres externos para parmetros con valores por defecto.
Parmetros variadic
Un parmetro variadic acepta cero o ms valores de un tipo especificado. Se utiliza un
parmetro variadic para especificar que el parmetro se puede pasar un nmero variable
de valores de entrada cuando se llama la funcin. Escribir parmetros variadic
insertando tres personajes de poca ( ... ) despus del nombre de tipo de parmetro.
Los valores que se pasan a un parmetro variadic se ponen a disposicin en el cuerpo de
la funcin como una matriz del tipo apropiado. Por ejemplo, un parmetro variadic con
un nombre de nmeros y un tipo dedoble ... se pone a disposicin dentro del
cuerpo de la funcin como una matriz constante llama nmeros de tipo [Doble] .
El siguiente ejemplo calcula la media aritmtica (tambin conocida como la media )
para obtener una lista de nmeros de cualquier longitud:
total += number
arithmeticMean(1, 2, 3, 4, 5)
99
Si su funcin tiene uno o ms parmetros con un valor por defecto, y tambin tiene un
parmetro variadic, coloque el parmetro variadic despus de todos los parmetros en
mora al final de la lista.
Parmetros Constante y Variable
Parmetros de la funcin son constantes por defecto. Tratar de cambiar el valor de un
parmetro de la funcin desde dentro del cuerpo de que los resultados de la funcin en
un error en tiempo de compilacin.Esto significa que usted no puede cambiar el valor de
un parmetro por error.
Sin embargo, a veces es til para una funcin que tiene una variable de copia del valor
de un parmetro para trabajar. Usted puede evitar definir una nueva variable a s mismo
dentro de la funcin mediante la especificacin de uno o ms parmetros
como parmetros variables en lugar. Los parmetros variables estn disponibles como
variables y no como constantes, y dan una nueva copia modificable del valor del
parmetro de la funcin de trabajar.
Definir parmetros variables con el prefijo del nombre del parmetro con la palabra
clave var :
func alignRight(var string: String, count: Int, pad: Character) -> String {
if amountToPad < 1 {
return string
for _ in 1...amountToPad {
return string
100
let temporaryA = a
a=b
b = temporaryA
}
El swapTwoInts funcin simplemente intercambia el valor de b en una , y el valor
de una en b . La funcin realiza este intercambio almacenando el valor de una en una
constante temporal llamada temporaryA , asignando el valor de b a una , y luego
asignar temporaryA a b .
Usted puede llamar al swapTwoInts funcin con dos variables de tipo int para
intercambiar sus valores. Tenga en cuenta que los nombres
101
var someInt = 3
swapTwoInts(&someInt, &anotherInt)
return a + b
return a * b
}
Este ejemplo define dos funciones matemticas simples
llamados addTwoInts y multiplyTwoInts . Estas funciones cada toman
dos Int valores y devuelven un int valor, que es el resultado de realizar una
operacin matemtica apropiada.
El tipo de ambas de estas funciones es (Int, Int) -> Int . Esto puede leerse
como:
"Un tipo de funcin que tiene dos parmetros, tanto de tipo int , y que devuelve un
valor de tipo int . "
He aqu otro ejemplo, para una funcin sin parmetros o valor de retorno:
func printHelloWorld() {
println("hello, world")
}
El tipo de esta funcin es () -> () , o "una funcin que no tiene parmetros y
devuelve vaco . "Funciones que no se especifique un valor de retorno siempre
devuelven vaco , lo que equivale a una tupla vaca en Swift, se muestra como () .
102
mathFunction = multiplyTwoInts
printMathResult(addTwoInts, 3, 5)
103
return input + 1
return input - 1
}
Aqu hay una funcin llamada chooseStepFunction , cuyo retorno tipo es "una
funcin del tipo (Int) -> Int ".chooseStepFunction devuelve
el StepForward funcin o la stepbackward funcin basada en un parmetro
Boolean llamada hacia atrs :
}
Ahora puede utilizar chooseStepFunction obtener una funcin que le paso en una
direccin o la otra:
var currentValue = 3
104
println("Counting to zero:")
// Counting to zero:
while currentValue != 0 {
println("\(currentValue)... ")
currentValue = moveNearerToZero(currentValue)
println("zero!")
// 3...
// 2...
// 1...
// zero!
Funciones anidadas
Todas las funciones que ha encontrado hasta ahora en este captulo han sido ejemplos
de funciones globales, que se definen en un mbito global. Tambin puede definir
funciones dentro de los cuerpos de otras funciones, conocidas como funciones
anidadas .
Funciones anidadas estn ocultos del mundo exterior de forma predeterminada, pero an
as pueden ser llamados y utilizados por su funcin envolvente. Una funcin envolvente
tambin puede devolver una de sus funciones anidados para permitir la funcin anidada
para ser utilizado en otro mbito.
Puede volver a escribir la chooseStepFunction ejemplo anterior de usar y
devolver funciones anidadas:
println("Counting to zero:")
// Counting to zero:
while currentValue != 0 {
println("\(currentValue)... ")
currentValue = moveNearerToZero(currentValue)
println("zero!")
// 3...
// 2...
// 1...
// zero!
105
Cierres
Los cierres son bloques autnomos de la funcionalidad que se pueden pasar alrededor y
utilizar en su cdigo.Cierres en Swift son similares a los bloques en C y Objective-C y
para lambdas en otros lenguajes de programacin.
Los cierres pueden capturar y almacenar las referencias a todos los constantes y
variables del contexto en el que se definen. Esto se conoce como el cierre de ms de
esas constantes y variables, de ah el nombre "cierres". Swift se encarga de toda la
gestin de memoria de captura para usted.
NOTA
No se preocupe si usted no est familiarizado con el concepto de "captura". Se explica
en detalle a continuacin en la captura de Valores .
Funciones globales y anidadas, como introdujo en funciones , en realidad son casos
especiales de cierres.Los cierres tienen una de tres formas:
Funciones globales son los cierres que tienen un nombre y no captan ningn valor.
Funciones anidadas son los cierres que tienen un nombre y pueden capturar valores
de su funcin que encierra.
Expresiones de cierre son cierres annimas escritas en una sintaxis ligera que puede
capturar los valores de su contexto circundante.
Expresiones de cierre de Swift tienen un estilo claro limpio, con optimizaciones que
fomenten breve sintaxis, libre de desorden en escenarios comunes. Estas optimizaciones
incluyen:
Inferir los parmetros y valores de retorno tipos de contexto
Rendimientos implcitos de los cierres de una sola expresin
Nombres de los argumentos taquigrafa
Perdiendo sintaxis cierre
Expresiones de cierre
Funciones anidadas, como introdujo en Funciones anidadas , son un medio conveniente
de nombrar y definir los bloques autnomos de cdigo como parte de una funcin ms
grande. Sin embargo, a veces es til escribir las versiones ms cortas de construcciones
tipo funcin sin una declaracin y nombre completo. Esto es particularmente cierto
cuando se trabaja con funciones que tienen otras funciones como uno o ms de sus
argumentos.
Expresiones de cierre son una manera de escribir cierres en lnea en una breve, centrado
sintaxis.Expresiones de cierre proporcionan varias optimizaciones de sintaxis para
escribir cierres en forma abreviada y sin prdida de claridad o la intencin. Los
ejemplos a continuacin ilustran el cierre de expresin estas optimizaciones mediante el
refinado de un nico ejemplo de la ordenada en funcin de varias iteraciones, cada
una de las cuales expresa la misma funcionalidad de una manera ms concisa.
La Funcin Ordenada
La biblioteca estndar de Swift proporciona una funcin llamada ordenados , que
ordena una matriz de valores de un tipo conocido, en base a la salida de un cierre de la
clasificacin que usted proporcione. Una vez que se completa el proceso de
clasificacin, la ordenada funcin devuelve una nueva matriz del mismo tipo y
tamao que el anterior, con sus elementos en el orden de clasificacin correcto. La
matriz original no es modificado por la ordenada funcin.
106
"Barry" , "Daniella" ]
La ordenada funcin toma dos argumentos:
Matriz de valores de un tipo conocido.
Un cierre que toma dos argumentos del mismo tipo que el contenido de la matriz, y
devuelve un Boolvalor para decir si el primer valor debe aparecer antes o despus
de que el segundo valor una vez que se ordenan los valores. El cierre de
clasificacin tiene que devolver verdadero si el primer valor debe
aparecer antes del segundo valor, y falso de lo contrario.
Este ejemplo es clasificar un conjunto de Cuerda valores, por lo que el cierre de la
clasificacin tiene que ser una funcin del tipo (String, String) -> Bool .
Una manera de proporcionar el cierre de clasificacin es escribir una funcin normal del
tipo correcto, y para pasarlo adentro como el clasificado segundo parmetro de la
funcin:
return s1 > s2
}
Sintaxis de las expresiones de cierre puede utilizar parmetros constantes, parmetros
variables y inoutparmetros. Los valores por defecto no puede ser
proporcionada. Parmetros variadic se pueden utilizar si el nombre del parmetro
107
variadic y coloca ltima en la lista de parmetros. Las tuplas tambin se puede utilizar
como tipos de parmetros y tipos de retorno.
El siguiente ejemplo muestra una versin expresin cierre del revs funcin de antes:
return s1 > s2
})
Tenga en cuenta que la declaracin de parmetros y el tipo de retorno para este cierre en
lnea es idntica a la declaracin del revs funcin. En ambos casos, se escribe
como (s1: String, s2: String) -> Bool . Sin embargo, para la expresin
de cierre en lnea, los parmetros y el tipo de retorno se escriben dentro de las llaves, y
no fuera de ellas.
El comienzo del cuerpo del cierre se introduce por el en la palabra clave. Esta palabra
clave indica que la definicin de parmetros y devuelve un tipo del cierre ha terminado,
y el cuerpo del cierre est por comenzar.
Debido a que el cuerpo del cierre es tan corto, que incluso se puede escribir en una sola
lnea:
reversed = sorted(names, { (s1: String, s2: String) -> Bool in return s1 > s2 } )
108
109
someFunctionThatTakesAClosure({
})
someFunctionThatTakesAClosure() {
}
NOTA
Si una expresin de cierre se proporciona como nico argumento de la funcin y le
proporcionar esa expresin como un cierre trasero, que no es necesario escribir un par
de parntesis () despus del nombre de la funcin cuando se llama a la funcin.
El cierre de cadena de clasificacin de la sintaxis de la expresin Cierre seccin anterior
se puede escribir fuera de la ordenada parntesis de funcionar como un cierre de
salida:
let digitNames = [
110
despus de mapa , porque el mapa mtodo tiene slo un parmetro, y ese parmetro se
proporciona como un cierre de arrastre:
number /= 10
return output
111
var runningTotal = 0
runningTotal += amount
return runningTotal
return incrementor
}
El tipo de retorno de makeIncrementor es () -> Int . Esto significa que
devuelve una funcin , en lugar de un valor simple. La funcin devuelve no tiene
parmetros y devuelve un int valor cada vez que se llama. Para aprender las funciones
pueden devolver otras funciones, consulte Tipos de funcin como tipo de retorno .
El makeIncrementor funcin define una variable entera llamada RunningTotal ,
para almacenar el total de ejecucin actual del incrementor que ser devuelto. Esta
variable se inicializa con un valor de 0 .
El makeIncrementor funcin tiene un nico int parmetro con un nombre externo
de forIncrement , y un nombre local de cantidad . El valor del argumento
pasado a este parmetro especifica cunto RunningTotaldebe ser incrementado por
cada vez que la funcin de volver incrementor se llama.
112
runningTotal += amount
return runningTotal
}
El incrementor funcin no tiene parmetros, y sin embargo, se refiere
a RunningTotal y cantidad de dentro de su cuerpo de la funcin. Lo hace
mediante la captura de los existentes valores de RunningTotal y cantidad de su
funcin alrededores y utilizarlos dentro de su propio cuerpo de la funcin.
Debido a que no modifica la cantidad , incrementor realmente capta y
almacena una copia del valor almacenado en cantidad . Este valor se almacena junto
con el nuevo incrementor funcin.
Sin embargo, ya que modifica la RunningTotal variable cada vez que se
llama, incrementor captura unareferencia a la actual RunningTotal variables, y
no slo una copia de su valor inicial. Captura de una referencia asegura
que RunningTotal no desaparece cuando la llamada
a makeIncrementor termina y asegura queRunningTotal seguir siendo
disponible la prxima vez que la funcin incrementor se llama.
NOTA
Swift determina lo que debe ser capturado por referencia y lo que debera ser copiada
por valor. No es necesario anotar la cantidad o RunningTotal decir que se
pueden utilizar dentro del anidado incrementorfuncin. Swift tambin se encarga de
toda la gestin de memoria que supone la colocacin de RunningTotalcuando ya no
es necesaria por la funcin incrementor.
He aqu un ejemplo de makeIncrementor en accin:
incrementByTen()
// returns a value of 10
incrementByTen()
// returns a value of 20
incrementByTen()
// Devuelve un valor de 30
Si se crea una segunda incrementor, tendr su propia referencia almacenado a una
nueva, separadaRunningTotal variables:
// Devuelve un valor de 7
Llamar a la incrementor originales ( incrementByTen ) de nuevo contina para
incrementar su propiaRunningTotal variables, y no afecta a la variable capturada
por incrementBySeven :
incrementBySeven()
incrementByTen()
// Devuelve un valor de 40
NOTA
Si asigna un cierre a una propiedad de una instancia de clase, y el cierre captura ese
ejemplo haciendo referencia a la instancia o de sus miembros, crear un fuerte ciclo de
referencia entre el cierre y la instancia.Swift utiliza listas de captura para romper estos
ciclos de referencia fuertes. Para obtener ms informacin, consulte Ciclos de referencia
fuertes para cierres .
Los cierres son tipos de referencia
En el ejemplo anterior, incrementBySeven y incrementByTen son constantes,
pero los cierres de estas constantes se refieren a son todava capaces de incrementar
los RunningTotal variables que se han capturado. Esto se debe a que las funciones y
los cierres son los tipos de referencia .
Cada vez que se asigna una funcin o un cierre a una constante o una variable, en
realidad se est configurando esa constante o variable para ser una referencia a la
funcin o el cierre. En el ejemplo anterior, es la eleccin de cierre
que incrementByTen se refiere a que es constante, y no los contenidos del propio
cierre.
Esto tambin significa que si asigna un cierre de dos constantes o variables diferentes,
tanto de esas constantes o variables se refieren a la misma de cierre:
alsoIncrementByTen()
// Devuelve un valor de 50
Funciones
Las enumeraciones
Las enumeraciones
Una enumeracin define un tipo comn de un grupo de valores relacionados y le
permite trabajar con los valores de una manera con seguridad de tipos dentro de su
cdigo.
Si est familiarizado con C, sabrs que C enumeraciones asignan nombres relacionados
a un conjunto de valores enteros. Las enumeraciones de Swift son mucho ms flexibles,
y no tienen que proporcionar un valor para cada miembro de la enumeracin. Si un
valor (conocido como valor de "prima") se proporciona para cada miembro de la
enumeracin, el valor puede ser una cadena, un carcter o un valor de nmero entero o
tipo de punto flotante.
Alternativamente, los miembros de enumeracin pueden especificar valores asociados
de cualquier tipo para ser almacenados junto con cada valor de miembro diferente, tanto
como los sindicatos o variantes hacen en otras lenguas. Puede definir un conjunto
114
comn de miembros relacionados como parte de una enumeracin, cada uno de los
cuales tiene un conjunto diferente de valores de tipos apropiados asociados.
Las enumeraciones de Swift son tipos de primera clase en su propio derecho. Adoptan
muchas caractersticas que tradicionalmente slo compatibles con las clases, como las
propiedades calculadas para proporcionar informacin adicional sobre el valor actual de
la enumeracin, y los mtodos de instancia para proporcionar funcionalidad relacionada
con los valores de la enumeracin representa. Las enumeraciones pueden definir
tambin inicializadores para proporcionar un valor inicial miembro; se puede extender
para ampliar su funcionalidad ms all de su aplicacin original; y puede ajustarse a los
protocolos para proporcionar una funcionalidad estndar.
Para ms informacin sobre estas funciones,
consulte Properties, Methods, Initialization, Extensions, and Protocols.
Sintaxis Enumeracin
Introduces enumeraciones con la enumeracin de palabras clave y colocar toda su
definicin dentro de un par de llaves:
enum SomeEnumeration {
}
He aqu un ejemplo de los cuatro puntos principales de una brjula:
enum CompassPoint {
case North
case South
case East
case West
}
Los valores definidos en la enumeracin (como Norte , Sur , Este y Oeste ) son
los valores de los miembros(o miembros ) de esa enumeracin. El caso de palabras
clave indica que una nueva lnea de valores de los miembros est por ser definido.
NOTA
A diferencia de C y Objective-C, miembros de la enumeracin Swift no se les asigna un
valor entero por defecto cuando se crean. En el CompassPoint ejemplo
anterior, Norte , Sur , Este y Oeste no lo hacen implcitamente
igual 0 , 1 , 2 y 3 . En su lugar, los diferentes miembros de la enumeracin son valores
de pleno derecho en su propio derecho, con un tipo definido de forma explcitade CompassPoint .
Valores de los miembros mltiples pueden aparecer en una sola lnea, separados por
comas:
enum Planet {
}
Each enumeration definition defines a brand new type. Like other types in Swift, their
Cada definicin de enumeracin define un nuevo tipo de marca. Al igual que otros tipos
115
de Swift, sus nombres (como CompassPoint y Planeta ) deben comenzar con una
letra mayscula. Dale tipos de enumeracin singulares en lugar de nombres en plural,
para que se lean como evidente:
directionToHead =. Oriente
El tipo de directionToHead ya se conoce, y por lo que puede bajar el tipo al
establecer su valor. Esto lo convierte en cdigo muy legible cuando se trabaja con
valores de enumeracin explcita mecanografiadas-.
Coincidencia de Valores de enumeracin con una sentencia switch
Puede coincidir con los valores de enumeracin individuales con un interruptor
de declaracin:
directionToHead = .South
switch directionToHead {
case .North:
case .South:
case .East:
case .West:
116
switch somePlanet {
case .Earth:
println("Mostly harmless")
default:
Otros productos que estn etiquetados con cdigos de barras 2D en forma de cdigos
QR, que pueden usar cualquiera de caracteres ISO 8859-1 y puede codificar una cadena
de hasta 2.953 caracteres de longitud:
117
Sera conveniente para un sistema de seguimiento de inventario para poder almacenar
los cdigos de barras UPC-A como una tupla de cuatro enteros, y los cdigos de barras
de cdigos QR como una cadena de cualquier longitud.
En Swift, una enumeracin para definir los cdigos de barras de productos de cualquier
tipo podra tener este aspecto:
enum Barcode {
case QRCode(String)
}
Esto puede leerse como:
"Definir un tipo de enumeracin llamado cdigo de barras , el cual puede tomar
un valor de UPCA con un valor asociado de tipo ( Int , Int , Int , Int ), o un valor
de QRCode con un valor asociado de tipo Cadena . "
Esta definicin no ofrece reales Int o de Cuerda valores-que slo define el tipo de
valores asociados que de cdigo de barras constantes y variables se almacenan
cuando son iguales a Barcode.UPCA oBarcode.QRCode .
Nuevos cdigos de barras a continuacin, se pueden crear utilizando cualquier tipo:
var productBarcode = cdigo de barras . UPCA ( 8 , 85909 ,
51226 , 3 )
En este ejemplo se crea una nueva variable llamada productBarcode y le asigna un
valor de Barcode.UPCAcon un valor asociado de tupla (8, 85909, 51226,
3) .
El mismo producto se puede asignar un tipo diferente de cdigo de barras:
productBarcode = .QRCode("ABCDEFGHIJKLMNOP")
En este punto, el original Barcode.UPCA sus valores enteros y se sustituyen por el
nuevo Barcode.QRCode y su valor de cadena. Constantes y variables de tipo de
cdigo de barras se pueden almacenar ya sea un .UPCAo una .QRCode (junto
con sus valores asociados), pero slo pueden almacenar uno de ellos en un momento
dado.
Los diferentes tipos de cdigos de barras se pueden verificar utilizando una sentencia
switch, como antes.Esta vez, sin embargo, los valores asociados puede ser extrada
como parte de la instruccin switch. Extraer cada valor asociado como una constante
118
(con la let prefijo) o una variable (con la var prefijo) para su uso en
el interruptor del cuerpo de caso:
switch productBarcode {
switch productBarcode {
}
En este caso, los valores de primas para una enumeracin
denominada ASCIIControlCharacter se definen como de tipo de
caracteres , y se ponen a algunos de los personajes ms comunes de control
ASCII.Carcter valores se describen en Cuerdas y Personajes .
Tenga en cuenta que los valores de primas son no lo mismo que los valores
asociados. Valores primas se ajustan a los valores rellenados previamente cuando defina
primero la enumeracin en el cdigo, como los tres cdigos ASCII anteriores. El valor
119
}
Auto-incrementacin significa que Planet.Venus tiene un valor en bruto de 2 , y as
sucesivamente.
Acceder al valor bruto de un miembro de la enumeracin con su toRaw mtodo:
// earthsOrder is 3
Utilizar de una enumeracin fromRaw mtodo para tratar de encontrar un miembro de
la enumeracin con un valor bruto particular. En este ejemplo se identifica Urano de su
valor bruto de 7 :
let positionToFind = 9
switch somePlanet {
case .Earth:
println("Mostly harmless")
default:
} else {
120
En este ejemplo se utiliza opcional vinculante para tratar de acceder a un planeta con un
valor bruto de 9 . La declaracin si dejar somePlanet = Planet.fromRaw
(9) recupera un opcional Planet , y establecesomePlanet al contenido de ese
opcional Planet si puede ser recuperada. En este caso, no es posible recuperar un
planeta con una posicin de 9 , por lo que la otra rama se ejecuta en su lugar.
Clases y estructuras
Las clases y las estructuras son de uso general, construcciones flexibles que se
convierten en los componentes bsicos del cdigo de su programa. Usted define las
propiedades y mtodos para agregar funcionalidad a sus clases y estructuras utilizando
exactamente la misma sintaxis que para las constantes, variables y funciones.
A diferencia de otros lenguajes de programacin, Swift no le requiere para crear
archivos de interfaz y de aplicacin nica para las clases y estructuras
personalizadas. En Swift, se define una clase o una estructura en un solo archivo, y la
interfaz externa a esa clase o estructura se hace automticamente disponible para otro
cdigo a utilizar.
NOTA
Una instancia de una clase se conoce tradicionalmente como un objeto . Sin embargo,
las clases y las estructuras de Swift estn mucho ms cerca en la funcionalidad que en
otros idiomas, y gran parte de este captulo se describe la funcionalidad que se puede
aplicar a instancias de cualquiera de una clase o un tipo de estructura. Debido a esto, el
trmino ms general de ejemplo se utiliza.
La comparacin de clases y estructuras
Clases y estructuras en Swift tienen muchas cosas en comn. Ambos pueden:
Definir propiedades para almacenar valores
Definir los mtodos para proporcionar funcionalidad
Definir subndices para dar acceso a sus valores usando la sintaxis subndice
Definir inicializadores para establecer su estado inicial
Se ampliar para ampliar su funcionalidad ms all de una implementacin por
defecto
Conformarse a protocolos para proporcionar una funcionalidad estndar de un cierto
tipo
Para obtener ms informacin,
vea Propiedades , Mtodos , subndices , inicializacin , extensiones , yProtocolos .
Las clases tienen capacidades adicionales que las estructuras no hacen:
La herencia permite a una clase a heredar las caractersticas de otro.
Tipo de fundicin permite comprobar e interpretar el tipo de una instancia de clase
en tiempo de ejecucin.
Deinitializers permiten una instancia de una clase para liberar todos los recursos que
tiene asignados.
El conteo de referencias permite ms de una referencia a una instancia de clase.
Para obtener ms informacin, vea Herencia , la conversin de
tipos , deinicializacin y conteo automtico de referencia .
NOTA
121
class SomeClass {
struct SomeStructure {
}
NOTA
Cada vez que se define una nueva clase o estructura, se definen de manera efectiva un
nuevo tipo Swift marca. Dale tipos UpperCamelCase nombres
(como AlgunaClase y SomeStructure aqu) para que coincida con la
capitalizacin de los tipos Swift estndar (tales como cuerdas , Int , y Bool ). Por
el contrario, siempre dan propiedades y mtodos lowerCamelCase nombres
(como frameRate y incrementCount ) para diferenciarlos de los nombres de los
tipos.
He aqu un ejemplo de una definicin de la estructura y una definicin de clase:
struct Resolution {
var width = 0
var height = 0
class VideoMode {
}
El ejemplo anterior define una nueva estructura llamada Resolucin , para describir
una resolucin de pantalla basado en pxeles. Esta estructura tiene dos propiedades
almacenado llamado anchura y altura .Propiedades almacenados son constantes o
variables que se empaquetan y almacenan como parte de la clase o estructura. Estas dos
propiedades se infieren a ser de tipo Int estableciendo su valor a un valor entero inicial
de 0 .
El ejemplo anterior tambin define una nueva clase llamada VideoMode , para
describir un modo de vdeo especfico para la visualizacin de vdeo. Esta clase tiene
cuatro propiedades almacenadas variables. La primera, la resolucin , se
inicializa con una nueva Resolucin instancia de estructura, lo que infiere un tipo de
propiedad de la Resolucin . Para las otras tres propiedades,
122
someVideoMode.resolution.width = 1280
123
var cinema = hd
En este ejemplo se declara una llamada constante hd y lo establece en
un Resolucin instancia inicializada con el ancho y la altura de vdeo Full HD
( 1920 pxeles de ancho por 1080 pxeles de alto).
A continuacin, declara una variable de llamada del cine y lo establece en el valor
actual de hd . DebidoResolucin es una estructura, una copia est hecha de la
instancia existente, y esta nueva copia se asigna acine . Aunque hd y el
cine tienen ahora la misma anchura y altura, son dos casos completamente diferentes
entre bastidores.
A continuacin, el ancho de la propiedad del cine se modifica para ser el ancho de
la 2K estndar ligeramente ms amplio utilizado para la proyeccin de cine digital
( 2048 pxeles de ancho por 1080 pxeles de alto):
enum CompassPoint {
currentDirection = .East
if rememberedDirection == .West {
tenEighty.resolution = hd
tenEighty.interlaced = true
tenEighty.name = "1080i"
tenEighty.frameRate = 25.0
En este ejemplo se declara una nueva constante llamada Teneighty y establece que
para referirse a una nueva instancia de la VideoMode clase. El modo de vdeo se le
asigna una copia de la resolucin HD de 1.920por 1.080 de antes. Se fija para ser
entrelazadas, y se le da un nombre de "1080i" . Finalmente, se establece a una
velocidad de 25,0 fotogramas por segundo.
A continuacin, Teneighty se asigna a una nueva constante,
llamado alsoTenEighty , y la velocidad de fotogramas de alsoTenEighty se
modifica:
125
alsoTenEighty.frameRate = 30.0
Debido a que las clases son tipos de
referencia, Teneighty y alsoTenEighty realidad ambos se refieren a
lamisma VideoMode instancia. Efectivamente, son slo dos nombres diferentes para la
misma instancia nica.
Comprobacin del frameRate propiedad de Teneighty muestra que informa
correctamente la nueva velocidad de fotogramas de 30,0 desde el
subyacente VideoMode ejemplo:
126
127
128
struct FixedLengthRange {
rangeOfThreeItems.firstValue = 6
rangeOfFourItems.firstValue = 6
129
valor antes de la inicializacin completa, y por lo tanto no pueden ser declarados como
perezoso.
Lazy propiedades son tiles cuando el valor inicial de una propiedad depende de
factores externos, cuyos valores no se conocen hasta despus de la inicializacin de una
instancia se ha completado. Lazy propiedades tambin son tiles cuando el valor inicial
de una propiedad requiere configuracin compleja o costosa computacionalmente que
no debe realizarse a menos que o hasta que se necesite.
El ejemplo siguiente utiliza una propiedad almacenada perezosa para evitar la
inicializacin innecesaria de una clase compleja. Este ejemplo define dos clases
llamadas DataImporter y DataManager , ninguno de los cuales se muestra en su
totalidad:
class DataImporter {
/ *
* /
class DataManager {
manager.data.append("Some data")
130
println(manager.importer.fileName)
// Impresiones "data.txt"
Propiedades almacenados y variables de instancia
Si usted tiene experiencia con Objective-C, usted puede saber que ofrece dos formas de
almacenar los valores y las referencias como parte de una instancia de clase. Adems de
las propiedades, puede utilizar las variables de instancia como un almacn de respaldo
para los valores almacenados en una propiedad.
Swift unifica estos conceptos en una nica declaracin de propiedad. Una propiedad
Swift no tiene una variable de instancia correspondiente, y el almacn de respaldo para
una propiedad no se accede directamente. Este enfoque evita la confusin acerca de
cmo se accede al valor en diferentes contextos y simplifica la declaracin de la
propiedad en una sola sentencia, definitiva. Toda la informacin sobre la propiedadincluyendo su nombre, caractersticas-es el tipo y la gestin de memoria definen en un
solo lugar, como parte de la definicin del tipo.
Propiedades calculadas
Adems de las propiedades almacenados, clases, estructuras y enumeraciones pueden
definir propiedades calculadas , que en realidad no almacenan un valor. En su lugar,
proporcionan un getter y un setter opcional para recuperar y establecer otras
propiedades y valores de manera indirecta.
struct Point {
struct Size {
}
131
struct Rect {
get {
set(newCenter) {
132
de la plaza. Como se puede ver arriba, el getter devuelve correctamente un punto central
de (5, 5) .
El centro de la propiedad se establece a continuacin, a un nuevo valor de (15,
15) , que se mueve a la plaza arriba y hacia la derecha, a la nueva posicin mostrada
por el cuadrado de color naranja en el siguiente diagrama. Ajuste del centro de la
propiedad llama al colocador de centro , que modifica la x y Y los valores de la
almacenada origen propiedad, y se mueve hacia la plaza a su nueva posicin.
Taquigrafa Declaracin Setter
Si seleccionador de propiedades computarizada no define un nombre para el nuevo
valor que se determine, el nombre predeterminado nuevoValor se utiliza. Aqu hay
una versin alternativa de la Rect estructura, que se aprovecha de esta notacin
abreviada:
struct AlternativeRect {
get {
133
set {
}
Slo lectura Propiedades calculadas
Una propiedad calculada con un captador pero ningn organismo que se conoce como
una propiedad calculada de slo lectura . Una propiedad de slo lectura computarizada
siempre devuelve un valor, y se puede acceder a travs de la sintaxis con punto, pero no
se puede ajustar a un valor diferente.
NOTA
Debe declarar propiedades-incluyendo calculados propiedades de slo lectura-como
propiedades de las variables calculadas con la var palabra clave, porque su valor no es
fijo. El let palabra clave slo se utiliza para propiedades constantes, para indicar que
sus valores no se pueden cambiar una vez que se establecen como parte de inicializacin
de instancia.
Se puede simplificar la declaracin de un solo lectura propiedad calculada mediante la
eliminacin de la getpalabra clave y sus apoyos:
struct Cuboid {
134
class StepCounter {
willSet(newTotalSteps) {
didSet {
}
135
stepCounter.totalSteps = 200
stepCounter.totalSteps = 360
stepCounter.totalSteps = 896
136
Constantes y variables globales se calculan siempre con pereza, de una manera similar
a to Lazy Stored Properties. A diferencia de las propiedades almacenados perezosos,
constantes y variables globales no necesitan ser marcados con el lazy modificador.
Constantes y variables locales no se calculan perezosamente.
Tipo de Propiedades
Propiedades de instancia son las propiedades que pertenecen a una instancia de un tipo
particular. Cada vez que se crea una nueva instancia de ese tipo, tiene su propio
conjunto de valores de la propiedad, separada de cualquier otra instancia.
Tambin puede definir propiedades que pertenecen al tipo de s mismo, no a cualquier
instancia de ese tipo.Slo habr alguna vez una copia de estas propiedades, no importa
cuntas instancias de ese tipo que crean.Estos tipos de propiedades se
denominan propiedades de tipo .
Propiedades de tipo son tiles para definir los valores que son universales para todas
las instancias de un tipo particular, tal como una propiedad constante que todas las
instancias pueden utilizar (como una constante esttica en C), o una propiedad variable
que almacena un valor que es global para todos los instancias de ese tipo (como una
variable esttica en C).
Para los tipos de valor (es decir, estructuras y enumeraciones), puede definir
almacenado y calculado propiedades de tipo. Para las clases, puede definir slo
propiedades de tipo computados.
Propiedades de tipo almacenados para los tipos de valor pueden ser variables o
constantes. Propiedades de tipo calculadas siempre se declaran como propiedades de las
variables, en la misma forma que las propiedades de instancia computados.
NOTA
A diferencia de propiedades de la instancia almacenados, siempre hay que dar
propiedades de tipo almacenado un valor por defecto. Esto es porque el tipo en s no
tiene un inicializador que puede asignar un valor a una propiedad de tipo almacenado en
tiempo de inicializacin.
Escriba Propiedad Sintaxis
En C y Objective-C, se define constantes estticas y variables asociadas a un tipo
como globales variables estticas. En Swift, sin embargo, las propiedades del tipo se
escriben como parte de la definicin del tipo, entre llaves exteriores del tipo, y cada
propiedad tiene el mbito de tipo explcitamente al tipo que soporta.
Usted define las propiedades del tipo para los tipos de valor con la esttica de
palabras clave y propiedades de tipo para los tipos de clase con la clase de palabras
clave. El siguiente ejemplo muestra la sintaxis de propiedades de tipo almacenados y
calculados:
struct SomeStructure {
}
137
enum SomeEnumeration {
class SomeClass {
}
NOTA
Los ejemplos calculados tipo de propiedad anteriores son para propiedades de tipo de
slo lectura computados, pero tambin es posible definir propiedades de estilo
calculados con la misma sintaxis que para las propiedades de instancia calculados de
lectura-escritura.
Consulta y ajuste del tipo de Propiedades
Tipo propiedades se consultan y establecen con la sintaxis con punto, al igual que las
propiedades de instancia. Sin embargo, las propiedades del tipo se consultan y
establecen en el tipo , no en una instancia de ese tipo. Por ejemplo:
println(SomeClass.computedTypeProperty)
// imprime "42"
println(SomeStructure.storedTypeProperty)
println(SomeStructure.storedTypeProperty)
138
Los canales de audio descritos anteriormente estn representados por instancias de
la AudioChannelestructura:
struct AudioChannel {
didSet {
currentLevel = AudioChannel.thresholdLevel
AudioChannel.maxInputLevelForAllChannels = currentLevel
}
El AudioChannel estructura define dos propiedades de tipo almacenados en apoyo
de su funcionalidad. El primero, thresholdLevel , define el valor de umbral
mximo un nivel de audio puede tomar. Este es un valor constante de 10 para todos
los AudioChannel casos. Si una seal de audio llega con un valor superior a 10 , que
se limitar a este valor de umbral (como se describe a continuacin).
139
leftChannel.currentLevel = 7
println(leftChannel.currentLevel)
// prints "7"
println(AudioChannel.maxInputLevelForAllChannels)
// imprime "7"
Si se intenta establecer la CurrentLevel de la derecha del canal a 11 , se puede ver
que el canal derechoCurrentLevel propiedad est limitado al valor mximo de 10 ,
y el maxInputLevelForAllChannels tipo de propiedad se ha actualizado a la
igualdad 10 :
rightChannel.currentLevel = 11
println(rightChannel.currentLevel)
// imprime "10"
println(AudioChannel.maxInputLevelForAllChannels)
// imprime "10"
140
Mtodos
En esta pgina
Mtodos son funciones que estn asociadas con un tipo particular. Las clases,
estructuras y enumeraciones todos pueden definir mtodos de instancia, que encapsulan
tareas y funciones especficas para trabajar con una instancia de un tipo dado. Las
clases, estructuras y enumeraciones tambin pueden definir mtodos de tipo, que se
asocian con el propio tipo. Tipo mtodos son similares a los mtodos de clase en
Objective-C.
El hecho de que las estructuras y enumeraciones pueden definir mtodos en Swift es
una gran diferencia con C y Objective-C. En Objective-C, las clases son los nicos tipos
que pueden definir mtodos. En Swift, puede elegir si desea definir una clase, estructura
o enumeracin, y an as tener la flexibilidad de definir mtodos en el tipo que cree.
Mtodos de instancia
Los mtodos de instancia son funciones que pertenecen a instancias de una clase,
estructura o enumeracin particular. Apoyan a la funcionalidad de los casos, ya sea
proporcionando formas de acceder y modificar las propiedades de instancia, o
proporcionando una funcionalidad relacionada con el propsito de la instancia.Los
mtodos de instancia tienen exactamente la misma sintaxis que las funciones, como se
describe enFunciones .
Usted escribe un mtodo de instancia dentro de las llaves de apertura y cierre del tipo al
que pertenece. Un mtodo de instancia tiene acceso implcito a todos los dems
mtodos de instancia y las propiedades de ese tipo. Un mtodo de instancia slo se
puede llamar a una instancia especfica del tipo al que pertenece. No se puede llamar de
forma aislada, sin una instancia existente.
He aqu un ejemplo que define un sencillo contador de la clase, que se puede
utilizar para contar el nmero de veces que se produce una accin:
class Counter {
var count = 0
func increment() {
count++
count += amount
func reset() {
count = 0
}
El contador de clase define tres mtodos de instancia:
Valor mnimo incrementa el contador por 1 .
incrementBy (cantidad: Int) incrementa el contador por un importe
entero especificado.
141
counter.increment()
counter.incrementBy(5)
counter.reset()
class Counter {
142
}
Esta incrementBy mtodo tiene dos parmetroscantidad y numberOfTimes . De forma predeterminada, Swift
trata cantidad tan slo un nombre local, pero trata numberOfTimes como tanto
local y un nombre externo.Llamar al mtodo de la siguiente manera:
counter.incrementBy(5, numberOfTimes: 3)
}
El comportamiento predeterminado descrito anteriormente significa que las definiciones
de mtodo en Swift se escriben con el mismo estilo gramatical como Objective-C, y se
llaman de una manera natural, expresiva.
Modificacin de parmetros externos Comportamiento Nombre de Mtodos
A veces es til para proporcionar un nombre de parmetro externo para el primer
parmetro de un mtodo, a pesar de que este no es el comportamiento
predeterminado. Usted puede aadir un nombre externo explcito a ti mismo, o puede
anteponer el nombre del primer parmetro con un smbolo de hash para utilizar el
nombre local como un nombre externo tambin.
Por el contrario, si usted no desea proporcionar un nombre externo para el segundo o
subsiguiente parmetro de un mtodo, reemplazar el comportamiento predeterminado
mediante un carcter de subrayado ( _ ) como un nombre de parmetro externo explcito
para ese parmetro.
El auto de la propiedad
Cada instancia de un tipo tiene una propiedad llamada implcita auto , que es
exactamente equivalente a la propia instancia. Se utiliza el auto propiedad para hacer
referencia a la instancia actual dentro de sus propios mtodos de instancia.
El incremento de mtodo en el ejemplo anterior se podra haber escrito as:
func increment() {
self.count++
}
En la prctica, no es necesario escribir uno mismo en su cdigo muy a menudo. Si
usted no escribe explcitamente auto , Swift asume que se est haciendo referencia a
143
una propiedad o mtodo de la instancia actual cada vez que utilice una propiedad
conocida o nombre de mtodo dentro de un mtodo. Esta suposicin se demostr
mediante el uso de recuento (en lugar de self.count ) dentro de los tres mtodos
de instancia para Contador .
La principal excepcin a esta regla se produce cuando un nombre de parmetro para un
mtodo de instancia tiene el mismo nombre que una propiedad de esa instancia. En esta
situacin, el nombre del parmetro tiene prioridad, y se hace necesario hacer referencia
a la propiedad de forma ms cualificada. Se utiliza el autopropiedad de distinguir entre
el nombre del parmetro y el nombre de la propiedad.
Aqu, por cuenta de ambigedad entre un parmetro de mtodo llamado x y una
propiedad de instancia que tambin se llama x :
struct Point {
if somePoint.isToTheRightOfX(1.0) {
struct Point {
x += deltaX
y += deltaY
somePoint.moveByX(2.0, y: 3.0)
fixedPoint.moveByX(2.0, y: 3.0)
struct Point {
}
This version of the mutating moveByX method creates a brand new structure Esta
versin de la mutacin moveByX mtodo crea una nueva estructura de marcas
cuya x y Y los valores se establecen en la ubicacin de destino. El resultado final de
llamar a esta versin alternativa del mtodo ser exactamente la misma que para llamar
a la versin anterior.
La mutacin de los mtodos para enumeraciones puede establecer el
implcito auto parmetro que ser miembro diferente de la misma enumeracin:
enum TriStateSwitch {
switch self {
145
case Off:
self = Low
case Low:
self = High
case High:
self = Off
ovenLight.next()
ovenLight.next()
class SomeClass {
SomeClass.someTypeMethod()
Dentro del cuerpo de un mtodo de tipo, lo implcito auto propiedad se refiere al tipo
en s, en lugar de una instancia de ese tipo. Para las estructuras y enumeraciones, esto
significa que usted puede utilizar auto para eliminar la ambigedad entre las
146
propiedades estticas y parmetros del mtodo esttico, tal como lo hace para las
propiedades de instancia y los parmetros del mtodo de instancia.
Ms en general, cualquier mtodo y propiedad nombres no calificados que se utilizan
dentro del cuerpo de un mtodo tipo se referirn a otros mtodos y propiedades de nivel
de tipo. Un mtodo de tipo puede llamar a otro mtodo de tipo con el nombre del otro
mtodo, sin necesidad de un prefijo con el nombre del tipo. Del mismo modo, los
mtodos de tipo de estructuras y enumeraciones pueden tener acceso a las propiedades
estticas utilizando el nombre de la propiedad esttica sin un prefijo de nombre de tipo.
El ejemplo siguiente define una estructura llamada LevelTracker , que rastrea el
progreso del jugador a travs de los diferentes niveles o etapas de un juego. Es un juego
para un solo jugador, pero puede almacenar informacin para mltiples jugadores en un
solo dispositivo.
Todos los niveles del juego (aparte de nivel uno) estn bloqueadas cuando el partido se
jug por primera vez.Cada vez que un jugador termina un nivel, ese nivel est
desbloqueado para todos los jugadores en el dispositivo. El LevelTracker estructura
utiliza propiedades y mtodos estticos para no perder de vista que los niveles del juego
han sido desbloqueados. Tambin realiza un seguimiento del nivel actual para un
jugador individual.
struct LevelTracker {
var currentLevel = 1
if LevelTracker.levelIsUnlocked(level) {
currentLevel = level
return true
} else {
return false
}
El LevelTracker estructura no pierde de vista el nivel ms alto que cualquier
jugador ha desbloqueado. Este valor se almacena en una propiedad esttica
llamada highestUnlockedLevel .
LevelTracker tambin define dos funciones de tipo para trabajar con
el highestUnlockedLevel propiedad. La primera es una funcin de tipo de
147
class Player {
LevelTracker.unlockLevel(level + 1)
tracker.advanceToLevel(level + 1)
init(name: String) {
playerName = name
}
El player de la clase crea una nueva instancia de LevelTracker para seguir el
progreso de ese jugador.Tambin proporciona un mtodo
llamado completedLevel , que se llama cada vez que un jugador completa un nivel
particular. Este mtodo desbloquea el siguiente nivel para todos los jugadores y
actualiza el progreso del jugador para moverse al siguiente nivel. (El valor de retorno
booleano de advanceToLevel se ignora, ya que el nivel es conocido por haber sido
desbloqueado por la llamada a LevelTracker.unlockLevel en el rubro anterior.)
Puede crear una instancia del player de clase para un nuevo jugador, y ver lo que
sucede cuando el jugador completa el nivel uno:
player.completedLevel(1)
148
Si crea un segundo jugador, quien intenta mover a un nivel que todava no est
desbloqueado por cualquier jugador en el juego, el intento de establecer el nivel actual
del jugador falla:
if player.tracker.advanceToLevel(6) {
} else {
get {
set(newValue) {
149
}
He aqu un ejemplo de una aplicacin de slo lectura subndice, que define
un TimesTable estructura para representar un n -veces-tabla de enteros:
struct TimesTable {
150
numberOfLegs["bird"] = 2
El ejemplo anterior define una variable llamada numberOfLegs y lo inicializa con un
diccionario literal que contiene tres pares clave-valor. El tipo de
la numberOfLegs diccionario se infiere que [Cadena: Int] . Despus de crear el
diccionario, este ejemplo utiliza la asignacin subndice aadir una cuerda clave
de "pjaro" y unInt valor de 2 al diccionario.
Para obtener ms informacin acerca de Diccionario subndices, consulte Acceso y
Modificacin de un diccionario .
NOTA
El Dictionary tipo de Swift implementa su subscripting clave-valor como un
subndice que toma y recibe unaopcional tipo. Para los numberOfLegs diccionario de
ms arriba, el subndice de clave y valor toma y devuelve un valor de tipo int? , o "int
opcional". El Diccionario de tipo utiliza un tipo subndice opcional para modelar el
hecho de que no todas las teclas tendr un valor, y para dar una forma de eliminar un
valor de una clave mediante la asignacin de un nulo valor para esa llave.
Opciones Subndice
Los subndices pueden tomar cualquier nmero de parmetros de entrada, y estos
parmetros de entrada pueden ser de cualquier tipo. Los subndices tambin pueden
devolver cualquier tipo. Los subndices se pueden utilizar parmetros variables y
parmetros variadic, pero no pueden utilizar in-out parmetros o proporcionar valores
de los parmetros por defecto.
Una clase o estructura puede proporcionar tantas implementaciones subndice ya que
necesita, y el subndice adecuado para ser utilizado se infiere sobre la base de los tipos
de valor o los valores que se encuentran dentro de las llaves de subndice en el punto
que se utiliza el subndice. Esta definicin de mltiples subndices se conoce
como sobrecarga subndice .
Si bien es ms comn para un subndice para tomar un solo parmetro, tambin puede
definir un subndice con mltiples parmetros si es apropiado para su tipo. El ejemplo
siguiente define una matriz de estructura, lo que representa una matriz
bidimensional de dobles valores. El Matrix subndice de estructura toma dos
parmetros enteros:
struct Matrix {
self.rows = rows
self.columns = columns
151
return row >= 0 && row < rows && column >= 0 && column < columns
get {
set {
}
Matrix proporciona un inicializador que toma dos parmetros
denominados filas y columnas , y crea una matriz que es lo suficientemente grande
para almacenar filas * columnas valores de tipo doble . Cada posicin en la
matriz se le da un valor inicial de 0,0 . Para lograr esto, el tamao de la matriz, y un
valor de la celda inicial de 0.0 , se pasan a un inicializador de matriz que crea e
inicializa una nueva matriz del tamao correcto. Este inicializador se describe con ms
detalle en la creacin e inicializacin de una matriz .
Usted puede construir una nueva matriz de ejemplo haciendo pasar una fila
adecuada y el recuento de la columna a su inicializador:
Los valores en la matriz pueden ser establecidas pasando los valores de fila y columna
en el subndice, separados por una coma:
matrix[0, 1] = 1.5
matrix[1, 0] = 3.2
152
Estas dos afirmaciones llaman setter del subndice para establecer un valor de 1,5 en la
posicin superior derecha de la matriz (donde fila es 0 y la columna es 1 ),
y 3,2 en la posicin inferior izquierda (donde fila es1 y la columna es 0 ):
El Matrix get y set de subndice ambos contienen una afirmacin para comprobar que
el subndice de fila ycolumna valores son vlidos. Para ayudar con estas
afirmaciones, Matrix incluye un mtodo de conveniencia
denominada indexIsValidForRow (_: :) columna , que comprueba si el
solicitado fila y columna estn dentro de los lmites de la matriz:
return row >= 0 && row < rows && column >= 0 && column < columns
}
Una afirmacin se activa si se intenta acceder a un subndice que se encuentra fuera de
los lmites de la matriz:
Herencia
Una clase puede heredar mtodos, propiedades y otras caractersticas de otra
clase. Cuando una clase hereda de otra, la clase que hereda se conoce como
una subclase , y la clase que hereda de que se conoce como su superclase . La herencia
es un comportamiento fundamental que diferencia a las clases de otros tipos en Swift.
Clases en Swift pueden llamar y acceso mtodos, las propiedades y los subndices que
pertenecen a su superclase y pueden proporcionar sus propias versiones primordiales de
esos mtodos, propiedades y subndices para refinar o modificar su
comportamiento. Swift ayuda a asegurar las sustituciones son correctos mediante la
comprobacin de que la definicin de anulacin tiene una definicin de superclase a
juego.
Las clases tambin pueden agregar observadores de propiedad de las propiedades
heredadas a fin de ser notificados cuando el valor de una propiedad
cambia. Observadores de propiedad se pueden agregar a cualquier propiedad,
independientemente de si se defini originalmente como una propiedad almacenada o
calculado.
Definicin de una base de la Clase
Cualquier clase que no hereda de otra clase se conoce como una clase base .
NOTA
Clases Swift no heredan de una clase base universal. Las clases se definen sin
especificar una superclase automticamente convertido clases base para que usted pueda
aprovechar.
153
El ejemplo siguiente define una clase base llamada Vehculo . Esta clase base define
una propiedad almacenado llamado currentspeed , con un valor por defecto
de 0.0 (inferir un tipo de propiedad de doble ). Elcurrentspeed valor de la
propiedad es utilizada por una de slo lectura computarizada Cadena propiedad
llamada descripcin para crear una descripcin del vehculo.
El vehculo de la clase base tambin define un mtodo llamado makeNoise . Este
mtodo no hace nada para una base de vehculo instancia, pero ser personalizado
por subclases de vehculos ms adelante:
class Vehicle {
func makeNoise() {
}
Se crea una nueva instancia de vehculo con la sintaxis de inicializador , que se
escribe como un TypeNameseguida de parntesis vacos:
println("Vehicle: \(someVehicle.description)")
}
El ejemplo siguiente define una subclase llamada de bicicletas , con una
superclase de vehculo :
154
}
La nueva bicicleta de clase gana automticamente todas las caractersticas
del vehculo , tales como suscurrentspeed y descripcin propiedades y
su makeNoise mtodo.
Adems de las caractersticas que hereda, la bicicleta clase define una nueva
propiedad almacenada,hasBasket , con un valor predeterminado de false (inferir
un tipo de Bool para la propiedad).
Por defecto, cualquier nueva bicicleta instancia se crea no tendr una cesta. Puede
configurar el hasBasketpropiedad a true para un
particular, bicicletas instancia despus de crear esa instancia:
bicycle.hasBasket = true
Tambin puede modificar el heredado currentspeed propiedad de
una bicicleta de instancia y consultar heredado de la instancia descripcin de
propiedad:
bicycle.currentSpeed = 15.0
println("Bicycle: \(bicycle.description)")
var currentNumberOfPassengers = 0
}
Tandem hereda todas las propiedades y mtodos de bicicletas , que a su vez
hereda todas las propiedades y mtodos de vehculo . El Tandem subclase tambin
aade una nueva propiedad almacenado llamadocurrentNumberOfPassengers ,
con un valor por defecto de 0 .
Si crea una instancia de Tandem , se puede trabajar con cualquiera de sus propiedades
nuevas y heredadas, y consultar el de slo lectura Descripcin propiedad se hereda
de vehculo :
tandem.hasBasket = true
tandem.currentNumberOfPassengers = 2
tandem.currentSpeed = 22.0
println("Tandem: \(tandem.description)")
155
Anulacin
Una subclase puede proporcionar su propia implementacin personalizada de un mtodo
de instancia, mtodo de clase, propiedad de instancia, propiedad de clase, o subndice
que de otro modo heredar de una superclase. Esto se conoce como primordial .
Para anular una caracterstica que de otro modo se hereda, escribir antes de la definicin
primordial con la override keyword. Si lo hace, aclara que tiene la intencin de
proporcionar una anulacin y no se ha proporcionado una definicin coincidente por
error. Anulacin por accidente puede provocar un comportamiento inesperado, y los
reemplazos sin la anulacin de palabras clave son diagnosticados como un error
cuando se compila el cdigo.
La anulacin de palabras clave tambin solicita al compilador Swift para comprobar
que la superclase de la clase predominante (o uno de sus padres) tiene una declaracin
que coincide con la que nos indic en el aumento al presupuesto. Esta comprobacin
asegura que su definicin primordial es correcta.
Acceso a mtodos de superclase, propiedades y subndices
Cuando usted proporciona un mtodo, propiedad o anulacin subndice para una
subclase, a veces es til usar la aplicacin superclase existentes como parte de su
anulacin. Por ejemplo, se puede refinar el comportamiento de que la aplicacin
existente o almacenar un valor modificado en una variable heredada existente.
Cuando resulte oportuno, se accede a la versin de la superclase de un mtodo, una
propiedad o subndice utilizando el sper prefijo:
Un mtodo reemplazado llamado algunMetodo puede llamar a la versin de la
superclase de algunMetodollamando super.someMethod () dentro de la
implementacin del mtodo de primer orden.
Una propiedad anulado llamado UnaPropiedad puede acceder a la versin de la
superclase deUnaPropiedad como super.someProperty dentro del
captador primordial o aplicacin setter.
Un subndice reemplazado por someIndex puede acceder a la versin de la
superclase del mismo subndice como sper [someIndex] desde dentro de la
aplicacin subndice primordial.
Sustitucin de mtodos
Puede anular un mtodo de instancia o clase heredada para proporcionar una aplicacin
a medida o alternativa del procedimiento dentro de la subclase.
El ejemplo siguiente define una nueva subclase de vehculo llamado tren , lo que
anula el makeNoise mtodo que Train hereda de vehculo :
println("Choo Choo")
}
Si crea una nueva instancia de tren y llamar su makeNoise mtodo, se puede ver
que el tren versin subclase del mtodo se llama:
156
train.makeNoise()
Propiedades Anulacin
Puede reemplazar una instancia o una clase de bienes heredados para proporcionar su
propio getter y setter personalizado para esa propiedad, o para aadir observadores de
propiedad para permitir la propiedad primordial observar cuando los cambios
subyacentes valor de la propiedad.
Anulacin de la propiedad get y set
Puede proporcionar un captador de encargo (y setter, en su caso) para
anular cualquier propiedad heredada, sin importar si la propiedad heredada se
implementa como una propiedad almacenada o calculado en la fuente. La naturaleza
almacenado o calculado de una propiedad heredada no es conocido por una subclaseslo sabe que la propiedad heredada tiene un cierto nombre y tipo. Siempre se debe
indicar el nombre y el tipo de la propiedad est sustituyendo, para permitir que el
compilador para comprobar que su anulacin coincide con una propiedad superclase
con el mismo nombre y tipo.
Usted puede presentar una propiedad de slo lectura hereda como una propiedad de
lectura-escritura, proporcionando tanto un getter y un setter en su propiedad subclase de
anulacin. No puede, sin embargo, presentar una propiedad de lectura y escritura
heredado como una propiedad de slo lectura.
NOTA
Si usted proporciona un setter como parte de una anulacin de la propiedad, tambin
debe proporcionar un captador para que override. Si no desea modificar el valor de la
propiedad heredada dentro del captador primordial, slo tiene que pasar por el valor
heredado devolviendo super.someProperty del captador,
dondeUnaPropiedad es el nombre de la propiedad que est sustituyendo.
El ejemplo siguiente define una nueva clase llamada de coches , que es una subclase
de vehculo . El cocheclase introduce una nueva propiedad almacenado
llamado artes , con un valor entero por defecto de 1 . Elcoche clase tambin anula
la descripcin de propiedad que hereda de vehculo , para proporcionar una
descripcin personalizada que incluye la marcha actual:
var gear = 1
157
car.currentSpeed = 25.0
car.gear = 3
println("Car: \(car.description)")
Los observadores de Propiedad Anulacin
Puede utilizar la propiedad primordial para agregar observadores de propiedad a una
propiedad heredada.Esto permite que se le notifique cuando el valor de un cambio de
propiedad heredadas, independientemente de cmo se implement originalmente esa
propiedad. Para obtener ms informacin sobre los observadores de propiedades,
consulte Observadores de propiedad .
NOTA
No se puede agregar observadores de propiedad de propiedades constantes almacenado
heredadas o propiedades de slo lectura computados heredados. El valor de estas
propiedades no se puede ajustar, por lo que no es apropiada para proporcionar
una willSet o didSet aplicacin como parte de una anulacin.
Tenga en cuenta tambin que no se puede proporcionar tanto un pionero de primer
orden y un observador propiedad primordial de la misma propiedad. Si desea observar
los cambios en el valor de una propiedad, y que ya est proporcionando un setter
personalizado para esa propiedad, slo tiene que observar los cambios de valor del
interior del setter personalizado.
El ejemplo siguiente define una nueva clase llamada AutomaticCar , que es una
subclase de coches . ElAutomaticCar clase representa un coche con cambio
automtico, que selecciona automticamente una velocidad adecuada a utilizar en
funcin de la velocidad actual:
didSet {
158
automatic.currentSpeed = 35.0
println("AutomaticCar: \(automatic.description)")
159
init() {
}
El ejemplo siguiente define una nueva estructura llamada Fahrenheit para
almacenar las temperaturas expresadas en la escala
Fahrenheit. El Fahrenheit estructura tiene una propiedad almacenada, la
temperatura , que es de tipo doble :
struct Fahrenheit {
init() {
temperature = 32.0
var f = Fahrenheit()
160
NOTA
Si una propiedad tiene siempre el mismo valor inicial, proporcionar un valor por defecto
en lugar de establecer un valor dentro de un inicializador. El resultado final es el mismo,
pero el valor predeterminado ata inicializacin de la propiedad ms de cerca a su
declaracin. Se convierte en ms cortos, inicializadores ms claras y le permite inferir el
tipo de la propiedad de su valor original. El valor por defecto tambin hace que sea ms
fcil para que usted tome ventaja de inicializadores por defecto y la herencia de
inicializacin, como se describe ms adelante en este captulo.
Usted puede escribir la Fahrenheit estructura desde arriba en una forma ms simple,
proporcionando un valor predeterminado para su temperatura de propiedad en el
punto de que la propiedad se declara:
struct Fahrenheit {
Personalizacin de inicializacin
Usted puede personalizar el proceso de inicializacin de parmetros de entrada y tipos
de propiedad opcionales, o mediante la modificacin de las propiedades constantes
durante la inicializacin, como se describe en las siguientes secciones.
Parmetros de inicializacin
Usted puede proporcionar los parmetros de inicializacin , como parte de la definicin
de un inicializador, para definir los tipos y los nombres de los valores que personalizan
el proceso de inicializacin. Parmetros de inicializacin tienen las mismas capacidades
y la sintaxis como parmetros de funciones y mtodos.
El ejemplo siguiente define una estructura llamada Celsius , que almacena las
temperaturas expresadas en la escala Celsius. El Celsius estructura implementa dos
inicializadores personalizados denominados init (fromFahrenheit :) y init
(fromKelvin :) , que inicializar una nueva instancia de la estructura con un valor
de una escala de temperatura diferente:
struct Celsius {
// boilingPointOfWater.temperatureInCelsius is 100.0
// freezingPointOfWater.temperatureInCelsius is 0.0
161
struct Color {
self.red = red
self.green = green
self.blue = blue
init(white: Double) {
red = white
green = white
blue = white
}
Ambos inicializadores se pueden utilizar para crear un nuevo color de ejemplo,
proporcionando valores con nombre para cada parmetro de inicializacin:
162
struct Celsius {
temperatureInCelsius = celsius
// BodyTemperature.temperatureInCelsius es 37.0
La llamada inicializador Celsius (37.0) es clara en su intencin, sin la necesidad
de un nombre de parmetro externo. Por tanto, es conveniente escribir este inicializador
como init (_ celsius: Doble) por lo que se puede llamar al proporcionar un
annimo doble valor.
Tipos de Propiedad opcionales
Si su tipo personalizado tiene una propiedad almacenado que se permite lgicamente
tener "ningn valor" -quizs porque su valor no se puede ajustar durante la
inicializacin, o porque se le permite tener "ningn valor" en algn punto ms adelantedeclarar la propiedad con un opcional tipo. Inmuebles del tipo opcional se inicializan
automticamente con un valor de cero , lo que indica que la propiedad est destinado
deliberadamente a tener "ningn valor todava" durante la inicializacin.
El ejemplo siguiente define una clase denominada SurveyQuestion , con un
opcional de cuerda llamada propiedad respuesta :
163
class SurveyQuestion {
init(text: String) {
self.text = text
func ask() {
println(text)
cheeseQuestion.ask()
class SurveyQuestion {
init(text: String) {
self.text = text
func ask() {
println(text)
164
beetsQuestion.ask()
class ShoppingListItem {
var quantity = 1
165
El ejemplo siguiente define una estructura llamada Tamao con dos propiedades
denominadas anchura y altura. Ambas propiedades se infieren a ser de
tipo doble mediante la asignacin de un valor por defecto de 0.0 .
El Tamao estructura recibe automticamente una init (ancho: alto
:) inicializador miembro por miembro, que se puede utilizar para inicializar un
nuevo Tamao ejemplo:
struct Size {
struct Size {
166
struct Point {
}
Puede inicializar el Rect estructura por debajo de una de tres maneras: mediante el uso
de sus defecto cero inicializado- origen y tamao valores de la propiedad,
proporcionando un punto y el tamao de origen especfico, o proporcionando un punto
central especfico y tamao. Estas opciones de inicializacin estn representados por
tres inicializadores personalizadas que forman parte de la Rect definicin de la
estructura:
struct Rect {
init() {}
self.origin = origin
self.size = size
}
La primera Rect inicializador, init () , es funcionalmente lo mismo que el
inicializador por defecto que la estructura habra recibido si no tuviese una fisonoma
propia inicializadores personalizados. Este inicializador tiene un cuerpo vaco,
representado por un par vaco de llaves {} , y no perfom cualquier inicializacin. Al
llamar a este inicializador devuelve un Rect instancia cuyo origen y tamao
de las propiedades se inicializan con los valores por defecto de punto (x: 0.0,
y: 0.0) y Tamao (anchura: 0.0, Altura: 0.0) de sus definiciones de
propiedad:
167
168
init( parameters ) {
statements
}
Inicializadores de Conveniencia estn escritos en el mismo estilo, pero con
la comodidad modificador colocado antes del inicio de palabras clave, separadas
por un espacio:
}
Inicializador encadenamiento
Para simplificar las relaciones entre los inicializadores designados y de conveniencia,
Swift se aplica las siguientes tres reglas para la delegacin de llamadas entre
inicializadores:
Regla
1
Un inicializador designado debe llamar a un inicializador designado de su
superclase inmediata.
Regla
2
Un inicializador de conveniencia debe llamar a otro inicializador de
la misma clase.
Regla
3
Un inicializador de conveniencia debe en ltima instancia, llamar a un
inicializador designado.
Una forma sencilla de recordar esto es:
Inicializadores designados siempre deben delegar para arriba .
Inicializadores de Conveniencia siempre deben delegar en todo .
Estas reglas se ilustran en la siguiente figura:
169
Aqu, la superclase tiene un nico inicializador designado y dos inicializadores de
conveniencia. Un inicializador conveniencia llama a otro inicializador conveniencia,
que a su vez llama a la nica inicializador designado. Esto satisface las reglas 2 y 3 de
arriba. La superclase no en s tiene otros superclase, y lo que la regla 1 no se aplica.
La subclase de esta figura tiene dos inicializadores designados y un inicializador
conveniencia. El inicializador de conveniencia debe llamar a uno de los dos
inicializadores designados, ya que slo puede llamar a otro inicializador de la misma
clase. Esto satisface las reglas 2 y 3 de arriba. Ambos inicializadores designados deben
llamar a la nica inicializador designado de la superclase, para satisfacer a la regla 1
desde arriba.
NOTA
Estas normas no afectan a cmo los usuarios de sus clases crean instancias de cada
clase. Cualquier inicializador en el diagrama anterior se puede utilizar para crear una
instancia de inicializado completamente de la clase al que pertenecen. Las reglas slo
afectan a la forma de escribir la implementacin de la clase.
La siguiente figura muestra una jerarqua de clases ms complejo para cuatro
clases. Ilustra cmo los inicializadores designados en este acto jerarqua como puntos de
"embudo" para la inicializacin de clase, lo que simplifica las relaciones entre las clases
de la cadena:
170
Two-Phase inicializacin
Clase de inicializacin en Swift es un proceso de dos fases. En la primera fase, cada
propiedad almacenado se le asigna un valor inicial de la clase que lo introdujo. Una vez
que el estado inicial de cada propiedad almacenado ha sido determinada, la segunda fase
comienza, y cada clase se le da la oportunidad de personalizar sus propiedades
almacenadas ms antes de considerar la nueva instancia de lista para su uso.
El uso de un proceso de inicializacin de dos fases hace segura la inicializacin,
mientras que todava da flexibilidad completa a cada clase en una jerarqua de
clases. Inicializacin de dos fases impide valores de la propiedad de ser visitada antes
de que se inicializan, y evita los valores de propiedad de ser ajustado a un valor
diferente por otro inicializador inesperadamente.
NOTA
Proceso de inicializacin de dos fases de Swift es similar a la inicializacin en
Objective-C. La principal diferencia es que en la fase 1, Objective-C asigna cero o nulos
valores (como 0 o nulo ) a cada propiedad.Flujo de inicializacin de Swift es ms
flexible ya que permite establecer los valores iniciales de encargo, y puede hacer frente
a tipos a los que 0 o nulo no es un valor predeterminado vlido.
Compilador de Swift realiza cuatro controles de seguridad tiles para asegurarse de que
la inicializacin de dos fases se completa sin errores:
Comprobacin
de
seguridad
1
Un inicializador designado debe asegurar que todas las propiedades introducidas
por su clase se inicializan antes de que los delegados hasta un inicializador
superclase.
171
172
En este ejemplo, la inicializacin comienza con una llamada a un inicializador de
conveniencia en la subclase.Este inicializador conveniencia an no puede modificar las
propiedades. Delegados a travs a un inicializador designado de la misma clase.
El inicializador designado se asegura de que todas las propiedades de la subclase tienen
un valor, segn comprobacin de seguridad 1. A continuacin, llama un inicializador
designado en su superclase para continuar con la inicializacin de la cadena.
Inicializador designado de la superclase se asegura de que todas las propiedades de la
superclase tiene un valor. No hay ms superclases para inicializar, y as no se necesita
una mayor delegacin.
Tan pronto como todas las propiedades de la superclase tienen un valor inicial, su
memoria se considera totalmente inicializado, y la Fase 1 se ha completado.
As es como la fase 2 se ve por la misma llamada de inicializacin:
Inicializador designado de la superclase tiene ahora la oportunidad de personalizar la
instancia ms (aunque no tiene por qu).
Una vez inicializador designado de la superclase se termin, inicializador designado de
la subclase puede realizar una personalizacin adicional (aunque, de nuevo, que no tiene
por qu).
173
class Vehicle {
var numberOfWheels = 0
174
}
El vehculo clase proporciona un valor predeterminado para su propiedad slo
almacenado, y no proporciona ningn s inicializadores personalizados. Como
resultado, recibe automticamente un inicializador por defecto, como se describe
en Inicializadores predeterminados . El inicializador por defecto (si est disponible) es
siempre un inicializador designado para una clase, y se puede utilizar para crear un
nuevo vehculoejemplo con un numberOfWheels de 0 :
println("Vehicle: \(vehicle.description)")
override init() {
super.init()
numberOfWheels = 2
}
La bicycle subclase define un inicializador designado costumbre, init () . Este
inicializador designado coincide con un inicializador designado de la superclase
de bicicletas , por lo que la bicicleta versin de este inicializador est
marcado con el override modificador.
El init () inicializador para bicicletas comienza llamando super.init () ,
que llama al inicializador por defecto para la bicicleta superclase de la
clase, vehculo . Esto asegura que el numberOfWheels propiedad heredada es
inicializado por el vehculo antes de bicicletas tiene la oportunidad de
modificar la propiedad.Despus de llamar a super.init () , el valor original
de numberOfWheels se sustituye con un nuevo valor de 2 .
Si crea una instancia de la bicicleta , puede llamar a su
heredada Descripcin computarizada propiedad para ver cmo
su numberOfWheels propiedad ha sido actualizada:
println("Bicycle: \(bicycle.description)")
175
class Food {
init(name: String) {
self.name = name
convenience init() {
self.init(name: "[Unnamed]")
}
La siguiente figura muestra la cadena de inicializacin para la Alimentacin de
clase:
176
Las clases no tienen un miembro por miembro inicializador por defecto, por lo que
la Food clase proporciona un inicializador designado que toma un solo argumento
llamado nombre . Este inicializador puede ser utilizado para crear un
nuevo Alimentacin instancia con un nombre especfico:
self.quantity = quantity
super.init(name: name)
}
177
La siguiente figura muestra la cadena de inicializacin para
el recipeIngredient clase:
El recipeIngredient clase tiene un nico inicializador designado, init
(name: String, cantidad: Int) , que se puede utilizar para rellenar todas las
propiedades de un nuevo recipeIngredient ejemplo. Este inicializador comienza
asignando el pasado cantidad argumento a la cantidad de propiedad, que es la
nica propiedad nueva introducida por recipeIngredient . Despus de hacerlo,
los delegados de inicializador hasta el init (name: String) inicializador de
la Alimentacin de clase. Este proceso satisface control de seguridad 1 deTwoPhase inicializacin anteriormente.
RecipeIngredient tambin define un inicializador conveniencia, init (name:
String) , que se utiliza para crear un recipeIngredient ejemplo por su nombre
solo. Este inicializador conveniencia asume una cantidad de 1 por
cualquier recipeIngredient instancia que se crea sin una cantidad explcito. La
definicin de este inicializador conveniencia hace recipeIngredient casos ms
rpido y ms conveniente para crear, y evita la duplicacin de cdigo al crear varios de
una sola cantidad recipeIngredient casos. Este inicializador conveniencia
simplemente delegados de todo a inicializador designado de la clase, que pasan en
una cantidad de valor de1 .
El init (name: String) inicializador comodidad proporcionada
por recipeIngredient toma los mismos parmetros que el init (name:
String) designado inicializador de Alimentos . Debido a que este inicializador
conveniencia anula un inicializador designado de su superclase, que debe estar marcado
con la anulacin de modificacin (como se describe en Inicializador Sucesiones y
Anulacin ).
Aunque recipeIngredient ofrece el init (name: String) inicializador
como inicializador conveniencia,recipeIngredient ha proporcionado, sin
embargo, una implementacin de todos los inicializadores designados de su
178
return output
}
NOTA
ShoppingListItem no define un inicializador para proporcionar un valor inicial
para comprar , porque los elementos de una lista de la compra (como modelados aqu)
siempre comienzan unpurchased.
Debido a que proporciona un valor predeterminado para todas las propiedades que
presenta y no define ningn inicializadores s, ShoppingListItem hereda
automticamente todos los inicializadores de conveniencia designados y de su
superclase.
La siguiente figura muestra la cadena global de inicializacin para las tres clases:
179
Puede utilizar los tres de los inicializadores heredados para crear un
nuevo ShoppingListItem ejemplo:
var breakfastList = [
ShoppingListItem(),
ShoppingListItem(name: "Bacon"),
breakfastList[0].purchased = true
println(item.description)
// 1 x Orange juice
// 1 x Bacon
// 6 x Eggs
Aqu, una nueva matriz llamada breakfastList se crea a partir de una matriz que
contiene literal tres nuevosShoppingListItem casos. El tipo de la matriz se deduce
que [ShoppingListItem] . Una vez creada la matriz, el nombre de
la ShoppingListItem al inicio de la matriz se cambia
de "[nombre]" para "Zumo de naranja" y se marca como comprado. Impresin
180
class SomeClass {
required init() {
}
Tambin debe escribir el requerido modificador antes de cada aplicacin subclase
de un inicializador necesario, para indicar que el requisito de inicializacin se aplica a
otras subclases de la cadena. No escribes la anulacin modificador cuando anulando
un inicializador designado requerida:
required init() {
}
NOTA
Usted no tiene que proporcionar una implementacin explcita de un inicializador
necesaria si se puede cumplir con el requisito con un inicializador heredado.
El establecimiento de un defecto Valor de la propiedad con un cierre o la
Funcin
Si el valor predeterminado de una propiedad almacenado requiere algn tipo de
personalizacin o configuracin, puede utilizar un cierre o funcin global para
proporcionar un valor por defecto a medida para esa propiedad. Siempre que una nueva
instancia del tipo que la propiedad pertenece a se inicializa, el cierre o la funcin se
llama, y su valor de retorno se asigna como valor predeterminado de la propiedad.
Este tipo de cierres o funciones suelen crear un valor temporal del mismo tipo que la
propiedad, a medida que valoran para representar el estado inicial deseado, y luego
regresan ese valor temporal que se utilizar como valor predeterminado de la propiedad.
He aqu un esbozo de cmo un esqueleto de cierre puede ser utilizado para proporcionar
un valor de propiedad predeterminado:
class SomeClass {
return someValue
}()
181
}
Tenga en cuenta que extremo de la llave de cierre es seguido por un par de parntesis
vaco. Esto le dice a Swift para ejecutar el cierre inmediato. Si omite estos parntesis,
usted est tratando de asignar el propio cierre a la propiedad, y no el valor de retorno de
la clausura.
NOTA
Si utiliza un cierre para inicializar una propiedad, recuerde que el resto de la instancia
an no se ha inicializado en el punto que se ejecuta el cierre. Esto significa que no se
puede acceder a cualquier otro valor de las propiedades dentro de su cierre, incluso si
esas propiedades tienen valores por defecto. Tampoco se puede utilizar la
implcita auto propiedad, o llamar a cualquiera de los mtodos de la instancia.
El ejemplo siguiente define una estructura llamada de tablero de ajedrez , que
los modelos de un tablero para el juego de Checkers (tambin conocido como Damas ):
El juego de las Damas se juega en un tablero de diez por diez, con cuadrados blancos y
negros alternados.Para representar este tablero de juego, el tablero de
ajedrez estructura tiene una sola propiedad denominada boardColors , que es una
matriz de 100 Bool valores. Un valor de verdad de la matriz representa un cuadrado
negro y un valor de falso representa un cuadrado blanco. El primer elemento de la
matriz representa el cuadrado superior izquierda en el tablero y el ltimo elemento de la
matriz representa el cuadrado inferior derecha en el tablero.
El boardColors matriz se inicializa con un cierre para establecer sus valores de
color:
struct Checkerboard {
for i in 1...10 {
for j in 1...10 {
temporaryBoard.append(isBlack)
182
isBlack = !isBlack
isBlack = !isBlack
return temporaryBoard
}()
}
Cada vez que un nuevo tablero de ajedrez se crea una instancia, el cierre se
ejecuta, y el valor por defecto de boardColors se calcula y se volvi. El cierre en el
ejemplo anterior calcula y establece el color apropiado para cada casilla del tablero en
una matriz temporal llamado temporaryBoard , y devuelve esta matriz temporal
como valor de retorno de la clausura una vez que su configuracin se ha completado. El
valor de la matriz devuelta se almacena en boardColors y se puede consultar con
el squareIsBlackAtRow funcin de utilidad:
// imprime "verdadera"
// imprime "falsa"
Deinicializacin
En esta pgina
A deinitializer se llama inmediatamente antes de que se cancela la asignacin de una
instancia de clase.Usted escribe deinitializers con la deinit palabra clave, similar a
cmo intializers se escriben con el initpalabra clave. Deinitializers slo estn
disponibles en los tipos de clase.
Cmo deinicializacin Obras
Swift desasigna automticamente los casos en los que ya no son necesarios, para liberar
recursos. Swift se encarga de la gestin de memoria de casos a travs de la cuenta de
referencias automtico ( ARC ), como se describe en la cuenta automtica de
referencia . Normalmente no es necesario para llevar a cabo manual de limpieza cuando
se desasignan las instancias. Sin embargo, cuando se est trabajando con sus propios
recursos, es posible que deba realizar alguna limpieza adicional a ti mismo. Por
ejemplo, si crea una clase personalizada para abrir un archivo y escribir algunos datos
en l, es posible que tenga que cerrar el archivo antes de que se cancela la asignacin de
la instancia de clase.
Definiciones de clase pueden tener como mximo un deinitializer por clase. El
deinitializer no toma ningn parmetro y se escribe sin parntesis:
183
deinit {
// Realizar la deinicializacin
}
Deinitializers se denominan de forma automtica, justo antes de desasignacin ejemplo
se lleva a cabo. No se le permite llamar a un deinitializer ti mismo. Deinitializers
superclase son heredados por sus subclases, y la deinitializer superclase se llama
automticamente al final de una aplicacin deinitializer subclase.Deinitializers
superclase siempre se llaman, incluso si una subclase no proporciona su propio
deinitializer.
Debido a que una instancia no se cancela la asignacin hasta despus de su deinitializer
se llama, un deinitializer puede acceder a todas las propiedades de la instancia que se
llama en y puede modificar su comportamiento sobre la base de esas propiedades (tales
como buscar el nombre de un archivo que necesita ser cerrado ).
Deinitializers en Accin
He aqu un ejemplo de un deinitializer en accin. Este ejemplo define dos nuevos
tipos, el Banco y el jugador , para un juego simple. El Banco estructura gestiona
una moneda inventada, que nunca puede tener ms de 10.000 monedas en
circulacin. No puede ser ms que un Banco en el juego, por lo que el Banco se
implementa como una estructura con propiedades y mtodos para almacenar y
administrar su estado actual estticas:
struct Bank {
coinsInBank -= numberOfCoinsToVend
return numberOfCoinsToVend
coinsInBank += coins
}
Bank realiza un seguimiento del nmero actual de monedas que tiene con
su coinsInBank propiedad. Tambin ofrece dos mtodosvendCoins y receiveCoins : para manejar la distribucin y recogida de
monedas.
vendCoins comprueba que hay suficientes monedas en el banco antes de
distribuirlos. Si no hay suficientes monedas, Banco devuelve un nmero menor que el
nmero que se solicit (y devuelve cero si no hay monedas se dejan en el
banco). vendCoins declara numberOfCoinsToVend como un parmetro variable,
de modo que el nmero puede ser modificado dentro del mtodo de cuerpo sin la
necesidad de declarar una nueva variable. Devuelve un valor entero que indique el
nmero real de las monedas que se proporcionaron.
184
class Player {
init(coins: Int) {
coinsInPurse = Bank.vendCoins(coins)
coinsInPurse += Bank.vendCoins(coins)
deinit {
Bank.receiveCoins(coinsInPurse)
}
Cada Player instancia se inicializa con un subsidio inicial de un determinado nmero
de monedas del banco durante la inicializacin, aunque un Player instancia puede
recibir menos de ese nmero, si no hay suficientes monedas estn disponibles.
El player de clase define un winCoins mtodo, que recupera un cierto nmero de
monedas del banco y los agrega a la bolsa del jugador. El player de clase tambin
implementa un deinitializer, que se llama justo antes de un player se desasigna
instancia. Aqu, la deinitializer simplemente devuelve todo de monedas de los jugadores
a la orilla:
185
playerOne!.winCoins(2_000)
playerOne = nil
186
class Person {
init(name: String) {
self.name = name
deinit {
}
La person de clase tiene un inicializador que establece la instancia de name de
propiedad e imprime un mensaje para indicar que la inicializacin est en
marcha. La person de clase tambin tiene un deinitializer que imprime un mensaje
cuando se cancela la asignacin de una instancia de la clase.
El siguiente fragmento de cdigo define tres variables de tipo person? , que se
utilizan para configurar varias referencias a una nueva person instancia en fragmentos
de cdigo siguientes. Debido a que estas variables son de tipo opcional ( person? ,
187
reference2 = reference1
reference3 = reference1
En la actualidad hay tres referencias fuertes a esta nica persona instancia.
Si se rompe dos de estas referencias fuertes (incluyendo la referencia original)
asignando cero a dos de las variables, una sola fuertes vestigios de referencia, y
la persona instancia no se cancela la asignacin:
reference1 = nil
reference2 = nil
ARC no desasigna la persona instancia hasta que se rompe la tercera y ltima
referencia fuerte, momento en el que es evidente que ya no ests usando
la Person ejemplo:
reference3 = nil
188
class Person {
class Apartment {
}
Cada person instancia tiene un nombre de propiedad de tipo Cadena y un
opcional apartament propiedad que es
inicialmente cero . El apartament propiedad es opcional, porque una persona no
siempre puede tener un apartamento.
Del mismo modo, cada apartament instancia tiene un number property de
tipo int y tiene un opcionalinquilino propiedad que es inicialmente cero . La
propiedad es opcional porque el inquilino de un apartamento no siempre puede tener un
inquilino.
Ambas clases tambin definen un deinitializer, que imprime el hecho de que se est
deinitialized una instancia de esa clase. Esto le permite ver si las instancias
de Persona y Apartamento se desasignan como se esperaba.
Este siguiente fragmento de cdigo define dos variables de tipo opcional
llamado juan y number73 , que se establece en un
determinado Apartamento y Persona ejemplo a continuacin. Ambas variables
tienen un valor inicial de cero , en virtud de ser opcional:
189
He aqu cmo las referencias fuertes cuidan de creacin y asignacin de estas dos
instancias. El johnvariable de ahora tiene una fuerte referencia a la
nueva persona instancia, y el number73 variables tiene una fuerte referencia a la
nueva Apartamento ejemplo:
Ahora puede enlazar los dos casos juntos para que la persona tiene un apartamento, y el
apartamento tiene un inquilino. Tenga en cuenta que un signo de exclamacin ( ! se
utiliza para desenvolver y acceder a las instancias almacenadas en el interior
del) john y number73 las variables opcionales, por lo que las propiedades de esos
casos se pueden establecer:
Desafortunadamente, uniendo estos dos casos crea un fuerte ciclo de referencia entre
ellos. La Personaejemplo ahora tiene una fuerte referencia
al Apartamento ejemplo, y el Apartamento instancia tiene una fuerte referencia a
la persona de instancia. Por lo tanto, cuando se rompen las referencias fuertes en
poder de losjohn y number73 las variables, los recuentos de referencias no bajan a
cero, y los casos no se desasignan por ARC:
john = nil
number73 = nil
Tenga en cuenta que ni deinitializer fue llamado al configurar estas dos variables
a cero . El ciclo de referencia fuerte impide que la persona y Apartamento casos
que alguna vez se cancela la asignacin, causando una prdida de memoria en su
aplicacin.
190
Las fuertes referencias entre la persona y la instancia Apartamento instancia
permanecen y no se pueden romper.
Resolver Ciclos de referencia fuertes entre instancias de clase
Swift proporciona dos formas de resolver los ciclos de referencia fuertes cuando se
trabaja con las propiedades de tipo de clase: referencias dbiles y referencias sin dueo.
Referencias dbiles y sin dueo permiten una instancia en un ciclo de referencia para
referirse a la otra instancia y sin mantener un fuerte control sobre el mismo. Los casos
pueden entonces referirse unos a otros sin crear un ciclo de referencia fuerte.
Utilice una referencia dbil siempre que sea vlida para que se convierta en
referencia nula en algn momento durante su vida til. Por el contrario, utilice una
referencia sin dueo cuando se sabe que la referencia nunca ser nula una vez que se
ha establecido durante la inicializacin.
Referencias dbiles
Una referencia dbil es una referencia que no mantiene una fuerte influencia en la
instancia que se refiere, por lo que no deja de ARC de la eliminacin de la instancia de
referencia. Este comportamiento impide que la referencia se conviertan en parte de un
ciclo de referencia fuerte. Usted indica una referencia dbil mediante la colocacin de
la dbil palabra clave antes de una propiedad o declaracin de variables.
Utilice una referencia dbil para evitar los ciclos de referencia, siempre que sea posible
para que la referencia a tener "ningn valor" en algn momento de su vida. Si la
referencia ser siempre tener un valor, utilizar una referencia sin dueo en su lugar,
como se describe en las referencias sin propietario . En el Apartamentoejemplo
anterior, es apropiado para un apartamento para poder tener "ningn inquilino" en algn
momento de su vida til, por lo que una referencia dbil es una forma adecuada para
romper el ciclo de referencia en este caso.
NOTA
Referencias dbiles deben ser declaradas como variables, para indicar que su valor
puede cambiar en tiempo de ejecucin. Una referencia dbil no puede ser declarada
como una constante.
Debido a las referencias dbiles se les permite tener "ningn valor", debe declarar cada
referencia dbil como tener un tipo opcional. Tipos opcionales son la mejor forma de
representar la posibilidad de que "ningn valor" en Swift.
191
Debido a una referencia dbil no mantiene una fuerte influencia en la instancia que se
refiere, es posible que esa instancia para cancelar la asignacin, mientras que la
referencia dbil todava se est refiriendo a la misma. Por lo tanto, ARC establece
automticamente una referencia dbil a cero cuando la instancia que se refiere a que se
cancela la asignacin. Usted puede comprobar la existencia de un valor en la referencia
dbil, al igual que cualquier otro valor opcional, y que nunca va a terminar con una
referencia a una instancia vlida de que ya no existe.
El siguiente ejemplo es idntico al de la persona y Apartamento ejemplo desde
arriba, con una diferencia importante. Esta vez, el Apartamento de
tipo inquilino propiedad se declara como una referencia dbil:
class Person {
class Apartment {
}
Las fuertes referencias de las dos variables ( juan y number73 ) y los vnculos entre
las dos instancias se crean como antes:
john!.apartment = number73
number73!.tenant = john
As es como las referencias se ven ahora que usted ha enlazado las dos instancias a la
vez:
192
La persona instancia todava tiene una fuerte referencia al Apartamento instancia,
pero el Apartamento ejemplo ahora tiene una dbil referencia a la persona de
instancia. Esto significa que cuando se rompe la referencia fuerte en poder de
los john las variables, no hay referencias ms fuertes a la persona ejemplo:
Debido a que no existen referencias ms fuertes a la Persona ejemplo, se cancela la
asignacin:
john = nil
Debido a que no hay ms fuertes referencias al Apartamento ejemplo, tambin lo es
desasignada:
193
number73 = nil
194
class Customer {
init(name: String) {
self.name = name
class CreditCard {
self.number = number
self.customer = customer
}
NOTA
El nmero de propiedad del la tarjeta de crdito de clase se define con un
tipo de UInt64 lugar de Int , para asegurar que el nmero de la capacidad de la
propiedad es lo suficientemente grande como para guardar un nmero de tarjeta de 16
dgitos en ambos sistemas de 32 bits y 64 bits.
Este siguiente fragmento de cdigo define una opcional Cliente variable
llamada John , que se utiliza para almacenar una referencia a un cliente
especfico. Esta variable tiene un valor inicial de cero, en virtud de ser opcional:
195
As es como se ven las referencias, ahora que usted ha enlazado las dos instancias:
El cliente de ejemplo ahora tiene una fuerte referencia a la la tarjeta de
crdito instancia, y el la tarjeta de crdito instancia tiene una referencia
sin dueo al Cliente instancia.
Debido a la unowned cliente de referencia, cuando se rompe la referencia fuerte en
poder del john variables, no hay ms fuertes referencias al Cliente ejemplo:
Debido a que no existen referencias ms fuertes al Cliente ejemplo, se cancela la
asignacin. Despus de esto, no hay ms fuertes referencias al creditcard ejemplo,
y tambin lo es desasignada:
john = nil
196
class Country {
self.name = name
class City {
self.name = name
self.country = country
}
Para configurar la interdependencia entre las dos clases, el inicializador para la
ciudad toma un Pasinstancia, y almacena esta instancia en su pas la propiedad.
El inicializador para la ciudad se llama desde dentro del inicializador de Pas . Sin
embargo, el inicializador dePas no puede pasar a uno mismo a la Ciudad de
197
inicializacin hasta que un nuevo Pas instancia est totalmente inicializado, como se
describe en dos fase de inicializacin .
Para hacer frente a este requisito, se declara la capitalCity propiedad
del pas como una propiedad opcional implcitamente sin envolver, indicado por el
signo de exclamacin al final de su tipo de anotacin ( Ciudad! ).Esto significa que
el capitalCity propiedad tiene un valor por defecto de cero , como cualquier otro
opcional, pero se puede acceder sin necesidad de desenvolver su valor como se describe
en forma implcita Unwrapped Opcionales .
Debido capitalCity tiene un valor predeterminado cero valor, un
nuevo Pas instancia se considera totalmente inicializado tan pronto como
el Pas instancia establece su nombre de la propiedad dentro de su
inicializador.Esto significa que el Pas inicializador puede empezar a referenciar y
pasar alrededor de la implcita autopropiedad tan pronto como el nombre de la
propiedad se establece. El Pas , por lo tanto inicializador puede pasar a uno
mismo como uno de los parmetros para la Ciudad de inicializacin cuando
el Pas inicializador est estableciendo su propio capitalCity propiedad.
Todo esto significa que usted puede crear los Pas y Ciudad casos en una sola
sentencia, sin crear un ciclo de referencia fuerte, y el capitalCity propiedad se
puede acceder directamente, sin necesidad de utilizar un signo de exclamacin a
desenvolver su valor opcional:
198
instancias de clase, esta vez se trata de una instancia de clase y un cierre que se
mantena vivos unos a otros.
Swift ofrece una solucin elegante a este problema, conocido como una lista de captura
de cierre . Sin embargo, antes de aprender cmo romper un ciclo de referencia fuerte
con una lista de captura de cierre, es til para entender cmo un ciclo de este tipo puede
ser causado.
El siguiente ejemplo muestra cmo se puede crear un ciclo de referencia fuerte cuando
se utiliza un cierre que hace referencia a s mismo . Este ejemplo define una clase
llamada HTMLElement , que proporciona un modelo simple para un elemento
individual dentro de un documento HTML:
class HTMLElement {
return "<\(self.name)>\(text)</\(self.name)>"
} else {
self.name = name
self.text = text
deinit {
}
El HTMLElement clase define un nombre de propiedad, lo que indica el nombre del
elemento, como "p" para un elemento de prrafo, o "br" para un elemento de salto de
lnea. HTMLElement tambin define una opcin de texto propiedad, la cual se
puede establecer a un cadena que representa el texto que se dictar dentro de ese
elemento HTML.
Adems de estas dos propiedades simples, la HTMLElement clase define una
propiedad perezoso llamadoasHTML . Esta propiedad hace referencia a un cierre que
199
println(paragraph!.asHTML())
200
Del ejemplo asHTML propiedad se mantiene una fuerte referencia a su cierre. Sin
embargo, debido a que el cierre se refiere a la auto dentro de su cuerpo (como una
forma de referencia self.name y self.text ), el cierre captura auto, lo que
significa que contiene una referencia de nuevo a la fuerte HTMLElement ejemplo. Se
crea un ciclo de referencia fuerte entre los dos. (Para obtener ms informacin acerca de
la captura de los valores en un cierre, consulte Captura de valores .)
NOTA
A pesar de que el cierre se refiere a s mismo varias veces, slo capta una fuerte
referencia a la HTMLElementinstancia.
Si establece el prrafo variable nula y romper su fuerte referencia a
la HTMLElement ejemplo, ni el HTMLElementinstancia ni su cierre se desasignan,
debido al ciclo de referencia fuerte:
prrafo = nil
Tenga en cuenta que el mensaje en el HTMLElement deinitializer no se imprime, lo
que demuestra que laHTMLElement instancia no se cancela la asignacin.
Resolver Ciclos de referencia fuertes para cierres
A resolver un fuerte ciclo de referencia entre un cierre y una instancia de clase
definiendo una lista de capturacomo parte de la definicin de la clausura. Una lista de
captura define las reglas para usar en la captura de uno o ms tipos de referencia dentro
del cuerpo del cierre. Al igual que con fuertes ciclos de referencia entre dos instancias
de la clase, se declara cada referencia capturado para ser una referencia dbil o sin
dueo en lugar de una referencia fuerte. La eleccin adecuada de dbil o sin dueo
depende de las relaciones entre las diferentes partes de su cdigo.
NOTA
Swift requiere que usted escriba self.someProperty o self.someMethod (en
lugar de slo UnaPropiedad oalgunMetodo ) siempre hace referencia a un
miembro del auto dentro de un cierre. Esto le ayudar a recordar que es posible
capturar auto por accidente.
Definicin de una lista de captura
Cada elemento de una lista de captura es un acoplamiento entre el dbil o sin
dueo palabra clave con una referencia a una instancia de clase (por
ejemplo, auto o someInstance ). Estos emparejamientos se escriben dentro de un
par de corchetes, separados por comas.
201
}
Si un cierre no especifica una lista de parmetros o tipo de retorno, ya que pueden ser
inferidos a partir del contexto, coloque la lista de captura en el comienzo del cierre,
seguido por el de palabra clave:
[unowned self] in
}
Referencias dbiles y sin propietario
Definir una captura en un cierre como una referencia sin dueo cuando el cierre y la
instancia de captura siempre referirse unos a otros, y siempre se desasigna al mismo
tiempo.
Por el contrario, definir una captura como una referencia dbil cuando la referencia
capturado puede llegar a ser nula en algn momento en el futuro. Referencias dbiles
son siempre de tipo opcional, y se convierten automticamente a cero cuando se
desasigna la instancia que hacen referencia. Esto le permite comprobar su existencia
dentro del cuerpo del cierre.
NOTA
Si la referencia capturado nunca llegar a ser nula , siempre debe ser capturado como
una referencia sin dueo, en lugar de una referencia dbil.
Una referencia sin dueo es el mtodo de captura apropiado utilizar para resolver el
ciclo de referencia fuerte en el HTMLElement ejemplo de antes. He aqu cmo usted
escribe el HTMLElement clase para evitar el ciclo:
class HTMLElement {
[unowned self] in
return "<\(self.name)>\(text)</\(self.name)>"
} else {
202
self.name = name
self.text = text
deinit {
}
la adicin de una lista de captura dentro de la asHTML cierre. En este caso, la lista de
captura es [auto sin dueo] , que significa "auto captura como una referencia sin
dueo en lugar de una referencia fuerte".
Puede crear e imprimir un HTMLElement ejemplo de antes:
println(paragraph!.asHTML())
Esta vez, la captura de uno mismo por el cierre es una referencia sin dueo, y no
mantiene una fuerte influencia en la HTMLElement instancia que ha capturado. Si
establece la fuerte referencia del prrafo variable en nil , la HTMLElement se
desasigna ejemplo, como se puede ver desde la impresin de su mensaje deinitializer en
el siguiente ejemplo:
paragraph = nil
203
Encadenamiento Opcional
Encadenamiento opcional es un proceso para consultar y llamar a las propiedades,
mtodos y subndices en una opcin que en la actualidad podra ser nula . Si la opcin
contiene un valor, la propiedad, mtodo o llamada subndice tiene xito; si la opcin
es nula , la propiedad, mtodo o llamada subndice retornos nil .Mltiples consultas
pueden ser encadenados juntos, y toda la cadena falla con gracia si cualquier eslabn de
la cadena es nula .
NOTA
Encadenamiento Opcional en Swift es similar a la mensajera nula en Objective-C,
pero de una manera que funcione para cualquier tipo, y que se puede comprobar por el
xito o el fracaso.
El encadenamiento opcional como alternativa a forzado Unwrapping
Se especifica el encadenamiento opcional mediante la colocacin de un signo de
interrogacin ( ? ) tras el valor opcional en la que desea llamar a una propiedad, mtodo
o subndice si el opcional es no nula . Esto es muy similar a la colocacin de un signo
de exclamacin ( ! ) despus de un valor opcional para forzar el desembalaje de su
valor. La principal diferencia es que el encadenamiento opcional falla con gracia cuando
la opcin es nula , mientras que desenvolver forzada provoca un error de ejecucin
cuando el opcional es nula .
Para reflejar el hecho de que el encadenamiento opcional se puede llamar en
un nulo valor, el resultado de una llamada de encadenamiento opcional es siempre un
valor opcional, incluso si la propiedad, mtodo o subndice que est consultando
devuelve un valor que no sea opcional. Puede utilizar este valor de retorno opcional
para comprobar si la llamada encadenamiento opcional fue exitosa (opcional regresado
contiene un valor), o no tuvo xito debido a una nula valor en la cadena (el valor
opcional devuelto es nulo ).
Especficamente, el resultado de una llamada de encadenamiento opcional es del mismo
tipo que el valor de retorno esperado, pero envuelto en una opcional. Una propiedad que
normalmente devuelve un Int devuelve un int? cuando se accede a travs de
encadenamiento opcional.
Los prximos fragmentos de cdigo muestran cmo opcional encadenamiento difiere de
desenvolver forzada y le permite comprobar si hay xito.
En primer lugar, dos clases llamadas Persona y Residencia se definen:
class Person {
class Residence {
var numberOfRooms = 1
}
Residence casos tener un nico int propiedad llamada numberOfRooms , con un
valor predeterminado de 1 .Person casos tienen un opcional residence propiedad
de tipo Residence? .
204
} else {
john.residence = Residence()
john.residence ahora contiene un real Residence ejemplo, en lugar
de cero . Si intenta acceder a numberOfRoomscon el mismo encadenamiento
opcional como antes, ser ahora devolver un int? que contiene el
defectonumberOfRooms valor de 1 :
205
} else {
class Person {
}
La Residencia de clase es ms complejo que antes. Esta vez, la Residencia clase
define una propiedad variable llamada habitaciones , que se inicia con una matriz
vaca de tipo [Sala] :
class Residence {
return rooms.count
get {
return rooms[i]
set {
rooms[i] = newValue
func printNumberOfRooms() {
206
}
Debido a que esta versin de Residencia almacena una matriz de la
habitacin de los casos, sunumberOfRooms propiedad se implementa como una
propiedad calculada, no una propiedad almacenada. El
computarizada numberOfRooms propiedad simplemente devuelve el valor de
la cuenta de la propiedad de lahabitaciones matriz.
Como un atajo para acceder a su habitaciones matriz, esta versin
de Residencia ofrece un subndice de lectura y escritura que da acceso a la
habitacin en el ndice se solicita en la salas de matriz.
Esta versin de Residencia tambin proporciona un mtodo
llamado printNumberOfRooms , que simplemente imprime el nmero de
habitaciones en la residencia.
Por ltimo, Residencia define una propiedad opcional llamado direccin , con
un tipo de direccin? . LaDireccin tipo de clase de esta propiedad se define a
continuacin.
La Sala de clase utilizada para la salas de matriz es una clase simple con una
propiedad llamada nombre , y un inicializador para establecer esa propiedad a un
nombre local adecuado:
class Room {
}
La ltima clase en este modelo se llama Direccin . Esta clase tiene tres propiedades
opcionales del tipo de cuerda? . Las dos primeras
propiedades, buildingName y buildingNumber , son formas alternativas para
identificar a un edificio en particular como parte de una direccin. La tercera
propiedad, calle , se utiliza para nombrar la calle para esa direccin:
class Address {
if buildingName != nil {
return buildingName
return buildingNumber
} else {
return nil
207
}
La Direccin de clase tambin proporciona un mtodo
llamado buildingIdentifier , que tiene un tipo de retorno de la Cadena? . Este
mtodo comprueba las buildingName y buildingNumber propiedades y
devuelvebuildingName si tiene un valor, o buildingNumber si tiene un valor,
o nil si ni la propiedad tiene un valor.
Acceso a las propiedades A travs Opcional encadenamiento
Como se demuestra en Optional Chaining as an Alternative to Forced Unwrapping,
puede utilizar encadenamiento opcional para acceder a una propiedad en un valor
opcional, y para asegurarse de que ese acceso a la propiedad es un xito.
Utilice las clases definidas anteriormente para crear una nueva persona instancia, y
tratar de acceder a sunumberOfRooms propiedad como antes:
} else {
someAddress.buildingNumber = "29"
john.residence?.address = someAddress
En este ejemplo, el intento de establecer la direccin de la propiedad
de john.residence fallar, porquejohn.residence es actualmente nula .
Mtodos A travs de encadenamiento opcional Calling
Usted puede utilizar el encadenamiento opcional para llamar a un mtodo en un valor
opcional, y para comprobar si ese llamado mtodo es exitoso. Usted puede hacer esto
incluso si ese mtodo no define un valor de retorno.
El printNumberOfRooms mtodo en la Residencia de clase imprime el valor
actual de numberOfRooms . As es como se ve el mtodo:
func printNumberOfRooms() {
}
Este mtodo no especifica un tipo de retorno. Sin embargo, las funciones y los mtodos
con ningn tipo de retorno tienen un tipo de retorno implcita de vaco , como se
208
describe en Funciones Sin Valores retornados .Esto significa que devuelven un valor
de () , o una tupla vaca.
Si se llama a este mtodo en un valor opcional con el encadenamiento opcional, tipo de
retorno del mtodo ser Vaco? , no vaco , porque los valores de retorno son
siempre de tipo opcional cuando se invocan mediante el encadenamiento opcional. Esto
le permite utilizar un si declaracin para comprobar si era posible llamar a
la printNumberOfRooms mtodo, a pesar de que el mtodo no define un valor de
retorno. Compare el valor de retorno de las printNumberOfRooms llaman
contra cero para ver si la llamada al mtodo se ha realizado correctamente:
if john.residence?.printNumberOfRooms() != nil {
} else {
} else {
Acceso subndices A travs Opcional encadenamiento
Usted puede utilizar el encadenamiento opcional para tratar de recuperar y establecer un
valor de un subndice en un valor opcional, y para comprobar si esa llamada subndice
tiene xito.
NOTA
Cuando acceda a un subndice en un valor opcional a travs de encadenamiento
opcional, se coloca el signo de interrogacin antes de los apoyos del subndice, no
despus. El signo de interrogacin encadenamiento opcional siempre sigue
inmediatamente despus de la parte de la expresin que es opcional.
El siguiente ejemplo intenta recuperar el nombre de la primera habitacin en la salas
de gama de lajohn.residence establecimiento mediante el subndice definida en
209
} else {
johnsHouse.rooms.append(Room(name: "Kitchen"))
john.residence = johnsHouse
} else {
var testScores = ["Dave": [86, 82, 84], "Bev": [79, 94, 81]]
testScores["Dave"]?[0] = 91
testScores["Bev"]?[0]++
210
testScores["Brian"]?[0] = 72
} else {
211
Tenga en cuenta que en el ejemplo anterior, usted est tratando de recuperar el valor de
la calle de la propiedad. El tipo de esta propiedad es de cuerda? . El valor de
retorno de john.residence? .Address? .streetes, por tanto, tambin de
cuerda? , a pesar de que dos niveles de encadenamiento opcional se aplican adems
del tipo opcional subyacente de la propiedad.
Si establece un real Direccin instancia como valor
para john.residence.address , y establecer un valor real para los de la
direccin de la calle propiedad, se puede acceder al valor de la calle de la
propiedad a travs de encadenamiento opcional multinivel:
john.residence!.address = johnsAddress
} else {
212
if let beginsWithThe =
john.residence?.address?.buildingIdentifier()?.hasPrefix("The") {
if beginsWithThe {
} else {
213
class MediaItem {
init(name: String) {
self.name = name
}
El siguiente fragmento de cdigo define dos subclases de MediaItem . La primera
subclase, Pelcula , encapsula informacin adicional acerca de una pelcula o una
pelcula. Se aade un director propiedad en la parte superior de la
base MediaItem clase, con un inicializador correspondiente. La segunda
subclase, Cancin, aade un artista propiedad y inicializador en la parte superior
de la clase base:
self.director = director
super.init(name: name)
self.artist = artist
super.init(name: name)
}
El fragmento final, crea una matriz constante llamada biblioteca , que contiene
dos pelculas instancias y tres canciones casos. El tipo de
la biblioteca matriz se infiere por la inicializacin con el contenido de un literal de
matriz. Tipo ortogrfico de Swift es capaz de deducir que la pelcula y la
cancin tiene una superclase comn de MediaItem , y por lo que infiere un tipo
de [MediaItem] para la biblioteca de matriz:
let library = [
var movieCount = 0
var songCount = 0
if item is Movie {
++movieCount
++songCount
215
216
Downcasting a Movie falla cuando se aplica a las dos canciones instancias del array
biblioteca. Para hacer frente a esto, el ejemplo anterior utiliza opcional de unin para
comprobar si la opcin Movie realidad contiene un valor (es decir, para saber si los
abatidos sucedi.) Esta unin se escribe "opcional artculo si dejar que la
pelcula = as? Pelcula ", que se puede leer como:
"Trate de acceder tema como Pelcula . Si esto tiene xito, establecer una nueva
constante temporal denominada pelcula con el valor almacenado en la opcin de
regresar Movie ".
Si el downcasting tiene xito, las propiedades de la pelcula se utilizan para
imprimir una descripcin de eseMovie ejemplo, incluyendo el nombre de
su director . Un principio similar se utiliza para comprobar si haycancin de los
casos, y para imprimir una descripcin apropiada (incluyendo artista nombre)
siempre que una cancin se encuentra en la biblioteca.
NOTA
Fundicin en realidad no modificar la instancia o cambiar sus valores. La instancia
subyacente sigue siendo el mismo; simplemente se trata y se accede como una instancia
del tipo al que se ha fundido.
Escriba Casting para Todas y AnyObject
Swift proporciona dos alias de tipo especial para trabajar con tipos no especficos:
AnyObject puede representar una instancia de cualquier tipo de clase.
Cualquier puede representar una instancia de cualquier tipo en absoluto, aparte
de los tipos de funcin.
NOTA
Utilice Cualquier y AnyObject slo cuando se necesita explcitamente el
comportamiento y las capacidades que proporcionan. Siempre es mejor ser especfico
acerca de los tipos que se pueden esperar para trabajar con en el cdigo.
AnyObject
Al trabajar con las API de cacao, es comn recibir una matriz con un tipo
de [AnyObject] , o "una matriz de valores de cualquier tipo de objeto". Esto se debe
a Objective-C no tiene matrices con tipo de forma explcita.Sin embargo, a menudo se
puede estar seguro sobre el tipo de los objetos contenidos en una gama tan slo de la
informacin que tiene sobre la API que proporciona la matriz.
En estas situaciones, puede utilizar la versin forzada del operador de conversin de
tipos ( como ) al abatido cada elemento de la matriz a un tipo de clase ms especfica
que AnyObject , sin la necesidad de desenvolver opcional.
El ejemplo siguiente define una matriz de tipo [AnyObject] y rellena esta matriz con
tres instancias de lapelcula de clase:
]
Debido a que esta variedad se sabe que contiene slo la pelcula de los casos,
usted puede abatido y desenvolver directamente a un no opcional Pelcula con la
versin forzada del operador de conversin de tipos ( como ):
217
things.append(0)
things.append(0.0)
things.append(42)
things.append(3.14159)
things.append("hello")
things.append((3.0, 5.0))
218
switch thing {
case 0 as Int:
println("zero as an Int")
case 0 as Double:
println("zero as a Double")
case is Double:
default:
println("something else")
// Un valor entero de 42
219
Tipos anidados
Las enumeraciones son creadas a menudo para apoyar a una clase especfica o la
funcionalidad de la estructura. Del mismo modo, puede ser conveniente definir clases y
estructuras de utilidad puramente para su uso en el contexto de un tipo ms
complejo. Para lograr esto, Swift le permite definir tipos anidados , por el que usted
nido apoyar las enumeraciones, las clases y las estructuras dentro de la definicin del
tipo que soportan.
Para anidar un tipo dentro de otro tipo, escribir su definicin dentro de las llaves
externas del tipo que soporta.Los tipos pueden ser anidados a tantos niveles como son
obligatorios.
Tipos anidados en Accin
El ejemplo siguiente define una estructura llamada BlackjackCard , que modela una
tarjeta de juego tal como se utiliza en el juego de Blackjack. El BlackJack estructura
contiene dos tipos de enumeracin anidados llamados Traje y Rango .
En el Blackjack, las cartas Ace tienen un valor de uno u once. Esta caracterstica est
representada por una estructura llamada Valores , que est anidado dentro
del rango de enumeracin:
struct BlackjackCard {
case Two = 2, Three, Four, Five, Six, Seven, Eight, Nine, Ten
struct Values {
switch self {
case .Ace:
default:
return output
}
El suit enumeracin describe los cuatro juegos de la tarjeta de juego comunes, junto
con una prima de caracteres valor para representar a su smbolo.
El rango de enumeracin describe las trece posibles filas de tarjetas de juego, junto
con una prima Int valor para representar a su valor nominal. (Esta prima Int valor no
se utiliza para la Jota, Reina, Rey y As de tarjetas.)
Como se mencion anteriormente, el rango de enumeracin define una estructura
anidada adicional de sus propios, llamados valores . Esta estructura encapsula el
hecho de que la mayora de las tarjetas tienen un valor, pero la tarjeta Ace tiene dos
valores. El Valores estructura define dos propiedades para representar esto:
primero , de tipo Int
segundo , de tipo Int? , o "opcional Int "
Rango tambin define una propiedad calculada, valores , que devuelve una
instancia de la Valores estructura.Esta propiedad computarizada considera el rango
de la tarjeta y se inicializa un nuevo Valores instancia con los valores adecuados en
funcin de su rango. Utiliza valores especiales para Jack , Reina , Rey y As . Para
las tarjetas numricas, utiliza prima del rango Int valor.
El BlackjackCard estructura en s tiene dos propiedades- rango y suit. Tambin
define una propiedad calculada denominada descripcin , que utiliza los valores
almacenados en rango y suit para construir una descripcin del nombre y el valor
de la tarjeta. La descripcin de propiedad utiliza opcional vinculante para
comprobar si hay un segundo valor a mostrar, y si es as, inserta descripcin adicional
detallada para ese segundo valor.
Debido BlackjackCard es una estructura sin inicializadores personalizados, tiene un
inicializador implcito miembro por miembro, como se describe en miembro por
miembro Inicializadores de Estructura Tipos . Usted puede utilizar este inicializador
para inicializar una nueva constante llamados theAceOfSpades :
221
println("theAceOfSpades: \(theAceOfSpades.description)")
//
HeartsSymbol
es
""
Para el ejemplo anterior, esto permite que los nombres
de Traje , Rango y valores que se mantiene deliberadamente corto, porque sus
nombres son, naturalmente, calificados por el contexto en el que se definen.
Extensiones
Extensiones de aadir nueva funcionalidad a una clase, estructura o tipo de enumeracin
existente. Esto incluye la capacidad de ampliar los tipos para los que no tiene acceso al
cdigo fuente original (conocido como el modelado retroactiva ). Las extensiones son
similares a categoras en Objective-C. (A diferencia de las categoras de Objective-C,
extensiones Swift no tienen nombres.)
Extensiones en Swift puede:
Agregar propiedades calculadas y propiedades estticas calculadas
Definir los mtodos de instancia y mtodos de tipo
Proporcionar nuevos inicializadores
Definir subndices
Definir y utilizar nuevos tipos anidados
Haz un tipo existente se ajusta a un protocolo
NOTA
Las extensiones pueden aadir nuevas funcionalidades a un tipo, pero no pueden
reemplazar la funcionalidad existente.
Sintaxis Extensin
Declarar extensiones con la extensin de la palabra clave:
extension SomeType {
}
Una extensin puede extender un tipo existente para que adopte uno o ms
protocolos. Cuando este es el caso, los nombres de protocolo se escriben exactamente
de la misma manera que para una clase o estructura:
}
Adicin de conformidad protocolo de esta manera se describe en Aadiendo Protocolo
de Conformidad con una extensin .
NOTA
Si se define una extensin para agregar nueva funcionalidad a un tipo existente, la
nueva funcionalidad estar disponible en todas las instancias existentes de ese tipo,
incluso si se hubieran creado antes se defini la extensin.
Propiedades calculadas
Las extensiones pueden aadir propiedades de instancia calculados y propiedades de
tipo calculados a los tipos existentes. Este ejemplo aade cinco propiedades de la
instancia computarizada para incorporado de Swift doble tipo, para proporcionar
soporte bsico para trabajar con unidades de distancia:
extension Double {
223
Estas propiedades se calcula las propiedades de slo lectura, por lo que se expresan sin
el get palabra clave, por razones de brevedad. Su valor de retorno es de tipo doble , y
se puede utilizar en clculos matemticos, cuando ese doble se acepta:
struct Size {
struct Point {
struct Rect {
224
Debido a que el Rect estructura proporciona valores predeterminados para todas sus
propiedades, que recibe un inicializador por defecto y un inicializador de miembro por
miembro automticamente, como se describe enInicializadores predeterminados . Estos
inicializadores pueden ser utilizados para crear nuevas Rect casos:
extension Rect {
}
Este nuevo inicializador comienza calculando un punto de origen adecuado en funcin
de la proporcionadacentro punto y tamao valor. El inicializador luego llama de la
estructura automtica inicializador miembro por miembro init (origen: tamao
:) , que almacena los nuevos valores de origen y tamao en las propiedades adecuadas:
extension Int {
for i in 0..<self {
task()
225
3.repetitions({
println("Hello!")
})
// Hola!
// Hola!
// Hola!
Utilice arrastrando sintaxis de cierre para realizar la llamada ms sucinta:
3.repetitions {
println("Goodbye!")
// Adis!
// Adis!
// Adis!
Mutando Mtodos de instancia
Los mtodos de instancia aaden con una extensin tambin se puede modificar
(o mutar ) la propia instancia. Estructura y mtodos de enumeracin que modifican uno
mismo o sus propiedades deben marcar el mtodo de instancia como la mutacin ,
al igual que la mutacin de los mtodos de una implementacin original.
El ejemplo siguiente aade un nuevo mtodo mutante llamada plaza de
Swift Int tipo, que las plazas del valor original:
extension Int {
var someInt = 3
someInt.square()
// SomeInt es ahora 9
Los subndices
Las extensiones pueden aadir nuevos subndices para un tipo existente. En este
ejemplo se agrega un subndice entero a built-in de Swift Int tipo. Este
subndice [n] devuelve los dgitos decimales n en lugares de la derecha del nmero:
123456789 [0] devuelve 9
123456789 [1] devuelve 8
226
... Etctera:
extension Int {
var decimalBase = 1
decimalBase *= 10
--digitIndex
746381295[0]
// returns 5
746381295[1]
// returns 9
746381295[2]
// returns 2
746381295[8]
// returns 7
Si el Int valor no tiene suficientes dgitos para el ndice solicitado, la aplicacin
devuelve el subndice 0 , como si el nmero haba sido rellenado con ceros a la
izquierda:
746381295 [ 9 ]
0746381295 [ 9 ]
Tipos anidados
Las extensiones pueden aadir nuevos tipos anidados a clases, estructuras y
enumeraciones existentes:
extension Int {
enum Kind {
switch self {
case 0:
return .Zero
227
return .Positive
default:
return .Negative
}
En este ejemplo se agrega una nueva enumeracin anidada a Int . Esta enumeracin,
llamado Kind , expresa el tipo de nmero que un nmero entero particular
representa. Especficamente, expresa si el nmero es negativo, cero o positivo.
Este ejemplo tambin aade una nueva propiedad calculada instancia para Int ,
llamado tipo , que devuelve el apropiado Kind miembro de la enumeracin de ese
entero.
La enumeracin anidada ahora se puede utilizar con cualquier Int valor:
switch number.kind {
case .Negative:
print("- ")
case .Zero:
print("0 ")
case .Positive:
print("+ ")
print("\n")
228
Protocolos
Un protocolo define un plano de los mtodos, propiedades y otros requisitos que se
adapten a una tarea o un pedazo de funcionalidad particular. El protocolo no
proporciona realmente una implementacin de cualquiera de estos requisitos, que slo
describe lo que una aplicacin se ver as. El protocolo puede ser adoptado por una
clase, estructura o enumeracin para proporcionar una implementacin real de esos
requisitos. Cualquier tipo que satisfaga los requisitos de un protocolo se dice
que conforme a dicho protocolo.
Los protocolos pueden requerir que se ajusten tipos tienen propiedades especficas
ejemplo, los mtodos ejemplo, los mtodos de tipo, operadores y subndices.
Sintaxis Protocolo
Usted define los protocolos de una manera muy similar a las clases, estructuras y
enumeraciones:
protocol SomeProtocol {
}
Tipos personalizados afirman que adopten un protocolo particular poniendo el nombre
del protocolo despus del nombre del tipo, separados por dos puntos, como parte de su
definicin. Protocolos pueden aparecer mltiples, y estn separadas por comas:
}
Si una clase tiene una superclase, anote el nombre de la superclase antes de cualquier
protocolo de que adopte, seguido de una coma:
AnotherProtocol {
}
Requisitos de Propiedad
Un protocolo puede requerir cualquier tipo conforme a proporcionar una propiedad de
instancia o tipo de propiedad con un nombre y un tipo particular. El protocolo no
especifica si la propiedad debe ser una propiedad almacenado o una computadopropiedad slo especifica el nombre de la propiedad requerida y el tipo. El protocolo
tambin especifica si cada propiedad debe ser gettable o gettable y ajustable.
Si un protocolo requiere una propiedad de ser obtenibles y configurable, que el requisito
de propiedad no puede ser satisfecha por una propiedad almacenada constante o una
propiedad calculada de slo lectura. Si el protocolo slo requiere de una propiedad para
ser gettable, el requisito puede cumplirse mediante cualquier tipo de propiedad, y es
vlida para la propiedad de ser tambin ajustable si esto es til para su propio cdigo.
Requisitos de propiedad siempre se declaran como propiedades de las variables, el
prefijo de la var palabra clave. Propiedades getTable y ajustables se indican por
229
protocol SomeProtocol {
}
Siempre requisitos de propiedades de tipo prefijo con la clase de palabras clave
cuando se defina en un protocolo. Esta norma se refiere a pesar de que los requisitos de
propiedades de tipo van precedidos de laesttica palabra clave cuando se
implementa una estructura o enumeracin:
protocol AnotherProtocol {
}
He aqu un ejemplo de un protocolo con un solo requisito de propiedad de instancia:
protocol FullyNamed {
}
El FullyNamed protocolo requiere un tipo de conformacin para proporcionar un
nombre totalmente calificado.El protocolo no especifica nada acerca de la naturaleza del
tipo de conformacin-slo especifica que el tipo debe ser capaz de proporcionar el
nombre completo por s mismo. El protocolo establece que cualquierFullyNamed tipo
debe tener una propiedad de instancia denominada gettable fullName , que es del
tipo de cuerda .
He aqu un ejemplo de una estructura simple que adopta y se ajusta a
la FullyNamed protocolo:
self.name = name
self.prefix = prefix
protocolo SomeProtocol {
}
El ejemplo siguiente define un protocolo con un solo requisito mtodo de instancia:
protocol SomeProtocol {
}
Este protocolo, RandomNumberGenerator , requiere ningn tipo de ajuste a tener
un mtodo de instancia denominado aleatorio , que devuelve un doble valor cada
vez que se le llama. Aunque no se especifica como parte del protocolo, se supone que
este valor ser un nmero desde 0,0 hasta (pero no incluyendo) 1.0 .
231
let m = 139968.0
let a = 3877.0
let c = 29573.0
lastRandom = ((lastRandom * a + c) % m)
return lastRandom / m
232
la toggle mtodo est pensado para cambiar o invertir el estado de cualquier tipo de
conformacin, por lo general mediante la modificacin de una propiedad de ese tipo.
La toggle mtodo est marcado con el mutando palabra clave como parte de
la togglable definicin de protocolo, para indicar que se espera que el mtodo para
mutar el estado de una instancia conforme cuando se le llama:
protocol Togglable {
}
Si implementa la togglable protocolo para una estructura o enumeracin, que
estructura o enumeracin pueden ajustarse al protocolo al proporcionar una
implementacin de la palanca mtodo que tambin se marca como mutando .
El ejemplo siguiente define una enumeracin denominada OnOffSwitch . Esta
enumeracin alterna entre dos estados, indicados por los casos de
enumeracin On y Off . La enumeracin de toggle aplicacin se marca
como mutante , para que coincida con la togglable requisitos de protocolo:
case Off, On
switch self {
case Off:
self = On
case On:
self = Off
lightSwitch.toggle()
protocol SomeProtocol {
init(someParameter: Int)
233
}
El uso del required modificador garantiza que usted proporciona una
implementacin explcita o heredada del requisito de inicializacin de todas las
subclases de la clase de conformacin, de tal manera que tambin cumplen con el
protocolo.
Para obtener ms informacin sobre los inicializadores necesarios,
consulte Inicializadores obligatorios .
NOTA
No es necesario marcar las implementaciones de inicializador protocolo con
la required modificador sobre las clases que estn marcados con
el ltimo modificador, porque las clases finales no pueden ser subclases. Para ms
informacin sobre el ltimo modificador, consulte Prevencin de anulaciones .
Si una subclase sobreescribe un inicializador designado de una superclase, y tambin
implementa un requisito inicializador juego de un protocolo, marque la aplicacin
inicializador tanto con los requeridos yanular modificadores:
protocol SomeProtocol {
init()
class SomeSuperClass {
init() {
234
class Dice {
self.sides = sides
self.generator = generator
}
En este ejemplo se define una nueva clase llamada dados , lo que representa un n sided dados para su uso en un juego de mesa. Dados los casos tienen una propiedad de
entero llamado lados , lo que representa el nmero de lados que tienen, y una
propiedad llamada generador , que proporciona un azar generador de nmeros desde
el que crear los valores dados.
El generador de la propiedad es de tipo RandomNumberGenerator . Por lo
tanto, usted puede configurarlo para que una instancia de cualquier tipo que adopta
el RandomNumberGenerator protocolo. Nada ms se requiere de la instancia que
se asigna a esta propiedad, a excepcin de que la instancia debe adoptar
elRandomNumberGenerator protocolo.
Dados tambin tiene un inicializador, para establecer su estado inicial. Este
inicializador tiene un parmetro llamado generador , que tambin es de
tipo RandomNumberGenerator . Puede pasar un valor de cualquier tipo de
conformacin en este parmetro cuando se inicializa un nuevo Dados instancia.
Dados proporciona un mtodo de instancia, rodillo , que devuelve un valor entero
entre 1 y el nmero de lados de los dados. Este mtodo llama del
generador aleatorio mtodo para crear un nuevo nmero aleatorio
235
entre 0,0 y 1,0 , y utiliza este nmero aleatorio para crear un valor tirada de los dados
dentro del rango correcto. Debido a que el generador se conoce a
adoptar RandomNumberGenerator , es la garanta de tener unazar mtodo a
llamar.
As es como el de los dados clase se puede utilizar para crear un dado de seis caras
con unLinearCongruentialGenerator instancia como su generador de
nmeros aleatorios:
for _ in 1...5 {
Delegacin
Delegacin es un patrn de diseo que permite a una clase o estructura en mano fuera
(o delegado ) algunas de sus responsabilidades a una instancia de otro tipo. Este patrn
de diseo se implementa mediante la definicin de un protocolo que encapsula las
responsabilidades delegadas, de tal manera que un tipo de conformacin (conocida
como delegado) est garantizado para proporcionar la funcionalidad que ha sido
delegada. Delegacin se puede utilizar para responder a una accin en particular, o para
recuperar datos de una fuente externa sin necesidad de conocer el tipo subyacente de esa
fuente.
El siguiente ejemplo define dos protocolos para el uso con los dados basados en juegos
de mesa:
protocol DiceGame {
func play()
protocol DiceGameDelegate {
}
El DiceGame protocolo es un protocolo que puede ser adoptado por cualquier juego
que consiste en dados. ElDiceGameDelegate protocolo puede ser adoptado por
cualquier tipo para seguir el progreso de un DiceGame .
236
Aqu hay una versin del juego de la oca juego introducido originalmente en control de
flujo . Esta versin est adaptada para utilizar un Dados ejemplo para sus dados
rollos; adoptar el DiceGame protocolo; y para notificar a
un DiceGameDelegate sobre su progreso:
let finalSquare = 25
var square = 0
init() {
func play() {
square = 0
delegate?.gameDidStart(self)
case finalSquare:
break gameLoop
continue gameLoop
default:
square += diceRoll
square += board[square]
delegate?.gameDidEnd(self)
}
Para una descripcin de la Serpientes y Escaleras juego, ver la rotura seccin
del control de flujo captulo.
Esta versin del juego est envuelto en una clase llamada SnakesAndLadders , que
adopta la DiceGameprotocolo. Proporciona una gettable dados propiedad y
237
var numberOfTurns = 0
numberOfTurns = 0
if game is SnakesAndLadders {
++numberOfTurns
println("Rolled a \(diceRoll)")
238
game.delegate = tracker
game.play()
// Laminado a 3
// Laminado a 5
// Laminado un 4
// Laminado a 5
239
protocol TextRepresentable {
}
The Dice class from earlier can be extended to adopt and conform
to TextRepresentable:
}
Esta extensin adopta el nuevo protocolo exactamente de la misma manera que
si Dados haba proporcionado en su implementacin original. El nombre del protocolo
se proporciona despus el nombre del tipo, separados por dos puntos, y una puesta en
prctica de todos los requisitos del protocolo se proporciona dentro de llaves de la
extensin.
Cualquier Dados ejemplo ahora se puede tratar como TextRepresentable :
println(d12.asText())
println(game.asText())
Declarando Adopcin Protocolo con una extensin
Si un tipo que ya cumple con todos los requisitos de un protocolo, pero an no ha
declarado que adopta ese protocolo, puede hacer que apruebe el protocolo con una
extensin vaca:
struct Hamster {
240
println(somethingTextRepresentable.asText())
println(thing.asText())
// un dado de 12 lados
}
He aqu un ejemplo de un protocolo que hereda el TextRepresentable protocolo
desde arriba:
241
}
En este ejemplo se define un nuevo protocolo, PrettyTextRepresentable , que
hereda de TextRepresentable .Cualquier cosa que
adopta PrettyTextRepresentable debe satisfacer todos los requisitos impuestos
porTextRepresentable , adems de los requisitos adicionales impuestos
por PrettyTextRepresentable . En este
ejemplo, PrettyTextRepresentable aade un nico requisito de proporcionar
un mtodo de instancia denominado asPrettyText que devuelve una Cadena .
El SnakesAndLadders clase se puede extender a adoptar y cumplir
con PrettyTextRepresentable :
switch board[index] {
default:
return output
}
Esta extensin indica que adopta la PrettyTextRepresentable protocolo y
proporciona una implementacin de la asPrettyText mtodo para
la SnakesAndLadders tipo. Cualquier cosa que
es PrettyTextRepresentable tambin debe ser TextRepresentable , por
lo que el asPrettyText aplicacin comienza llamando la AsText mtodo
delTextRepresentable protocolo para iniciar una cadena de salida. Se aade dos
puntos y un salto de lnea, y utiliza esto como el inicio de su representacin de texto
bastante. A continuacin, itera a travs de la serie de casillas del tablero, y anexa una
forma geomtrica para representar el contenido de cada cuadrado:
Si el valor del cuadrado es mayor que 0 , es la base de una escalera, y est
representado por .
Si el valor del cuadrado es inferior a 0 , que es la cabeza de una serpiente, y est
representado por .
242
println(game.asPrettyText())
//
Protocolos-Class Slo
Puede limitar la adopcin del protocolo de tipos de clase (y no a las estructuras o
enumeraciones) mediante la adicin de la clase de palabras clave a la lista de la
herencia de un protocolo. La clase de palabras clave siempre debe aparecer primero
en la lista de la herencia de un protocolo, antes de que los protocolos heredados:
}
En el ejemplo anterior, SomeClassOnlyProtocol slo puede ser adoptada por los
tipos de clase. Se trata de un error de tiempo de compilacin para escribir una definicin
de estructura o enumeracin que intenta adoptarSomeClassOnlyProtocol .
NOTA
Utilice un protocolo de clase slo cuando el comportamiento definido por los requisitos
de ese protocolo supone o exige que un tipo de conformacin tiene una semntica de
referencia en lugar de la semntica de valor. Para ms informacin sobre referencia y
valor semntico, ver estructuras y enumeraciones son tipos de valor y las clases son
tipos de referencia .
Protocolo de Composicin
Puede ser til exigir un tipo de ajustarse a mltiples protocolos a la vez. Se pueden
combinar varios protocolos en un nico requisito con una composicin
protocolo . Composiciones Protocolo tienen la forma de protocolo
<SomeProtocol, AnotherProtocol> . Usted puede enumerar tantos
protocolos dentro del par de corchetes angulares ( <> ) como necesite, separados por
comas.
He aqu un ejemplo que combina dos protocolos llamados con
nombre y envejecido en un nico requisito composicin protocolo en un
parmetro de la funcin:
protocol Named {
protocol Aged {
wishHappyBirthday(birthdayPerson)
}
NOTA
244
Puede comprobar el cumplimiento del protocolo slo si el protocolo est marcado con
el objc atributo, como se ve por la HasArea protocolo anterior. Este atributo indica
que el protocolo debe ser expuesto al cdigo de Objective-C y se describe en Uso de
Swift con Cocoa y Objective-C . Incluso si usted no est interoperar con Objective-C,
tiene que marcar sus protocolos con el objc atributo si quieres ser capaz de verificar la
conformidad del protocolo.
Tenga en cuenta tambin que los objc protocolos pueden ser adoptadas por las clases,
y no por estructuras o enumeraciones. Si marca el protocolo como objc con el fin de
comprobar la conformidad, usted ser capaz de aplicar ese protocolo slo para tipos de
clase.
Aqu hay dos clases, Circle y Pas , las cuales se ajustan a la HasArea protocolo:
let pi = 3.1415927
}
El Crculo clase implementa el rea requisito de propiedad como una propiedad
calculada, en base a un almacenada radio de propiedad. El Pas clase implementa
el rea requerimiento directamente como una propiedad almacenada. Ambas clases se
ajustan correctamente a la HasArea protocolo.
Aqu hay una clase llamada Animal , que no se ajusta a la HasArea protocolo:
class Animal {
}
Los Circle , Pas y animales clases no tienen una clase base comn. No obstante,
son todas las clases, y por lo tanto los casos de los tres tipos pueden utilizarse para
inicializar una matriz que almacena valores de tipoAnyObject :
Circle(radius: 2.0),
Country(area: 243_610),
Animal(legs: 4)
]
El objeto array se inicializa con un literal de matriz que contiene
un crculo instancia con un radio de 2 unidades; un Pas instancia inicializada con
245
println("Area is \(objectWithArea.area)")
} else {
// Area es 12.5663708
// Area es 243610.0
246
Tenga en cuenta tambin que los objc protocolos pueden ser adoptadas por las clases,
y no por estructuras o enumeraciones. Si marca el protocolo como objc con el fin de
especificar los requisitos opcionales, slo ser capaz de aplicar ese protocolo para tipos
de clase.
El ejemplo siguiente define una clase entera de conteo llamado Contador , que utiliza
una fuente de datos externa para proporcionar a su importe mnimo de la subasta. Esta
fuente de datos se define por laCounterDataSource protocolo, que tiene dos
requisitos opcionales:
}
El CounterDataSource protocolo define un requisito mtodo opcional
llamado incrementForCount y un requisito de propiedad opcional
llamado fixedIncrement . Estos requisitos definen dos maneras diferentes para
fuentes de datos para proporcionar una cantidad de incremento apropiado para
un contador de instancia.
NOTA
En rigor, se puede escribir una clase personalizada que se ajuste
a CounterDataSource sin implementar ya sea requisito protocolo. Ellos son ambos
opcionales, despus de todo. Aunque tcnicamente permitido, esto no hara por una muy
buena fuente de datos.
El contador de la clase, se define a continuacin, tiene un
opcional dataSource propiedad de tipoCounterDataSource? :
var count = 0
func increment() {
count += amount
count += amount
}
El contador de la clase almacena su valor actual en una propiedad variable
llamada count . El contador de la clase tambin define un mtodo llamado de
incremento , lo que incrementa el recuento de propiedad cada vez que se llama
al mtodo.
El incremento mtodo primero intenta recuperar un importe mnimo de la subasta
mediante la bsqueda de una implementacin de la incrementForCount mtodo en
su origen de datos. El incremento mtodo utiliza el encadenamiento opcional para
247
let fixedIncrement = 3
}
Puede utilizar una instancia de ThreeSource como origen de datos para un
nuevo contador ejemplo:
counter.dataSource = ThreeSource()
for _ in 1...4 {
counter.increment()
println(counter.count)
}
248
// 3
// 6
// 9
//
12
El cdigo anterior crea un nuevo contador de instancia; establece su fuente de datos
para ser un nuevoThreeSource instancia; y pide del contador incremento mtodo
de cuatro veces. Como era de esperar, el contador count propiedad aumenta por tres
cada vez que la subasta se llama.
He aqu una fuente de datos ms compleja llamada TowardsZeroSource , lo que
hace un contador de instancia contar hacia arriba o hacia abajo a cero de su
actual cuenta de valor:
if count == 0 {
return 0
return 1
} else {
return -1
}
El TowardsZeroSource clase implementa la
opcional incrementForCount mtodo del CounterDataSource protocolo y
utiliza el conteo valor del argumento de averiguar qu direccin para contar.
Si cuenta ya es cero, el mtodo devuelve 0 para indicar que no hay ms de conteo
debe tener lugar.
Puede utilizar una instancia de TowardsZeroSource con el
vigente Contador instancia a contar desde -4 a cero.Una vez que el contador llegue a
cero, no ms de conteo se lleva a cabo:
counter.count = -4
counter.dataSource = TowardsZeroSource()
for _ in 1...5 {
counter.increment()
println(counter.count)
// -3
// -2
//
-1
249
// 0
//
0
Genricos
Cdigo genrico le permite escribir, funciones flexibles reutilizables y tipos que pueden
trabajar con cualquier tipo, con sujecin a los requisitos que se definan. Se puede
escribir cdigo que evite la duplicacin y expresa su intencin de una manera clara
abstrado.
Los genricos son una de las caractersticas ms potentes de Swift, y gran parte de la
biblioteca estndar de Swift est construido con cdigo genrico. De hecho, usted ha
estado utilizando los genricos en toda la gua de idiomas , incluso si usted no se dio
cuenta. Por ejemplo, de Swift matriz y Diccionario tipos son ambas colecciones
genricas. Puede crear una matriz que contiene Int valores, o una matriz que
contiene Cuerdavalores, o incluso una matriz de cualquier otro tipo que se puede crear
en Swift. Del mismo modo, se puede crear un diccionario para almacenar valores de
cualquier tipo especificado, y no hay limitaciones en lo que ese tipo puede ser.
El problema que Generics Resuelva
Aqu hay un estndar de funcin, no genrica llamada swapTwoInts , que
intercambia dos Int valores:
let temporaryA = a
a=b
b = temporaryA
}
Esta funcin hace uso de parmetros de salida para cambiar los valores de una y b ,
como se describe enParmetros In-Out .
El swapTwoInts funcin intercambia el valor original de b en una , y el valor
original de una en b . Usted puede llamar a esta funcin para intercambiar los valores
de dos Int variables:
var someInt = 3
swapTwoInts(&someInt, &anotherInt)
250
let temporaryA = a
a=b
b = temporaryA
let temporaryA = a
a=b
b = temporaryA
}
Usted puede haber notado que los cuerpos de
los swapTwoInts , swapTwoStrings y swapTwoDoubles funciones son
idnticas. La nica diferencia es el tipo de los valores que se aceptan ( Int , Cuerda ,
y dobles ).
Sera mucho ms til, y considerablemente ms flexible, para escribir una sola funcin
que podran intercambiar dos valores de cualquier tipo. Cdigo genrico le permite
escribir una funcin de este tipo. (Una versin genrica de estas funciones se define a
continuacin.)
NOTA
En todas las tres funciones, es importante que los tipos de una y b se definen para ser el
mismo que el uno al otro. Si una y b no eran del mismo tipo, no sera posible cambiar
sus valores. Swift es un lenguaje de tipo seguro, y no permite que (por ejemplo) una
variable de tipo de cadena y una variable de tipo doble para intercambiar valores
entre s. Si lo intenta, se inform como un error en tiempo de compilacin.
Funciones Genricas
Funciones genricas pueden trabajar con cualquier tipo. Aqu hay una versin genrica
del swapTwoIntsfuncin de lo alto, llamados swapTwoValues :
let temporaryA = a
a=b
b = temporaryA
}
El cuerpo de la swapTwoValues funcin es idntica a la del cuerpo de
la swapTwoInts funcin. Sin embargo, la primera lnea de swapTwoValues es
ligeramente diferente de swapTwoInts . He aqu cmo se comparan las primeras
lneas:
251
dice nada acerca de lo que T debe ser, pero no decir que tanto una y b deben ser del
mismo tipo T, lo que T representa. El tipo real para usar en lugar de T ser determinado
cada vez que el swapTwoValues funcin es llamada.
La otra diferencia es que el nombre de la funcin genrica ( swapTwoValues ) es
seguido por el nombre del tipo de marcador de posicin ( T ) dentro de corchetes
angulares ( <T> ). Los corchetes indican que Swift T es un nombre de tipo de marcador
de posicin dentro de la swapTwoValues definicin de la funcin. Debido a que T es
un marcador de posicin, Swift no busca un tipo real llamado T .
El swapTwoValues funcin puede ser llamado ahora en la misma manera
que swapTwoInts , excepto que se puede pasar dos valores de cualquier tipo,
siempre y cuando ambos de esos valores son del mismo tipo que el uno al otro. Cada
vez swapTwoValues se llama, el tipo a utilizar para T se infiere de los tipos de
valores pasados a la funcin.
En los dos ejemplos siguientes, T se infiere ser Int y de cadena , respectivamente:
var someInt = 3
swapTwoValues(&someInt, &anotherInt)
swapTwoValues(&someString, &anotherString)
252
253
1. En este momento hay tres valores en la pila.
2. Un cuarto valor es "empujada" en la parte superior de la pila.
3. La pila ahora tiene cuatro valores, con el ms reciente en la parte superior.
4. El elemento superior de la pila se elimina, o "estallar".
5. Despus de hacer estallar un valor, la pila tiene una vez ms tres valores.
Aqu se explica cmo escribir una versin no genrica de una pila, en este caso para una
pila de Int valores:
struct IntStack {
items.append(item)
return items.removeLast()
}
Esta estructura utiliza una matriz de propiedad denominado artculos para
almacenar los valores en la pila.Stack proporciona dos mtodos, empuje y pop ,
para impulsar y valores emergentes y fuera de la pila. Estos mtodos estn marcados
como mutante , porque tienen que modificar (o mutar ) de la estructura de los
elementos de matriz.
El IntStack tipo mostrado anteriormente solamente se puede utilizar
con Int valores, sin embargo. Sera mucho ms til para definir
un genrico Pila clase, que puede administrar una pila de cualquier tipo de valor.
Aqu hay una versin genrica del mismo cdigo:
struct Stack<T> {
254
items.append(item)
return items.removeLast()
}
Ntese cmo la versin genrica de la pila es esencialmente la misma que la
versin no genrica, pero con un parmetro de tipo de marcador de posicin
denominada T en lugar de un tipo real de Int . Este parmetro tipo se escribe dentro de
un par de corchetes angulares ( <T> ) inmediatamente despus del nombre de la
estructura.
T define un nombre de marcador de posicin para "Tipo de alguna T "para proporcionar
ms adelante. Este tipo futuro puede ser referido como " T "en cualquier lugar dentro de
la definicin de la estructura. En este caso, T se utiliza como un marcador de posicin
en tres lugares:
Para crear una propiedad llamada artculos , que se inicia con una matriz vaca
de valores de tipo T
Para especificar que el empuje mtodo tiene un nico parmetro llamado tema ,
que debe ser de tipo T
Para especificar que el valor devuelto por el pop mtodo ser un valor de tipo T
Debido a que es un tipo genrico, Stack se puede utilizar para crear una pila
de cualquier tipo vlido en Swift, de una manera similar a
la matriz y Diccionario .
Se crea una nueva pila instancia escribiendo el tipo que se almacena en la pila dentro
de parntesis angulares. Por ejemplo, para crear una nueva pila de cuerdas,
escribes Stack <String> () :
stackOfStrings.push("uno")
stackOfStrings.push("dos")
stackOfStrings.push("tres")
stackOfStrings.push("cuatro")
255
Hacer estallar un valor a partir de las declaraciones de la pila y elimina el valor de la
parte superior, "cuatro" :
La extensin de un tipo genrico
Al ampliar un tipo genrico, no proporciona una lista de parmetros de tipo como parte
de la definicin de la extensin. En cambio, la lista de parmetros de tipo de la original
de definicin de tipo se encuentra disponible dentro del cuerpo de la extensin, y los
nombres de los parmetros de tipo originales se utilizan para referirse a los parmetros
de tipo de la definicin original.
El siguiente ejemplo extiende la genrica Stack tipo para agregar una propiedad de
slo lectura computarizada llamada topItem , que devuelve el elemento superior de la
pila sin estallar de la pila:
extension Stack {
var topItem: T? {
256
257
if value == valueToFind {
return index
return nil
}
El findStringIndex funcin se puede utilizar para encontrar un valor de cadena en
una matriz de cadenas:
if value == valueToFind {
return index
258
return nil
}
Esta funcin no se compila lo escrito anteriormente. El problema radica en la
comprobacin de igualdad, " si el valor == valueToFind ". No todos los
tipos de Swift se puede comparar con el operador igual a ( == ). Si crea su propia clase
o estructura para representar un modelo de datos complejos, por ejemplo, entonces el
significado de "igual" para esa clase o estructura no es algo que Swift puede adivinar
por ti. Debido a esto, no es posible garantizar que el cdigo funciona para cada tipo
posible T , y se informa de un error apropiado cuando intenta compilar el cdigo.
No todo est perdido, sin embargo. La librera estndar Swift define un protocolo
llamado equatable , que requiere cualquier tipo de conformacin para aplicar el
operador igual a ( == ) y el operador no es igual a ( ! =) para comparar dos valores de
ese tipo. Todos los tipos estndar de Swift apoyan automticamente
elequatable protocolo.
Cualquier tipo que es equiparable se puede utilizar de manera segura con
la FindIndex funcin, ya que se garantiza la compatibilidad de la igual al
operador. Para expresar este hecho, usted escribe una restriccin de tipo
de equatable como parte de la definicin del tipo de parmetro cuando se define la
funcin:
if value == valueToFind {
return index
return nil
}
El nico parmetro de tipo para FindIndex se escribe como T: equatable , que
significa "cualquier tipo T que se ajusta a la equatable protocolo. "
El FindIndex funcin ahora compila con xito y se puede utilizar con cualquier tipo
que sea equiparable , tales como doble o de cadena :
259
marcador de posicin (o alias ) a un tipo que se utiliza como parte del protocolo. El tipo
real de utilizar para ese tipo asociado no se ha especificado hasta que se adopte el
protocolo. Tipos asociados se especifican con el typealias palabra clave.
Tipos Asociados en Accin
He aqu un ejemplo de un protocolo llamado Container , que declara un tipo
asociado llamado ItemType :
protocol Container {
typealias ItemType
}
El Contenedor protocolo define tres capacidades necesarias que cualquier
contenedor debe proporcionar:
Debe ser posible aadir un nuevo elemento en el contenedor con
un append mtodo.
Debe ser posible acceder a un recuento de los artculos en el recipiente a travs de
un recuento depropiedad que devuelve un Int valor.
Debe ser posible para recuperar cada elemento en el recipiente con un subndice que
toma un Int valor de ndice.
Este protocolo no especifica cmo los elementos en el contenedor deben ser
almacenados o qu tipo se les permite ser. El protocolo slo especifica los tres bits de
funcionalidad que cualquier tipo debe proporcionar a fin de ser considerado
un Contenedor . Un tipo de conformacin puede proporcionar funcionalidad
adicional, con tal de que satisface estos tres requisitos.
Cualquier tipo que se ajusta a la Container protocolo debe ser capaz de especificar el
tipo de valores que almacena. En concreto, se debe asegurar que slo los elementos del
tipo correcto se aaden al recipiente, y tiene que tener claro el tipo de los elementos
devueltos por su subndice.
Para definir estos requisitos, el Container protocolo necesita una forma de referirse
al tipo de los elementos que caben en este recipiente, sin saber lo que el tipo es un
contenedor especfico. El Contenedor protocolo debe especificar que cualquier valor
pasado al append mtodo debe tener el mismo tipo que el tipo de elemento del
contenedor, y que el valor devuelto por el subndice del contenedor ser del mismo tipo
que el tipo de elemento del contenedor.
Para lograrlo, el Container protocolo declara un tipo asociado llamado ItemType ,
escrito como typealias ItemType . El protocolo no define lo ItemType es un
alias para informacin -es se deja para cualquier tipo de conformacin para
proporcionar. No obstante, el ItemType alias proporciona una manera de referirse al
tipo de los elementos de un Contenedor , y para definir un tipo para su uso con
el append mtodo y subndice, para asegurar que el comportamiento que se espera de
cualquier Container se hace cumplir.
Aqu hay una versin de la no genrica IntStack tipo de anterior, adaptado para
ajustarse a la Containerprotocolo:
260
items.append(item)
return items.removeLast()
self.push(item)
return items.count
return items[i]
}
El IntStack tipo implementa los tres de la Container requisitos del protocolo, y
en cada caso envuelve parte del IntStack funcionalidad existente de tipo para
satisfacer estos requisitos.
Adems, IntStack especifica que para esta implementacin de contenedores , la
apropiada ItemType a utilizar es un tipo de Int . La definicin de typealias
ItemType = Int convierte el tipo abstracto de ItemType en un tipo concreto
de Int para esta aplicacin de la Container protocolo.
Gracias a la inferencia de tipos de Swift, que en realidad no necesita declarar un
hormign ItemType de Intcomo parte de la definicin
de IntStack . Debido IntStack cumple con todos los requisitos de
la Containerprotocolo, Swift se puede inferir la adecuada ItemType de usar,
simplemente mirando el tipo de la anexin del mtodo de elemento de parmetros
y el tipo de retorno del subndice. De hecho, si elimina las typealias ItemType
= Int lnea del cdigo anterior, todo sigue funcionando, porque est claro qu tipo se
debe utilizar para ItemType .
Tambin puede hacer que el genrico Pila tipo se ajusta a la Container protocolo:
261
items.append(item)
return items.removeLast()
self.push(item)
return items.count
return items[i]
}
Esta vez, el parmetro de tipo de marcador de posicin T se utiliza como el tipo de
la anexin del mtodo deelemento de parmetros y el tipo de retorno del
subndice. Por lo tanto, Swift puede inferir que T es el tipo adecuado para utilizar como
el ItemType para este contenedor particular.
La extensin de un tipo existente para especificar un tipo asociado
Puede extender un tipo existente para agregar la conformidad con un protocolo, como se
describe en Adicin de Protocolo de conformidad con una extensin . Esto incluye un
protocolo con un tipo asociado.
De Swift Matriz tipo ya ofrece un append mtodo, un recuento de la propiedad,
y un subndice con un Intndice para recuperar sus elementos. Estas tres capacidades
coinciden con los requisitos de la Containerprotocolo. Esto significa que usted
puede extender la matriz para ajustarse a la Container protocolo simplemente
declarando que la matriz adopta el protocolo. Esto se hace con una extensin vaca,
como se describe en Declarando Adopcin Protocolo con una extensin :
262
Tambin puede ser til para definir los requisitos para los tipos asociados. Esto se hace
mediante la definicin de dnde clusulas como parte de una lista de parmetros de
tipo. Una clusula where le permite exigir que un tipo asociado se ajusta a un
determinado protocolo, y / o que ciertos parmetros de tipo y tipos asociados a ser el
mismo. Usted escribe una clusula where colocando el donde la palabra clave
inmediatamente despus de la lista de parmetros de tipo, seguido de una o ms
restricciones para los tipos de asociados, y / o una o ms relaciones de igualdad entre los
tipos y tipos asociados.
El ejemplo siguiente define una funcin genrica llamada allItemsMatch , que
comprueba si dos contenedorescasos contienen los mismos elementos en el mismo
orden. La funcin devuelve un valor booleano de true si todos los elementos
coinciden y un valor de falso si no lo hacen.
Los dos contenedores para ser revisadas no tienen que ser del mismo tipo de contenedor
(aunque pueden ser), pero s tiene que mantener el mismo tipo de artculos. Este
requisito se expresa a travs de una combinacin de restricciones de tipo y donde
clusulas:
func allItemsMatch<
if someContainer.count != anotherContainer.count {
return false
for i in 0..<someContainer.count {
if someContainer[i] != anotherContainer[i] {
return false
return true
263
}
Esta funcin toma dos argumentos
llamados someContainer y anotherContainer . El someContainer argume
nto es de tipo C1 , y el anotherContainer argumento es de
tipo C2 . Tanto C1 y C2 son parmetros de tipo de marcador de posicin para dos tipos
de contenedores que se determinarn cuando se invoca la funcin.
Lista de parmetros de tipo de la funcin coloca los siguientes requisitos en los dos
parmetros de tipo:
C1 debe ser conforme a la Container protocolo (escrito como C1:
Contenedor ).
C2 tambin debe ajustarse a la Container protocolo (escrito como C2:
Contenedor ).
El ItemType para C1 debe ser el mismo que el ItemType para C2 (escrito
como C1.ItemType == C2.ItemType).
El ItemType para C1 debe ser conforme a la equatable protocolo (escrito
como C1.ItemType: equatable ).
La tercera y cuarta requisitos se definen como parte de una clusula en donde, y se
escriben despus de laque la palabra clave como parte de la lista de parmetros de tipo
de la funcin.
Estos requisitos se refiere a:
someContainer es un contenedor de tipo C1 .
anotherContainer es un contenedor de tipo C2 .
someContainer y anotherContainer contienen el mismo tipo de artculos.
Los artculos en someContainer se puede comprobar con el operador no igual
( ! = ) para ver si son diferentes unos de otros.
La tercera y cuarta requisitos combinan el sentido de que los artculos
en anotherContainer pueden tambinser revisados con el ! = operador, porque
son exactamente del mismo tipo que los elementos desomeContainer .
Estos requisitos permiten la allItemsMatch funcin para comparar los dos
contenedores, incluso si son de un tipo de contenedor diferente.
El allItemsMatch funcin inicia mediante la comprobacin de que ambos
recipientes contienen el mismo nmero de elementos. Si contienen un nmero diferente
de elementos, no hay manera de que puedan coincidir, y la funcin devuelve falso .
Despus de hacer esta comprobacin, las iteraciones de la funcin ms de todos los
artculos ensomeContainer con un para - en bucle y el operador de rango medio
abierta ( .. < ). Para cada elemento, la funcin comprueba si el elemento
de someContainer no es igual a la partida correspondiente
enanotherContainer . Si los dos artculos no son iguales, entonces los dos
contenedores no coinciden, y la funcin devuelve false .
Si el bucle termina sin encontrar una falta de coincidencia, los dos contenedores
coinciden, y la funcin devuelve verdadero .
He aqu cmo la allItemsMatch funcin se ve en accin:
stackOfStrings.push("uno")
stackOfStrings.push("dos")
stackOfStrings.push("tres")
264
if allItemsMatch(stackOfStrings, arrayOfStrings) {
} else {
265
266
267
Tipos Tuple
El nivel de acceso de un tipo tupla es el nivel de acceso ms restrictivo de los tipos
utilizados en esa tupla.Por ejemplo, si el usuario crea una tupla de dos tipos diferentes,
268
uno con acceso interno y otro con acceso privado, el nivel de acceso para ese tipo tupla
compuesto ser privada.
NOTA
Tipos de tupla no tienen una definicin independiente de la forma en que las clases,
estructuras, enumeraciones y funciones hacen. Nivel de acceso de un tipo tupla se
deduce automticamente cuando se utiliza el tipo de tupla, y no se puede especificar de
forma explcita.
Tipos de funciones
El nivel de acceso para un tipo de funcin se calcula como el nivel de acceso ms
restrictivo de tipos de parmetros de la funcin y el tipo de retorno. Debe especificar el
nivel de acceso de forma explcita como parte de la definicin de la funcin, si el nivel
de acceso de la funcin calculada no coincide con el valor por defecto contextual.
El ejemplo siguiente define una funcin global llamada algunaFuncion , sin
proporcionar un modificador especfico nivel de acceso para la funcin en s. Se podra
esperar que esta funcin tiene el nivel de acceso predeterminado de "interno", pero este
no es el caso. De hecho, algunaFuncion no recogera como est escrito a
continuacin:
}
Tipo de retorno de la funcin es un tipo tupla compuesta a partir de dos de las clases
personalizadas definidas anteriormente en Tipos personalizados . Una de estas clases se
defini como "interno", y el otro se defini como "privado". Por lo tanto, el nivel de
acceso general de la tupla tipo compuesto es (el nivel de acceso mnimo de tipos de
constituyentes de la tupla) "privado".
Debido a que el tipo de retorno de la funcin es privada, debe marcar el nivel de acceso
general de la funcin con el privado modificador para la declaracin de la funcin de
ser vlida:
}
No es vlido para marcar la definicin de algunaFuncion con
los pblicos o internos modificadores, o para utilizar la configuracin por
defecto de internos, ya que los usuarios pblicos o internos de la funcin podra no tener
acceso adecuado a la clase privada usada en el tipo de retorno de la funcin.
Tipos de enumeracin
Los casos individuales de una enumeracin automticamente reciben el mismo nivel de
acceso como la enumeracin que pertenecen. No se puede especificar un nivel de acceso
diferente para casos de enumeracin individuales.
En el siguiente ejemplo, el CompassPoint enumeracin tiene un nivel de acceso
explcita de "pblico". Los casos de enumeracin del
Norte , Sur , Este y Oeste , por tanto, tambin tienen un nivel de acceso de
"pblico":
269
case North
case South
case East
case West
}
Valores primas y valores asociados
Los tipos utilizados para cualquier valor primas o valores asociados en una definicin
de enumeracin deben tener un nivel de acceso por lo menos tan alto como nivel de
acceso de la enumeracin. No puede utilizar unprivado tipo que el tipo de valor en
bruto de una enumeracin con un interno de nivel de acceso, por ejemplo.
Tipos anidados
Tipos anidados definidos dentro de un tipo privado tienen un nivel de acceso automtico
de los privados.Tipos anidados definidos dentro de un tipo de pblico o un tipo interno
tienen un nivel de acceso automtico de los internos. Si quieres un tipo anidado dentro
de un tipo de pblico que est disponible pblicamente, debe declarar explcitamente el
tipo anidado como pblico.
Subclassing
Usted puede crear una subclase de cualquier clase que se puede acceder en el contexto
de acceso actual.Una subclase no puede tener un nivel de acceso ms alto que su
ejemplo superclase-para, usted no puede escribir una subclase de una superclase pblica
interna.
Adems, puede invalidar cualquier miembro de la clase (mtodo, propiedad,
inicializador, o subndice) que es visible en un contexto de acceso seguro.
Una anulacin puede hacer un miembro de la clase heredada ms accesible que su
versin de la superclase.En el siguiente ejemplo, la clase A es una clase pblica con un
mtodo privado llamado someMethod. Clase Bes una subclase de A , con un nivel de
acceso reducido de "interno". Sin embargo, la clase B proporciona una anulacin
de someMethod con un nivel de acceso de "interno", que es ms alta que la
implementacin original de someMethod:
public class A {
internal class B: A {
}
Incluso es vlido para un miembro de la subclase llamar a un miembro de la superclase
que tiene permisos de acceso ms bajos que el miembro de la subclase, siempre y
270
public class A {
internal class B: A {
super.someMethod()
}
Debido superclase A y subclase B se definen en el mismo archivo fuente, es vlido para
el B implementacin de someMethod llamar super.someMethod () .
Constantes, variables, propiedades, y subndices
Una constante, variable o la propiedad no puede ser ms pblico que su tipo. No es
vlido para escribir una propiedad pblica con un tipo privado, por ejemplo. Del mismo
modo, un subndice no puede ser ms pblico que sea su tipo de ndice o tipo de
retorno.
Si una constante, variable, propiedad, o subndice hace uso de un tipo privado, la
constante, variable, propiedad, o subndice debe tambin ser marcado como privado :
Captadores y definidores
Getters y setters para las constantes, variables, propiedades y subndices
automticamente reciben el mismo nivel de acceso como la constante, variable,
propiedad, o subndice que pertenecen.
Usted puede dar un setter un menor nivel de acceso de su correspondiente captador,
para restringir el alcance de lectura-escritura de esa variable, propiedad o subndice. Se
asigna un nivel de acceso ms bajo escribiendo privado (set) o interna
(set) antes de la var o subndice introductor.
NOTA
Esta regla se aplica a las propiedades almacenados, as como propiedades calculadas. A
pesar de que usted no escribe un captador explcito y setter para una propiedad
almacenada, Swift todava sintetiza un captador implcita y setter para que usted
proporcione el acceso al almacenamiento de respaldo de la propiedad
almacenada. Utilice privado (set) y interior (set) para cambiar el nivel de
acceso de este organismo sintetiza exactamente de la misma manera que para un setter
explcita en una propiedad calculada.
El ejemplo siguiente define una estructura llamada TrackedString , que mantiene
un registro del nmero de veces que una propiedad de cadena se modifica:
271
struct TrackedString {
didSet {
numberOfEdits++
}
El TrackedString estructura define una propiedad de cadena almacenado
llamado valor , con un valor inicial de "" (una cadena vaca). La estructura tambin
define una propiedad de entero almacenado llamadonumberOfEdits , que se utiliza
para realizar el seguimiento del nmero de veces que el valor se modifica. Este
seguimiento modificacin se lleva a cabo con un didSet observador propiedad en
el valor de la propiedad, que se incrementa numberOfEdits cada vez que
el valor de la propiedad se establece en un nuevo valor.
El TrackedString estructura y el valor de la propiedad no proporcionan un
modificador explcito nivel de acceso, por lo que ambos reciben el nivel de acceso por
defecto de internos. Sin embargo, el nivel de acceso para
el numberOfEdits propiedad est marcada con un (juego)
privado modificador para indicar que la propiedad debe ser ajustable slo desde
dentro del mismo archivo fuente que la TrackedString definicin de
estructura. Getter de la propiedad todava tiene el nivel de acceso por defecto de
internos, pero su organismo es ahora privado a la fuente en la que TrackedString se
define. Esto permite TrackedString modificar elnumberOfEdits propiedad
internamente, sino para presentar la propiedad como una propiedad de slo lectura
cuando es utilizado por otros archivos de cdigo fuente en el mismo mdulo.
Si crea una TrackedString instancia y modificar su valor de cadena un par de
veces, se puede ver elnumberOfEdits actualizacin valor de la propiedad para que
coincida con el nmero de modificaciones:
272
didSet {
numberOfEdits++
public init() {}
Inicializadores
Inicializadores personalizados se pueden asignar un nivel de acceso inferior o igual al
tipo que inicializar. La nica excepcin es para los inicializadores requeridos (segn se
define en Inicializadores requeridos ). Un inicializador requerido debe tener el mismo
nivel de acceso como la clase a la que pertenece.
Al igual que con los parmetros de funcin y de mtodo, los tipos de los parmetros de
un inicializador no pueden ser ms privado que el propio nivel de acceso del
inicializador.
Inicializadores defecto
Swift proporciona un inicializador por defecto sin ningn argumento para cualquier
estructura o base clase que proporciona valores predeterminados para todas sus
propiedades y no proporciona al menos un inicializador de s mismo. Este inicializador
por defecto se describe en Inicializadores predeterminados . El inicializador por defecto
tiene el mismo nivel de acceso como el tipo se inicializa.
NOTA
Para un tipo que se define como pblica , el inicializador por defecto se considera
interna. Si desea un tipo pblico sea initializable con un inicializador sin argumentos
cuando se usa en otro mdulo, debe proporcionar a un pblico sin argumentos
inicializador ti mismo como parte de la definicin del tipo.
Por defecto miembro por miembro Inicializadores de Estructura Tipos
El inicializador de miembro por miembro predeterminado para un tipo de estructura se
considera privada si alguna de las propiedades almacenados de la estructura son
privados. De lo contrario, el inicializador tiene un nivel de acceso de interior.
Al igual que con el inicializador por defecto de arriba, si quieres un tipo de estructura
pblica sea initializable con un inicializador de miembro por miembro cuando se usa en
273
274
275
tipo de encargo. Swift hace que sea fcil para proporcionar implementaciones a medida
de estos operadores y para determinar exactamente lo que su comportamiento debe ser
para cada tipo que cree.
Usted no est limitado a los operadores predefinidos. Swift le da la libertad para definir
sus propios operadores infijo costumbre, prefijos, Postfix, y de asignacin, con valores
de precedencia y asociatividad personalizado. Estos operadores se pueden utilizar y
adoptaron en su cdigo como cualquiera de los operadores predefinidos, e incluso se
puede extender los tipos existentes para apoyar a los operadores de encargo que usted
defina.
Operadores a nivel de bit
Operadores bit a bit le permiten manipular los bits de datos en bruto individuales dentro
de una estructura de datos. A menudo se utilizan en la programacin de bajo nivel, tales
como la programacin de grficos y la creacin de controlador de
dispositivo. Operadores bit a bit tambin pueden ser tiles cuando se trabaja con datos
en bruto procedentes de fuentes externas, como los datos de codificacin y
decodificacin de la comunicacin a travs de un protocolo personalizado.
Swift es compatible con todos los operadores de bits que se encuentran en C, tal como
se describe a continuacin.
A nivel de bit del operador NO
El nivel de bit NO operador ( ~ ) invierte todos los bits en un nmero:
El nivel de bit NO es un operador prefijo, y aparece inmediatamente antes del valor que
opera en, sin ningn espacio en blanco:
276
En el siguiente ejemplo, los valores de firstSixBits y lastSixBits ambos
tienen cuatro bits medias iguales a 1. El operador AND los combina para hacer el
nmero 00111100 , que es igual a un valor decimal sin signo de60 :
Operador binario OR
El operador binario OR ( | ) compara los bits de dos nmeros. El operador devuelve un
nuevo nmero cuyos bits se ponen a 1 si los bits son iguales a 1 , en tanto el nmero de
entrada:
En el siguiente ejemplo, los valores de someBits y moreBits tienen diferentes bits
puestos a 1 . El operador binario OR los combina para hacer el nmero 11111110 , lo
que equivale a un decimal sin signo de 254 :
XOR Operador
El operador XOR bit a bit , o "operador O exclusivo" ( ^ ), compara los bits de dos
nmeros. El operador devuelve un nuevo nmero cuyos bits se ponen a 1 , donde los
277
bits de entrada son diferentes y estn ajustados a 0 , donde los bits de entrada son los
mismos:
En el siguiente ejemplo, los valores de firstBits y otherBits tienen cada uno un
conjunto de bits a 1 en un lugar que el otro no. El operador XOR bit a bit establece
estos dos bits a 1 en su valor de salida. Todos los otros bits
en firstBits y otherBits partido y se ponen a 0 en el valor de salida:
278
As es como se ve poco cambio en el cdigo Swift:
279
El bit de signo es 0 (lo que significa "positivo"), y los siete bits de valor son slo el
nmero 4 , escrito en notacin binaria.
Los nmeros negativos, sin embargo, se almacenan de manera diferente. Se almacenan
restando su valor absoluto de 2 a la potencia de n , donde n es el nmero de bits de
valor. Un nmero de ocho bits tiene siete bits de valor, por lo que esto significa 2 a la
potencia de 7 , o 128 .
He aqu cmo los bits dentro de un INT8 buscan el nmero -4 :
Esta vez, el bit de signo es 1 (que significa "negativo"), y los siete bits de valor tiene un
valor binario de 124(que es 128-4 ):
La codificacin para los nmeros negativos se conoce como un complemento a dos
de la representacin.Puede parecer una manera inusual para representar nmeros
negativos, pero tiene varias ventajas.
En primer lugar, puede agregar -1 a -4 , basta con realizar una suma binaria estndar
de todos los ocho bits (incluyendo el bit de signo), y descartar cualquier cosa que no
encaja en los ocho bits, una vez que haya terminado:
280
En segundo lugar, la representacin de los dos se complementan tambin le permite
desplazar los bits de los nmeros negativos a la izquierda y la derecha como nmeros
positivos, y an as terminar duplicando ellos por cada turno que realice a la izquierda, o
reducir a la mitad de ellos por cada turno que realice a la derecha . Para lograr esto, se
utiliza una regla adicional cuando enteros con signo se desplazan a la derecha:
Cuando usted cambia enteros con signo a la derecha, se aplican las mismas reglas
que para los enteros sin signo, pero llenar cualquier pedacito vaco de la izquierda
con el bit de signo , en lugar de con un cero.
Esta accin asegura que los nmeros enteros con signo tienen el mismo signo despus
de que se desplazan a la derecha, y se conoce como un desplazamiento aritmtico .
Debido a la forma especial que los nmeros positivos y negativos se almacenan,
cambiando cualquiera de ellos a la derecha los mueve ms cerca de cero. Mantener el
signo mordi la misma durante este cambio significa que los enteros negativos siguen
siendo negativas ya que su valor se acerca a cero.
Operadores de desbordamiento
Si intenta insertar un nmero en una constante entera o variable que no puede contener
ese valor, por defecto Swift informa de un error en lugar de permitir un valor no vlido
que se crear. Este comportamiento da mayor seguridad cuando se trabaja con nmeros
que son demasiado grandes o demasiado pequeas.
Por ejemplo, la Int16 tipo entero puede contener cualquier nmero entero con signo
entre -32768 y 32767 .Tratar de establecer una Int16 constante o variable a un
nmero fuera de este rango produce un error:
// potentialOverflow equals 32767, which is the largest value an Int16 can hold
potentialOverflow += 1
281
Valor Underflow
Los nmeros tambin pueden llegar a ser demasiado pequeo como para caber dentro
de los lmites mximos de su tipo. He aqu un ejemplo.
El menor valor que un Uint8 puede contener es 0 (que es 00 millones en forma
binaria de ocho bits). Si se resta 1 de 00 millones mediante el operador de
sustraccin de desbordamiento, el nmero se desbordar hacia atrs y vuelta
a 11111111 , o 255 en decimal:
282
As es como que se ve en el cdigo Swift:
Aqu est lo mismo en cdigo Swift:
283
let x = 1
let y = x / 0
Sin embargo, las versiones de desbordamiento de estos operadores ( y / y &% )
devuelven un valor de cero si se divide por cero:
let x = 1
let y = x &/ 0
// Y es igual a 0
Precedencia y asociatividad
Operador precedencia da algunos operadores de mayor prioridad que otras; estos
operadores se aplican primero.
Operador asociatividad define cmo se agrupan los operadores de la misma precedencia
juntos (o asociados) -bien agrupan desde la izquierda, o agrupados por la
derecha. Piense en ello en el sentido de "que asocian con la expresin a su izquierda", o
"que se asocian con la expresin de su derecho."
Es importante tener en cuenta la precedencia y asociatividad de cada operador cuando
se trabaja con el orden en el que se calcula una expresin compuesta. He aqu un
ejemplo. Por qu la siguiente expresin es igual a 4 ?
2 + 3 * 4 % 5
// Esto es igual a 4
Tomado estrictamente de izquierda a derecha, es de esperar que esto se lea como sigue:
2 ms 3 igual a 5;
5 veces 4 es igual a 20;
20 resto 5 es igual a 0
Sin embargo, la respuesta real es 4 , no 0 . Operadores de mayor precedencia se evalan
antes que las de menor precedencia. En Swift, como en C, el operador de multiplicacin
( * ) y el operador de resto ( % ) tienen una mayor precedencia que el operador de suma
( + ). Como resultado, ambos son evaluados antes se considera la adicin.
Sin embargo, la multiplicacin y el resto tienen la misma precedencia que s. Para
calcular el orden de evaluacin exacta de usar, tambin es necesario tener en cuenta su
asociatividad. La multiplicacin y la resta tanto asociado con la expresin a su
izquierda. Piense en esto como la adicin de parntesis implcitos alrededor de estas
partes de la expresin, a partir de su izquierda:
2 + (( 3 * 4 )% 5 )
(3 * 4) es 12 , as que esto es equivalente a:
2 + ( 12 % 5 )
(12% 5) es 2 , as que esto es equivalente a:
2 + 2
Este clculo se obtiene la respuesta final de 4 .
284
struct Vector2D {
}
La funcin de operador se define como una funcin global con un nombre de funcin
que coincide con el operador para ser sobrecargado ( + ). Debido a que el operador de
suma aritmtica es un operador binario, esta funcin operador toma dos parmetros de
entrada de tipo Vector2D y devuelve un nico valor de salida, tambin de
tipo Vector2D .
En esta aplicacin, los parmetros de entrada se
denominan izquierda y derecha para representar losVector2D instancias que
estarn en el lado izquierdo y el lado derecho de la + operador. La funcin devuelve una
nueva Vector2D ejemplo, cuya x y Y. propiedades se inicializan con la suma de
la x y Y las propiedades de los dos Vector2D casos que se agregan juntos.
La funcin se define a nivel mundial, en lugar de como un mtodo en
el Vector2D estructura, de modo que pueda ser utilizado como un operador infijo
entre existentes Vector2D casos:
285
Este ejemplo suma los vectores (3.0, 1.0) y (2.0, 4.0) para hacer que el
vector (5.0, 5.0) , como se ilustra a continuacin.
Prefijo y Operadores de Postfix
El ejemplo anterior demuestra una implementacin personalizada de un operador infijo
binario. Clases y estructuras tambin pueden proporcionar implementaciones de los
estndares operadores unarios . Los operadores unarios operan en un solo
objetivo. Son prefijo cuando fueren anteriores a su destino (por ejemplo : una )
y postfix operadores si siguen su destino (como i ++ ).
Implementa un prefijo o Postfix operador unitario escribiendo el prefijo o de
sufijo modificador antes de lafunc palabra clave cuando se declara la funcin de
operador:
}
El ejemplo anterior implementa el operador menos unario ( -a )
para Vector2D casos. El operador menos unario es un operador prefijo, por lo que
esta funcin tiene que ser calificado con el prefijo modificador.
Para los valores numricos simples, el operador menos unario convierte nmeros
positivos en su negativa versa equivalente y el vicio. La aplicacin correspondiente
para Vector2D casos realiza esta operacin tanto en la x y Y propiedades:
286
Operadores de Asignacin Compuesto
Operadores de asignacin compuestos combinan asignacin ( = ) con otra
operacin. Por ejemplo, el operador de asignacin de suma ( + = ) combina la adicin y
la asignacin en una sola operacin. Usted marca parmetro de entrada izquierda una
asignacin del operador compuesto como inout , porque el valor del parmetro ser
modificado directamente desde dentro de la funcin de operador.
El siguiente ejemplo implementa una funcin de operador de asignacin de suma
para Vector2D casos:
}
Debido a que un operador de suma se defini anteriormente, no es necesario volver a
implementar el proceso de adicin aqu. En lugar de ello, la funcin de operador de
asignacin Adems se aprovecha de la funcin de operador de suma existente, y la
utiliza para establecer el valor de izquierda a ser el valor ms el valor izquierda derecha:
original += vectorToAdd
return vector
}
La funcin de operador de incremento prefijo anteriormente se aprovecha de que el
operador de asignacin de suma definida anteriormente. Se aade
un Vector2D con x y Y los valores de 1,0 a la Vector2D en la que se le llama, y
devuelve el resultado:
287
}
El ejemplo anterior implementa un "igual a" operador ( == ) para comprobar si
dos Vector2D casos tienen valores equivalentes. En el contexto de Vector2D , tiene
sentido considerar "igual" en el sentido de "ambas instancias tienen los
mismos x valores y Y valores ", y por lo que esta es la lgica utilizada por la aplicacin
del operador. El ejemplo tambin implementa el "no es igual a" operador ( ! = ), que
simplemente devuelve el inverso del resultado de la "igual a" operador.
Ahora puede utilizar estos operadores para comprobar si dos Vector2D casos son
equivalentes:
if twoThree == anotherTwoThree {
288
vector += vector
return vector
}
Esta implementacin de +++ es muy similar a la aplicacin de ++ para Vector2D ,
excepto que esta funcin de operador aade el vector a s mismo, en lugar de
aadir Vector2D (1.0, 1.0) :
289
Este operador suma los x valores de dos vectores, y resta el y valor de la segunda vector
desde el primero.Debido a que es en esencia un operador "aditivo", se ha dado a los
mismos valores de asociatividad y precedencia ( izquierda y 140 ) como
operadores infijos aditivo defecto como + y - . Para obtener una lista completa de los
ajustes de precedencia y asociatividad de operadores Swift predeterminados,
veaExpresiones .
NOTA
No se especifica una prioridad en la definicin de un operador de prefijo o de sufijo. Sin
embargo, si usted solicita un prefijo y un operador de sufijo al mismo operando, el
operador de sufijo se aplica primero.
290
Acerca de la Referencia del lenguaje
Esta parte del libro describe la gramtica formal del lenguaje de programacin Swift. La
gramtica se describe aqu est destinado a ayudar a entender el idioma con ms detalle,
en lugar de que le permite implementar directamente un analizador o compilador.
El lenguaje Swift es relativamente pequeo, debido a que muchos comunes tipos,
funciones y operadores que aparecen prcticamente en todas partes en el cdigo Swift
estn definidos en la librera estndar de Swift. Aunque estos tipos, funciones y
operadores que no forman parte de la propia lengua Swift, que se utilizan ampliamente
en las discusiones y ejemplos de cdigo en esta parte del libro.
Cmo leer la Gramtica
La notacin utilizada para describir la gramtica formal del lenguaje de programacin
Swift sigue una serie de convenciones:
Una flecha () se utiliza para marcar las producciones de la gramtica y se puede
leer como "puede consistir en."
Categoras sintcticas se indican mediante cursiva texto y aparecen en ambos lados
de una regla de produccin gramtica.
Palabras literales y puntuacion se indican con negrita anchura
constante texto y slo aparecen en el lado derecho de una regla de gramtica de
produccin.
Producciones gramaticales alternativos estn separados por barras verticales
(|). Cuando producciones alternativas son demasiado tiempo para leer con facilidad,
que se dividen en varias reglas de la gramtica de produccin en nuevas lneas.
En unos pocos casos, el texto fuente normal se utiliza para describir el lado derecho
de una regla de gramtica de produccin.
Categoras y literales sintcticas opcionales estn marcadas por un subndice de
arrastre, optan .
Como ejemplo, la gramtica de un bloque getter-setter se define como sigue:
GRAMTICA DE UN BLOQUE GETTER-SETTER
getter-setter-block {getter-clausesetter-clauseopt} {setter-clausegetter-clause}
Esta definicin indica que un bloque getter-setter puede consistir en una clusula getter
seguida de una clusula facultativa setter, entre llaves, o una clusula setter seguido por
una clusula getter, entre llaves. La produccin de la gramtica anterior es equivalente a
las siguientes dos producciones, donde las alternativas se extraen explcitamente:
GRAMTICA DE UN BLOQUE GETTER-SETTER
getter-setter-block {getter-clausesetter-clauseopt} {setter-clausegetter-clause}
291
Estructura lxica
En esta pgina
La estructura lxica de Swift describe qu secuencia de caracteres forman smbolos
vlidos de la lengua.Estos tokens vlidos forman los bloques de construccin de ms
bajo nivel de la lengua y se utilizan para describir el resto de la lengua en los captulos
siguientes. Un smbolo consiste en un identificador, palabra clave, puntuacion, literal, o
el operador.
En la mayora de los casos, las fichas se generan a partir de los caracteres de un archivo
de origen Swift considerando la ms larga subcadena posible del texto de entrada,
dentro de las restricciones de la gramtica que se especifican a continuacin. Este
comportamiento se conoce como partido ms largo o munch mxima.
Los espacios en blanco y comentarios
El espacio en blanco tiene dos usos: para separar tokens en el archivo de origen y para
ayudar a determinar si un operador es un prefijo o de sufijo (ver Operadores ), pero se
ignora lo contrario. Los siguientes caracteres se consideran espacios en blanco: espacio
(U + 0020), avance de lnea (U + 000A), retorno de carro (U + 000D), tabulador
horizontal (U + 0009), pestaa vertical (U + 000B), la forma de alimentacin (U +
000C) y nulo (U + 0000).
Los comentarios son tratados como espacios en blanco por el compilador. Una sola
lnea Los comentarios comienzan con // y continuar hasta que un retorno de carro (U +
000D) o avance de lnea (U + 000A).Comentarios multilnea empiezan con / * y
terminan con * / . Anidacin comentarios multilnea est permitido, pero los
marcadores de comentario debe ser equilibrado.
Identificadores
Identificadores comienzan con una letra mayscula o minscula de la A a la Z, un guin
bajo ( _ ), un carcter alfanumrico noncombining Unicode en el plano multilinge
bsico, o un personaje fuera del plano multilinge bsico que no est en un rea de uso
privado. Despus del primer carcter, tambin se permite la combinacin de dgitos y
caracteres Unicode.
Para utilizar una palabra reservada como identificador, poner un acento grave ( ` ) antes
y despus de ella.Por ejemplo, la clase no es un identificador vlido,
pero `class` es vlida. Los acentos abiertos no se consideran parte del
identificador; `x` y x tienen el mismo significado.
Dentro de un cierre sin nombres explcitos de los parmetros, los parmetros se
denominan implcitamente $ 0 , $ 1 , $ 2 , y as sucesivamente. Estos nombres son
identificadores vlidos dentro del mbito de aplicacin del cierre.
GRAMTICA DE UN IDENTIFICADOR
identifier identifier-headidentifier-charactersopt
identifier `identifier-headidentifier-charactersopt`
identifier implicit-parameter-name
identifier-list identifier identifier,identifier-list
identifier-head Upper- or lowercase letter A through Z
identifier-head _
identifier-head U+00A8, U+00AA, U+00AD, U+00AF, U+00B2U+00B5, or
U+00B7U+00BA
292
293
42 // Integer literal
294
295
296
Los caracteres especiales pueden ser incluidos en los literales de cadena utilizando las
siguientes secuencias de escape:
Carcter nulo ( \ 0 )
Barra invertida ( \\ )
Horizontal Tab ( \ t )
Avance de lnea ( \ n )
Retorno de carro ( \ r )
Doble Cita ( \ " )
Las comillas sencillas ( \ ' )
Unicode escalar ( \ u { n } ), donde n es entre uno y ocho dgitos hexadecimales
El valor de una expresin se puede insertar en una cadena literal mediante la colocacin
de la expresin entre parntesis despus de una barra invertida ( \ ). La expresin
interpolado no debe contener un doble cita no literal ( " ), una barra invertida sin escape
( \ ), un retorno de carro o un salto de lnea. La expresin debe evaluarse como un valor
de un tipo que la Cadena de clase tiene un inicializador de.
Por ejemplo, todos los siguientes literales de cadena tienen el mismo valor:
"1 2 3"
"1 2 \ ( 3 ) "
"1 2 \ ( 1 + 2 ) "
297
298
operator-head U+00A1U+00A7
operator-head U+00A9 or U+00AB
operator-head U+00AC or U+00AE
operator-head U+00B0U+00B1, U+00B6, U+00BB, U+00BF, U+00D7, or
U+00F7
operator-head U+2016U+2017 or U+2020U+2027
operator-head U+2030U+203E
operator-head U+2041U+2053
operator-head U+2055U+205E
operator-head U+2190U+23FF
operator-head U+2500U+2775
operator-head U+2794U+2BFF
operator-head U+2E00U+2E7F
operator-head U+3001U+3003
operator-head U+3008U+3030
operator-character operator-head
operator-character U+0300U+036F
operator-character U+1DC0U+1DFF
operator-character U+20D0U+20FF
operator-character U+FE00U+FE0F
operator-character U+FE20U+FE2F
operator-character U+E0100U+E01EF
operator-characters operator-characteroperator-charactersopt
dot-operator-head ..
dot-operator-character . operator-character
dot-operator-characters dot-operator-characterdot-operator-charactersopt
binary-operator operator
prefix-operator operator
postfix-operator operator
Tipos
En Swift, hay dos clases de tipos: tipos con nombre y tipos de compuestos. Un tipo con
nombre es un tipo que se puede dar un nombre en particular cuando se define. Tipos con
nombre incluyen clases, estructuras, enumeraciones y protocolos. Por ejemplo, las
instancias de una clase llamada definidos por el usuario MyClasstienen el
tipo MyClass . Adems de los tipos con nombres definidos por el usuario, la biblioteca
estndar Swift define muchos tipos con nombre de uso comn, incluidos aquellos que
representan arrays, diccionarios, y los valores opcionales.
Tipos de datos que normalmente se consideran bsicos o primitivos en otros idiomascomo los tipos que representan nmeros, caracteres y cadenas-se nombren tipos,
definidos e implementados en la biblioteca estndar Swift utilizando estructuras. Debido
a que se nombran los tipos, puede extender su comportamiento para adaptarse a las
necesidades de su programa, usando una ampliacin de declaracin, se discuti
enExtensiones y ampliacin de declaracin .
299
300
301
if !condition() {
println(message)
let testNumber = 5
var array3D: [[[Int]]] = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]
302
303
El tipo opcional <T> es una enumeracin con dos casos, Ninguno y Algunos
(T) , que se utilizan para representar valores que pueden o no pueden estar
presentes. Cualquier tipo puede ser declarado explcitamente que ser (o implcitamente
convertido a) un tipo opcional. Si usted no proporciona un valor inicial cuando se
declara una variable o propiedad opcional, su valor cambia automticamente a cero .
Si una instancia de un tipo opcional contiene un valor, se puede acceder a ese valor con
el operador de sufijo! , como se muestra a continuacin:
optionalInteger = 42
optionalInteger! // 42
Usando el ! operador a desenvolver un opcional que tiene un valor de nil resultados
en un error de ejecucin.
Tambin puede utilizar el encadenamiento opcional y de unin opcional para realizar
condicionalmente una operacin en una expresin opcional. Si el valor es cero , no se
realiza ninguna operacin, por lo que no se produce ningn error de ejecucin.
Para obtener ms informacin y ver ejemplos que muestran cmo utilizar los tipos
opcionales, consulteOpcionales .
GRAMTICA DE TIPO OPCIONAL
optional-type type?
Implcitamente Unwrapped Tipo Opcional
El lenguaje Swift define el postfix ! como azcar sintctico para el tipo
llamado ImplicitlyUnwrappedOptional <T> , que se define en la biblioteca
estndar de Swift. En otras palabras, las dos declaraciones siguientes son equivalentes:
304
305
class SomeBaseClass {
println("SomeBaseClass")
println("SomeSubClass")
someInstance.dynamicType.printClassName()
// Impresiones "SomeSubClass"
GRAMTICA DE UN TIPO METATIPO
metatype-type type.Type type.Protocol
Tipo Herencia Clusula
Una clusula tipo de herencia se utiliza para especificar qu clase de un tipo llamado
hereda y qu protocolos un tipo designado cumple con. Una clusula tipo de herencia
tambin se utiliza para especificar una clase derequisito en un protocolo. Una
clusula tipo de herencia comienza con dos puntos ( : ), seguido por cualquiera de
una clase de requisito, una lista de identificadores de tipo, o ambos.
Tipos de clases pueden heredar de una nica superclase y ajustarse a cualquier nmero
de protocolos.Cuando se define una clase, el nombre de la superclase debe aparecer
primero en la lista de identificadores de tipo, seguido de cualquier nmero de protocolos
de la clase debe cumplir. Si la clase no se hereda de otra clase, la lista puede comenzar
con un protocolo en su lugar. Para una extensa discusin y varios ejemplos de la
herencia de clases, vea Herencia .
Otros tipos con nombre slo pueden heredar de o ajustarse a una lista de
protocolos. Tipos de protocolo pueden heredar de cualquier nmero de otros
protocolos. Cuando un tipo de protocolo hereda de otros protocolos, el conjunto de
requisitos de los otros protocolos son agregados juntos, y de cualquier tipo que hereda
de la actual protocolo debe cumplir con todos esos requisitos. Como se discuti en la
declaracin el Protocolo , puede incluir la clase de palabras clave como el primer
elemento de la clusula de tipo de herencia para marcar una declaracin protocolo con
una clase requisito.
306
Una clusula tipo de herencia en una definicin de enumeracin puede ser una lista de
protocolos, o en el caso de una enumeracin que asigna valores de primas a sus casos,
una sola, el tipo con nombre que especifica el tipo de los valores brutos. Para ver un
ejemplo de una definicin de la enumeracin que utiliza una clusula tipo de herencia
para especificar el tipo de sus valores brutos, consulte Raw Values.
GRAMTICA DE UNA CLUSULA DE HERENCIA DE TIPO
type-inheritance-clause :class-requirement,type-inheritance-list
type-inheritance-clause :class-requirement
type-inheritance-clause :type-inheritance-list
type-inheritance-list type-identifier type-identifier,type-inheritance-list
class-requirement class
-requisito clase
Tipo Inferencia
Swift utiliza la inferencia de tipos ampliamente, lo que le permite omitir el tipo o la
parte del tipo de muchas variables y expresiones en el cdigo. Por ejemplo, en lugar de
escribir var x: int = 0 , se puede escribir var x = 0 , omitiendo el tipo
completamente-el compilador infiere correctamente que x nombres un valor de
tipoint . Del mismo modo, se puede omitir parte de un tipo cuando el tipo completo se
puede deducir por el contexto. Por ejemplo, si escribes dejar dict:
Diccionario = ["A": 1] , el compilador infiere que dict tiene el
tipo Dictionary <String, int> .
En los dos ejemplos anteriores, la informacin de tipo se pasa desde las hojas del rbol
de expresin a su raz. Es decir, el tipo de x en var x: int = 0 se deduce
comprobando primero el tipo de 0 y despus de pasar esta informacin de tipo hasta la
raz (la variable x ).
En Swift, informacin de tipo tambin puede fluir en la direccin opuesta, desde la raz
hasta las hojas. En el ejemplo siguiente, por ejemplo, la anotacin de tipo explcita ( :
flotador ) de la constante de eFloat hace que el literal numrico 2,71828 tener
un tipo inferido de flotador en lugar de doble .
307
308
309
310
expression is type
expression as type
Las is check de operador en tiempo de ejecucin si la expresin puede ser abatido a la
especificadatipo . Devuelve verdadero si la expresin puede ser abatido a la
especificada tipo ; de lo contrario, devuelvefalse . Si vas a vaciar a la
especificada tipo est garantizado para tener xito o fracasar, se eleva un error en
tiempo de compilacin. Por ejemplo, 10 es Int y 10 es de cadena tanto elevar
los errores en tiempo de compilacin.
El as operador realiza un elenco condicional de la expresin a la
especificada tipo . El as operador devuelve un opcional de la especificada tipo . En
tiempo de ejecucin, si la conversin se realiza correctamente, el valor de la
expresin se envuelve en una opcional y regres; de lo contrario, el valor devuelto
es nulo . Si vas a vaciar a la especificada tipo est garantizada a fallar, se eleva un
error en tiempo de compilacin. Por ejemplo, la conversin a un tipo que no es ni una
subclase o superclase del tipo de laexpresin es un error.
El as operador realiza una conversin forzada de la expresin a la
especificada tipo . El as operador devuelve un valor de la especificada tipo , no un tipo
opcional. Si la conversin falla, se produce un error de ejecucin. El comportamiento
de x as T es el mismo que el comportamiento de (x como? T)! .
Para obtener ms informacin acerca de la conversin de tipos y para ver ejemplos que
utilizan los operadores de tipo de fundicin a presin, ver la conversin de tipos .
GRAMTICA DE UN OPERADOR DE TIPO CASTING
type-casting-operator istype
type-casting-operator astype
type-casting-operator as?type
Expresiones primarias
Expresiones primarias son el tipo ms bsico de expresin. Pueden ser utilizados como
expresiones de su propia, y se pueden combinar con otras fichas para hacer expresiones
de prefijos binarios, expresiones y expresiones de sufijo.
GRAMTICA DE UNA EXPRESIN PRIMARIA
primary-expression identifiergeneric-argument-clauseopt
primary-expression literal-expression
primary-expression self-expression
primary-expression superclass-expression
primary-expression closure-expression
311
primary-expression parenthesized-expression
primary-expression implicit-member-expression
primary-expression wildcard-expression
Expresin Literal
Una expresin literal consiste ya sea de un literal ordinario (tal como una cadena o un
nmero), una matriz o diccionario literal, o uno de los siguientes literales especiales:
Literal
Tipo
Valor
__FILE__
Cadena
__LINE__
Int
__COLUMN__
Int
__FUNCTION__
Cadena
GRAMTICA DE UNA EXPRESIN LITERAL
literal-expression literal
literal-expression array-literal dictionary-literal
312
self
class SomeClass {
init(greeting: String) {
self.greeting = greeting
}
En un procedimiento de mutacin de un tipo de valor, se puede asignar una nueva
instancia de ese tipo de valor para uno mismo . Por ejemplo:
struct Point {
313
}
Los parmetros tienen la misma forma que los parmetros en una declaracin de la
funcin, tal como se describe en la declaracin de la funcin .
Hay varias formas especiales que permiten a los cierres que se escriben de manera ms
concisa:
Un cierre puede omitir los tipos de sus parmetros, el tipo de retorno, o ambos. Si
omite los nombres de los parmetros y de ambos tipos, omita el de palabra clave
antes de las sentencias. Si los tipos omitidos no se pueden deducir, se eleva un error
en tiempo de compilacin.
314
Un cierre puede omitir los nombres de sus parmetros. Sus parmetros son entonces
implcitamente nombrado $ seguidos de su posicin: $ 0 , $ 1 , $ 2 , y as
sucesivamente.
Un cierre que consta de slo una nica expresin se entiende para devolver el valor
de esa expresin.El contenido de esta expresin tambin se consideran cuando se
realiza la inferencia de tipos en la expresin de los alrededores.
Las siguientes expresiones de cierre son equivalentes:
myFunction {
return x + y
myFunction {
(x, y) in
return x + y
myFunction { return $0 + $1 }
myFunction { $0 + $1 }
Para obtener informacin acerca de pasar un cierre como argumento a una funcin,
consulte Funcin de llamada Expresin .
Una expresin de cierre puede especificar explcitamente los valores que retrata tanto en
el mbito circundante utilizando una lista de captura . Una lista de captura est escrita
como una lista separada por comas entre corchetes, antes de que la lista de
parmetros. Si utiliza una lista de captura, tambin debe usar el de palabra clave,
incluso si se omite los nombres de parmetros, tipos de parmetros y el tipo de retorno.
Cada entrada en la lista de captura puede ser marcado como dbil o sin
dueo para capturar una referencia dbil o sin dueo al valor.
315
var x = MyEnumeration.SomeValue
x = .AnotherValue
316
Expresin Comodn
Una expresin comodn se utiliza para ignorar explcitamente un valor durante una
asignacin. Por ejemplo, en la siguiente asignacin de 10 se asigna a x y 20 se ignora:
// x is 10, 20 is ignored
GRAMTICA DE UNA EXPRESIN COMODN
wildcard-expresin _
Postfix Expresiones
Expresiones Postfix se forman mediante la aplicacin de un operador de sufijo u otra
sintaxis postfix a una expresin. Sintcticamente, cada expresin primaria es tambin
una expresin postfix.
La biblioteca estndar Swift ofrece los siguientes operadores de sufijo:
++ Incremento
- Disminuir
Para obtener informacin sobre el comportamiento de estos operadores,
consulte Operadores bsicos yOperadores avanzados .
GRAMTICA DE UNA EXPRESIN POSTFIX
postfix-expression primary-expression
postfix-expression postfix-expressionpostfix-operator
postfix-expression function-call-expression
postfix-expression initializer-expression
postfix-expression explicit-member-expression
postfix-expression postfix-self-expression
postfix-expression dynamic-type-expression
postfix-expression subscript-expression
postfix-expression forced-value-expression
postfix-expression optional-chaining-expression
Funcin Expresin Call
Una expresin de llamada a la funcin consiste en un nombre de la funcin seguido de
una lista separada por comas de los argumentos de la funcin entre
parntesis. Expresiones de llamada de funcin tiene la siguiente forma:
317
var x = SomeClass.someClassFunction // ok
init() {
super.init()
318
class SomeClass {
var someProperty = 42
let c = SomeClass()
t.0 = t.1
expression .self
type .self
La primera forma se evala como el valor de la expresin . Por
ejemplo, x.self evala como x .
La segunda forma se evala al valor del tipo . Utilice este formulario para acceder a un
tipo como un valor.Por ejemplo, porque SomeClass.self evala
al AlgunaClase mismo tipo, puede pasar a una funcin o mtodo que acepta un
argumento de nivel de tipo.
319
class SomeBaseClass {
println("SomeBaseClass")
println("SomeSubClass")
someInstance.dynamicType.printClassName()
// Impresiones "SomeSubClass"
GRAMTICA DE UN TIPO DE EXPRESIN DINMICA
dynamic-type-expression postfix-expression.dynamicType
Expresin Subndice
Una expresin subndice proporciona acceso subndice usando el get y set de la
declaracin subndice correspondiente. Tiene la siguiente forma:
320
var x: Int? = 0
x!++
// x is now 1
someDictionary["a"]![0] = 100
GRAMTICA DE UNA EXPRESIN-VALOR FORZADO
forced-value-expression postfix-expression!
Opcional-encadenamiento Expresin
Una expresin opcional encadenamiento proporciona una sintaxis simplificada para el
uso de los valores opcionales en las expresiones de sufijo. Tiene la siguiente forma:
expression ?
Por su parte, el postfix ? operador simplemente devuelve el valor de su argumento
como un opcional.
Postfix expresiones que contienen una expresin opcional de encadenamiento se
evalan de una manera especial. Si la expresin-opcional encadenamiento es nulo ,
todas las otras operaciones en la expresin postfix son ignorados y toda la expresin
postfix evala como nula . Si la expresin-opcional encadenamiento no es nula , el
valor de la expresin-opcional encadenamiento se desenvuelve y se utiliza para evaluar
el resto de la expresin postfix. En cualquier caso, el valor de la expresin postfix sigue
siendo de un tipo opcional.
Si una expresin postfix que contiene una expresin opcional en cadena est anidado
dentro de otras expresiones de sufijo, slo la expresin ms externa devuelve un tipo
321
var c: SomeClass?
if let unwrappedC = c {
result = unwrappedC.property.performAction()
}
El valor de envolver de una expresin opcional de encadenamiento puede ser
modificado, ya sea por mutacin del valor en s, o mediante la asignacin a uno de los
miembros del valor. Si el valor de la expresin-opcional encadenamiento es nula , no
se evala la expresin en el lado derecho del operador de asignacin. Por ejemplo:
return 42
// someFunctionWithSideEffects no se evala
someDictionary["a"]?[0] = someFunctionWithSideEffects()
()
// someFunctionWithSideEffects se evala
GRAMTICA DE UNA EXPRESIN-OPCIONAL
ENCADENAMIENTO
optional-chaining-expression postfix-expression?
Declaraciones
En Swift, hay dos tipos de declaraciones: declaraciones simples y estados de flujo de
control. Declaraciones simples son los ms comunes y consisten tanto en una expresin
o una declaracin. Estados de flujos de control se utilizan para controlar el flujo de
322
}
Los punto y coma entre la inicializacin , condicin , y la subasta se requieren. Los
apoyos en torno a lasdeclaraciones tambin son necesarios en el cuerpo del bucle.
Una de sentencia se ejecuta de la siguiente manera:
323
}
El generar mtodo se llama en la coleccin de expresin para obtener un valor de un
tipo que es generador, un tipo que se ajusta a la GeneratorType protocolo. El
programa comienza la ejecucin de un bucle mediante una llamada
al siguiente mtodo en la secuencia. Si el valor devuelto no es Ninguno , se le
asigna a la partidapatrn, el programa ejecuta las declaraciones , y luego contina la
ejecucin en el principio del bucle. De lo contrario, el programa no realiza cesin o
ejecutar las sentencias , y que se haya ejecutado la para - encomunicado.
GRAMTICA DE UNA DECLARACIN FOR-IN
for-in-statement forpatterninexpressioncode-block
Mientras Declaracin
Un mientras declaracin permite un bloque de cdigo que se ejecuta repetidamente,
siempre y cuando una condicin sigue siendo cierto.
A mientras que la declaracin tiene la siguiente forma:
while condition {
statements
324
}
A mientras sentencia se ejecuta de la siguiente manera:
1. La condicin es evaluada.
Si cierto , la ejecucin contina con el paso 2 Si falso , el programa ha
terminado de ejecutar elmientras comunicado.
2. El programa ejecuta las declaraciones , y la ejecucin vuelve al paso 1.
Debido a que el valor de la condicin es evaluada antes de que las declaraciones se
ejecutan, lasdeclaraciones en una mientras que la declaracin se pueden ejecutar
cero o ms veces.
El valor de la condicin debe tener un tipo que se ajusta a
la BooleanType protocolo. La condicin tambin puede ser una declaracin de unin
opcional, como se discute en Opcional Binding .
GRAMTICA DE UNA SENTENCIA WHILE
while-statement whilewhile-conditioncode-block
while-condition expression declaration
Hgalo hasta instruccin (Do-While)
A do while sentencia permite un bloque de cdigo que se ejecutar una o varias
veces, siempre y cuando una condicin se mantiene fiel.
A do while declaracin tiene la siguiente forma:
do {
statements
} while condition
A do while sentencia se ejecuta de la siguiente manera:
1. El programa ejecuta las declaraciones , y la ejecucin contina con el paso 2.
2. La condicin es evaluada.
Si cierto , la ejecucin vuelve al paso 1 Si falso , el programa ha terminado de
ejecutar el do - mientrascomunicado.
Debido a que el valor de la condicin se evala despus de las declaraciones se
ejecutan, las declaracionesen un do - , mientras que la declaracin se ejecutan al
menos una vez.
El valor de la condicin debe tener un tipo que se ajusta a
la BooleanType protocolo. La condicin tambin puede ser una declaracin de unin
opcional, como se discute en Opcional Binding .
GRAMTICA DE UNA DECLARACIN DO-WHILE
do-while-statement docode-blockwhilewhile-condition
Declaraciones Branch
Declaraciones Branch permiten al programa para ejecutar ciertas partes de cdigo en
funcin del valor de una o ms condiciones. Los valores de las condiciones
especificadas en un comunicado rama controlan la forma, por lo tanto, lo que el bloque
325
de cdigo se ejecuta el programa se bifurca y,. Swift tiene dos declaraciones sucursal:
un si declaracin y un interruptor comunicado.
El flujo de control en un interruptor de declaracin puede ser modificada por
una ruptura declaracin y se discute en sentencia break abajo.
GRAMTICA DE UNA DECLARACIN DE LA RAMA
branch-statement if-statement
branch-statement switch-statement
Si Declaracin
Un if de declaracin se utiliza para ejecutar cdigo basado en la evaluacin de una o
ms condiciones.
Hay dos formas bsicas de un if declaracin. En cada formulario, se requiere que las
llaves de apertura y cierre.
La primera forma permite que el cdigo se ejecuta slo cuando una condicin es
verdadera y tiene la siguiente forma:
if condition {
statements
}
La segunda forma de un si declaracin proporciona un adicional clusula
else (introducido por la otra palabra clave) y se utiliza para ejecutar una parte de
cdigo cuando la condicin es verdadera y otra parte del cdigo cuando la misma
condicin es falsa. Cuando una sola clusula ms est presente, un caso
de declaracin tiene la siguiente forma:
if condition {
statements to execute if condition is true
} else {
statements to execute if condition is false
}
La clusula else de un caso de declaracin puede contener otro si la declaracin
para poner a prueba ms de una condicin. Un caso de declaracin encadenado
juntos de esta manera tiene la siguiente forma:
if condition 1 {
statements to execute if condition 1 is true
} else if condition 2 {
statements to execute if condition 2 is true
} else {
statements to execute if both conditions are false
326
}
El valor de cualquier condicin en un caso de declaracin debe tener un tipo que se
ajusta a la BooleanTypeprotocolo. La condicin tambin puede ser una declaracin
de unin opcional, como se discute en Opcional Binding .
GRAMTICA DE UNA SENTENCIA IF
if-statement ifif-conditioncode-blockelse-clauseopt
if-condition expression declaration
else-clause elsecode-block elseif-statement
Sentencia switch
Un switch de declaracin permite que ciertos bloques de cdigo a ejecutar en
funcin del valor de una expresin de control.
Una sentencia switch tiene la siguiente forma:
case pattern 1 :
statements
default:
statements
}
La expresin de control del switch de declaracin se evala y se compara entonces
con los patrones especificados en cada caso. Si se encuentra una coincidencia, el
programa ejecuta las declaraciones que figuran en el marco de ese caso. El alcance de
cada caso no puede estar vaco. Como resultado, debe incluir al menos una declaracin
despus de los dos puntos ( : ) de cada etiqueta de la caja. Use un solo break
declaracin si usted no tiene intencin de ejecutar cualquier cdigo en el cuerpo de un
caso compatible.
Los valores de las expresiones de su cdigo puede ramificar en son muy flexibles. Por
ejemplo, adems de los valores de los tipos escalares, como enteros y caracteres, su
cdigo puede ramificarse en los valores de cualquier tipo, incluidos los nmeros de
punto flotante, cadenas, tuplas, las instancias de clases personalizadas, y opcionales. El
valor de la expresin de control incluso puede ser igualada al valor de un caso en una
enumeracin y se comprueba para su inclusin en un rango especificado de
327
valores. Para obtener ejemplos de cmo utilizar estos diversos tipos de valores en los
switch declaraciones, consulte Switch en el control de flujo captulo.
Un switch de caso puede contener opcionalmente una expresin guardia despus de
cada patrn. Unprotector de expresin se introduce por la palabra clave , where
seguido por una expresin, y se utiliza para proporcionar una condicin adicional antes
de un patrn en un caso se considera adaptado a la expresin de control . Si una
expresin guardia est presente, las declaraciones en el caso pertinente slo se ejecutan
si el valor de la expresin de control coincide con uno de los patrones del caso y la
expresin guardia evala comoverdadera . Por ejemplo, una expresin de
control coincide con el caso en el ejemplo siguiente slo si es una tupla que contiene
dos elementos del mismo valor, tales como (1, 1) .
328
329
Sentencia break
Un break declaracin termina la ejecucin del programa de un bucle o un switch
de declaracin. Una break comunicado puede consistir en slo la palabra
clave break, o puede consistir en la palabra clave break seguido del nombre de una
etiqueta de declaracin, como se muestra a continuacin.
break
continue
330
return
return expression
Cuando un return declaracin es seguida por una expresin, el valor de la expresin
se devuelve a la funcin de llamada o mtodo. Si el valor de la expresin no coincide
con el valor del tipo de retorno declarado en la declaracin de la funcin o mtodo, el
valor de la expresin se convierte en el tipo de retorno antes de que se devuelve a la
funcin de llamada o mtodo.
Cuando un return declaracin no es seguido por una expresin, que puede ser
utilizado slo para volver de una funcin o mtodo que no devuelve un valor (es decir,
cuando el tipo de retorno de la funcin o mtodo esvaco o () ).
GRAMTICA DE UNA SENTENCIA RETURN
return-statement returnexpressionopt
331
Declaraciones
Una declaracin introduce un nuevo nombre o construir en su programa. Por ejemplo,
utiliza las declaraciones de introducir funciones y mtodos, variables y constantes, y
para definir nuevos tipos de enumeracin, estructura, clase, y de protocolo, con
nombre. Tambin puede utilizar una declaracin para extender el comportamiento de un
tipo con nombre existente e importar smbolos en el programa que se declar en otro
lugar.
En Swift, la mayora de las declaraciones son tambin las definiciones en el sentido de
que se implementan o inicializadas a la vez que se declaran. Dicho esto, ya que los
protocolos no implementan sus miembros, la mayora de los miembros de protocolo son
slo declaraciones. Por comodidad y porque la distincin no es tan importante en el
Swift, el plazo de declaracin abarca tanto las declaraciones y definiciones.
GRAMTICA DE UNA DECLARACIN
declaration import-declaration
declaration constant-declaration
declaration variable-declaration
declaration typealias-declaration
declaration function-declaration
declaration enum-declaration
declaration struct-declaration
declaration class-declaration
declaration protocol-declaration
declaration initializer-declaration
declaration deinitializer-declaration
declaration extension-declaration
declaration subscript-declaration
declaration operator-declaration
declarations declarationdeclarationsopt
De nivel superior Cdigo
El cdigo de nivel superior en un archivo fuente Swift consiste en cero o ms
declaraciones, declaraciones y expresiones. Por defecto, las variables, constantes, y
otras declaraciones con nombre que se declar en el nivel superior de un archivo de
origen se puede acceder al cdigo en cada archivo de origen que es parte del mismo
mdulo. Puede anular este comportamiento predeterminado marcando la declaracin
con un modificador de nivel de acceso, como se describe en los niveles de control de
acceso .
GRAMTICA DE UNA DECLARACIN DE ALTO NIVEL
top-level-declaration statementsopt
332
Bloques de Cdigo
Un bloque de cdigo es utilizado por una variedad de declaraciones y las estructuras de
control de los estados agrupar. Tiene la siguiente forma:
{
statements
}
Las declaraciones dentro de un bloque de cdigo incluyen declaraciones, expresiones y
otros tipos de sentencias y se ejecutan en el orden en que aparecen en el cdigo fuente.
GRAMTICA DE UN BLOQUE DE CDIGO
code-block {statementsopt}
Declaracin de Importacin
Una declaracin de importacin le permite acceder a los smbolos que se declaran fuera
del archivo actual.La forma bsica importa todo el mdulo; que consiste en
la importacin de palabra clave seguida de un nombre de mdulo:
import module
Proporcionar ms lmites que se detalle smbolos importan-puede especificar un
submdulo especfico o una declaracin especfica dentro de un grupo o
mdulo. Cuando se utiliza esta forma detallada, slo el smbolo importado (y no el
mdulo que lo declara) se pone a disposicin en el mbito actual.
333
334
get {
statements
}
Usted define esta forma de una declaracin de variable en el mbito global, el alcance
local de una funcin, o en el contexto de una estructura, enumeracin o ampliacin de
declaracin de clase. Cuando una declaracin de variable de esta forma se declara en el
mbito global o del mbito local de una funcin, que se conoce como la variable
calculada . Cuando se declara en el contexto de una estructura o ampliacin de
declaracin de clase, que se conoce como una propiedad calculada .
El captador se utiliza para leer el valor, y el colocador se utiliza para escribir el
valor. La clusula setter es opcional, y cuando slo se necesita un captador, puede
omitir ambas clusulas y devuelva el valor solicitado directamente, como se describe
335
}
Usted define esta forma de una declaracin de variable en el mbito global, el alcance
local de una funcin, o en el contexto de una declaracin de clase o estructura. Cuando
una declaracin de variable de esta forma se declara en el mbito global o del mbito
local de una funcin, los observadores se refieren comoobservadores variables
almacenadas . Cuando se declara en el contexto de una declaracin de clase o
estructura, los observadores se les conoce como los observadores de propiedad .
Puede agregar observadores de propiedad a cualquier propiedad almacenado. Tambin
puede agregar los observadores de propiedad a cualquier propiedad heredada (si
almacena o calcula) por razones imperiosas de la propiedad dentro de una subclase,
como se describe en observadores Overriding propiedad .
El inicializador de expresin es opcional en el contexto de una declaracin de clase o
estructura, pero requerido en otro lugar. Se requiere que la anotacin de tipo en todas las
declaraciones de variables que incluyen observadores, sin importar el contexto en el que
se declaran.
Los willSet y didSet observadores proporcionan una manera de observar (y para
responder adecuadamente) cuando se est estableciendo el valor de una variable o
propiedad. Los observadores no se les llama cuando la variable o propiedad se inicializa
336
por primera vez. En su lugar, se les llama slo cuando el valor se establece fuera de un
contexto de inicializacin.
A willSet observador se llama justo antes de que se fije el valor de la variable o
propiedad. El nuevo valor se pasa a la willSet observador como una constante, y por
lo tanto no se puede cambiar en la aplicacin de
lawillSet clusula. El didSet observador se llama inmediatamente despus de que
el nuevo valor se establece.En contraste con la willSet observador, el antiguo valor
de la variable o la propiedad se pasa al didSetobservador en caso de que todava
necesita el acceso a la misma. Dicho esto, si se asigna un valor a una variable o
propiedad dentro de su propio didSet clusula observador, ese nuevo valor que asigne
sustituir a la que se acaba de establecer y pasa al willSet observador.
El nombre del organismo y que encierran entre parntesis en
las willSet y didSet clusulas son opcionales.Si usted proporciona nombres setter,
que se utilizan como los nombres de los parmetros a
los willSet ydidSet observadores. Si usted no proporciona nombres setter, el
nombre del parmetro por defecto para elwillSet observador es nuevoValor y el
nombre del parmetro por defecto para el didSet observador esoldValue .
El didSet clusula es opcional cuando se proporciona un willSet clusula. Del
mismo modo, la willSetclusula es opcional cuando se proporciona
un didSet clusula.
Para obtener ms informacin y para ver un ejemplo de cmo utilizar los observadores
de propiedades, consulte Observadores propiedad .
Clase y propiedades de variables estticas
Para declarar una clase computarizada propiedad, marque la declaracin con
la clase modificador declaracin. Para declarar una propiedad esttica variables,
marque la declaracin con la estticamodificador declaracin. Las propiedades de
clase y estticas se discuten en Tipo de Propiedades .
GRAMTICA DE UNA DECLARACIN DE VARIABLE
variable-declaration variable-declaration-headpattern-initializer-list
variable-declaration variable-declaration-headvariable-nametype-annotationcodeblock
variable-declaration variable-declaration-headvariable-nametype-annotationgettersetter-block
variable-declaration variable-declaration-headvariable-nametype-annotationgettersetter-keyword-block
variable-declaration variable-declaration-headvariable-nametype-annotationinitializeroptwillSet-didSet-block
variable-declaration-head attributesoptdeclaration-modifiersoptvar
variable-name identifier
getter-setter-block {getter-clausesetter-clauseopt}
getter-setter-block {setter-clausegetter-clause}
getter-clause attributesoptgetcode-block
setter-clause attributesoptsetsetter-nameoptcode-block
337
setter-name (identifier)
getter-setter-keyword-block {getter-keyword-clausesetter-keyword-clauseopt}
getter-setter-keyword-block {setter-keyword-clausegetter-keyword-clause}
getter-keyword-clause attributesoptget
setter-keyword-clause attributesoptset
willSet-didSet-block {willSet-clausedidSet-clauseopt}
willSet-didSet-block {didSet-clausewillSet-clause}
willSet-clause attributesoptwillSetsetter-nameoptcode-block
didSet-clause attributesoptdidSetsetter-nameoptcode-block
Escriba Declaracin Alias
Una declaracin de tipo alias introduce un alias llamado de un tipo existente en su
programa. Tipo declaraciones de alias se declaran utilizando la palabra
clave typealias y tienen la siguiente forma:
}
If the function has a return type of Void, the return type can be omitted as follows:
}
El tipo de cada parmetro debe ser incluido-no se puede inferir. Aunque los parmetros
a una funcin son constantes por defecto, usted puede escribir dej delante del nombre
338
de un parmetro para enfatizar este comportamiento. Escribir var delante del nombre
de un parmetro para que sea una variable, la determinacin del alcance cualquier
cambio realizado en la variable slo para el cuerpo de la funcin, o escribir inout para
hacer esos cambios se aplican tambin al argumento de que fue aprobada en el alcance
de la persona que llama. Para un anlisis de los parmetros de salida, consulte InParmetros que .
Las funciones pueden devolver varios valores con un tipo tupla como el tipo de retorno
de la funcin.
Una definicin de funcin puede aparecer dentro de otra declaracin de la funcin. Este
tipo de funcin se conoce como una funcin anidada . Para un anlisis de las funciones
anidadas, consulte Funciones anidadas.
Nombres de parmetros
Parmetros de la funcin son una lista separada por comas donde cada parmetro tiene
una de varias formas. El orden de argumentos en una llamada a la funcin debe
coincidir con el orden de los parmetros en la declaracin de la funcin. La entrada ms
simple en una lista de parmetros tiene la siguiente forma:
parameter name : parameter type
Para los parmetros de funcin, el nombre del parmetro se utiliza en el cuerpo de la
funcin, pero no se utiliza cuando se llama a la funcin. Para los parmetros del
mtodo, el nombre del parmetro se utiliza como dentro del cuerpo de la funcin, y
tambin se utiliza como una etiqueta para el argumento al llamar al mtodo.El nombre
del primer parmetro de un mtodo slo se utiliza dentro del cuerpo de la funcin, como
el parmetro de una funcin. Por ejemplo:
return y + String(x)
class C {
return y + String(x)
let c = C()
339
_ : parameter type
340
Funciones Curried
Puede volver a escribir una funcin que toma varios parmetros como una funcin
equivalente que toma un solo parmetro y devuelve una funcin. La funcin devuelto
tiene el siguiente parmetro y devuelve otra funcin. Esto contina hasta que no hay
parmetros restantes, momento en el que la ltima funcin devuelve el valor de retorno
de la funcin de mltiples parmetros originales. La funcin reescrito se conoce como
unafuncin de curry . Por ejemplo, se puede reescribir la addTwoInts funcionan
como el equivalenteaddTwoIntsCurried funcin:
return a + b
return a + b
return addTheOtherInt
}
El addTwoInts funcin toma dos enteros y devuelve el resultado de
sumarlos. El addTwoIntsCurried funcin toma un solo entero, y devuelve otra
funcin que toma el segundo entero y lo aade a la primera. (La funcin anidada captura
el valor del primer argumento nmero entero de la funcin envolvente.)
En Swift, puede escribir una funcin al curry ms concisa con la siguiente sintaxis:
func function name ( parameter )( parameter ) -> return type {
statements
}
Por ejemplo, las dos declaraciones siguientes son equivalentes:
return a + b
return a + b
return addTheOtherInt
}
Para utilizar el addTwoIntsCurried funcionan de la misma manera que el
noncurried addTwoInts funcin, debe llamar a la addTwoIntsCurried funcin
con el primer argumento entero y luego llamar a su funcin vuelto con el segundo
argumento entero:
341
// Devuelve un valor de 9
addTwoIntsCurried(4)(5)
// Devuelve un valor de 9
Aunque usted debe proporcionar los argumentos a una funcin noncurried todos a la vez
en una sola llamada, usted puede utilizar el formulario al curry de una funcin de
proporcionar argumentos en varias llamadas a funciones, una a la vez (incluso en
diferentes lugares en su cdigo). Esto se conoce comoaplicacin de funcin
parcial . Por ejemplo, puede aplicar el addTwoIntsCurried funcin a un
argumento entero1 y asignar el resultado a la constante PlusOne :
addTwoInts(4, 5)
plusOne(10)
// Devuelve un valor de 11
GRAMTICA DE UNA DECLARACIN DE FUNCIN
function-declaration function-headfunction-namegeneric-parameter-clauseoptfunction-signaturefunction-body
function-head attributesoptdeclaration-modifiersoptfunc
function-name identifier operator
function-signature parameter-clausesfunction-resultopt
function-result ->attributesopttype
function-body code-block
parameter-clauses parameter-clauseparameter-clausesopt
parameter-clause () (parameter-list...opt)
parameter-list parameter parameter,parameter-list
parameter inoutoptletopt#optexternal-parameter-nameoptlocal-parameter-nametypeannotationdefault-argument-clauseopt
parameter inoutoptvar#optexternal-parameter-nameoptlocal-parameter-nametypeannotationdefault-argument-clauseopt
parameter attributesopttype
external-parameter-name identifier _
local-parameter-name identifier _
default-argument-clause =expression
Declaracin Enumeracin
Una declaracin de la enumeracin introduce un tipo de enumeracin llamado en su
programa.
Declaraciones de enumeracin tienen dos formas bsicas y se declaran usando la
palabra clave enum . El cuerpo de una enumeracin declarada utilizando formulario
342
}
Enumeraciones declaradas en esta forma a veces se llaman uniones discriminadas en
otros lenguajes de programacin.
En esta forma, cada bloque caso consiste en la palabra clave caso seguido por uno o
ms casos de enumeracin, separados por comas. El nombre de cada caso debe ser
nico. Cada caso tambin puede especificar que almacena los valores de un tipo
determinado. Estos tipos se especifican en el tipo de valor asociado tupla,
inmediatamente despus del nombre del caso. Para obtener ms informacin y ver
ejemplos de casos con tipos de valor asociadas, ver valores asociados .
Las enumeraciones con casos de un tipo de valor crudo
La forma siguiente declara un tipo de enumeracin que contiene los casos de
enumeracin del mismo tipo bsico:
343
En esta forma, cada bloque caso consiste en la palabra clave caso , seguido de uno o
ms casos de enumeracin, separados por comas. A diferencia de los casos en la
primera forma, cada caso tiene un valor subyacente, llamado valor en bruto , del mismo
tipo bsico. El tipo de estos valores se especifica en el tipo de valor crudo y debe
representar un nmero entero, el nmero de punto flotante, cadena, o de un solo
carcter.En particular, el tipo de prima-valor debe ajustarse a la equatable protocolo
y uno de los siguientes protocolos literal
convertibles: IntegerLiteralConvertible para literales
enteros, FloatingPointLiteralConvertible para los literales de punto
flotante, StringLiteralConvertible para los literales de cadena que contienen
cualquier nmero de caracteres,
y ExtendedGraphemeClusterLiteralConvertible para literales de cadena
que contienen slo un nico carcter.
Cada caso debe tener un nombre nico y se le asigna un valor prima nica. Si no se
especifica el tipo de valor crudo como int y no asigna un valor a los casos
explcitamente, se les asigna implcitamente los valores0 , 1 , 2 , y as
sucesivamente. Cada caso sin asignar de tipo Int est implcitamente asigna un valor
en bruto que se incrementa automticamente del valor bruto del caso anterior.
case A, B, C = 5, D
}
En el ejemplo anterior, el valor bruto de ExampleEnum.A es 0 y el valor
de ExampleEnum.B es 1 . Y debido a que el valor de ExampleEnum.C se establece
explcitamente en 5 , el valor de ExampleEnum.D se incrementa automticamente a
partir de 5 y por lo tanto es 6 .
El valor en bruto de un caso de enumeracin se puede acceder llamando a
su toRaw mtodo, como enExampleEnum.B.toRaw () . Tambin puede utilizar
un valor crudo para encontrar un caso correspondiente, si es que existe, llamando a
la fromRaw mtodo, que devuelve un caso opcional. Para obtener ms informacin y
ver ejemplos de casos con tipos de valor en bruto, vea Raw Values.
Acceso Casos de enumeracin
Para hacer referencia al caso de un tipo de enumeracin, utilice punto ( . sintaxis),
como enEnumerationType.EnumerationCase . Cuando el tipo de enumeracin
puede inferirse a partir del contexto, puede omitirlo (todava se requiere que el punto),
como se describe en Sintaxis Enumeracin y Implcita Expresin miembros .
Para comprobar los valores de la enumeracin de los casos, utilizar un interruptor
de declaracin, como se muestra en juego valores de enumeracin con una sentencia
switch . El tipo de enumeracin coincide-patrn en contra de los patrones de casos de
enumeracin en los bloques de caso del interruptor de la declaracin, como se
describe en el Modelo de Enumeracin Case .
344
}
El cuerpo de una estructura contiene cero o
ms declaraciones . Estas declaraciones pueden incluir tanto almacenados y calculados
propiedades, propiedades estticas, mtodos de instancia, los mtodos estticos,
inicializadores, subndices, alias de tipo, e incluso otra estructura, clase, y las
declaraciones de enumeracin.Estructura de las declaraciones no pueden contener
deinitializer o protocolo declaraciones. Para una discusin y varios ejemplos de
estructuras que incluyen diversos tipos de declaraciones, vea Clases y Estructuras .
Tipos de estructura puede adoptar cualquier nmero de protocolos, pero no pueden
heredar de clases, enumeraciones, u otras estructuras.
Hay tres formas de crear una instancia de una estructura previamente declarado:
Llame a uno de los inicializadores declarados dentro de la estructura, como se
describe eninicializadores .
345
}
El cuerpo de una clase contiene cero o ms declaraciones . Estas declaraciones pueden
incluir tanto almacenados y calculados propiedades, mtodos de instancia, mtodos de
clase, inicializadores, un solo deinitializer, subndices, alias de tipo, e incluso otra clase,
la estructura, y las declaraciones de enumeracin.Declaraciones de clase no pueden
contener declaraciones de protocolo. Para una discusin y varios ejemplos de clases que
incluyen diversos tipos de declaraciones, vea Clases y Estructuras .
Un tipo de clase puede heredar de una sola clase padre, su superclase , pero puede
adoptar cualquier nmero de protocolos. La superclase aparece por primera vez despus
de que el nombre de la clase y el colon, seguido por cualquier protocolos
adoptados . Clases genricas pueden heredar de otras clases genricas y no genricos,
sino una clase no genrica pueden heredar slo de otras clases no genricos.Cuando se
escribe el nombre de una clase superclase genrica tras los dos puntos, debe incluir el
nombre completo de esa clase genrica, incluida su clusula de parmetro genrico.
346
Como se discuti en la Declaracin Inicializador , las clases pueden han designado y los
inicializadores de conveniencia. El inicializador designado de una clase debe inicializar
todas las propiedades declaradas de la clase y debe hacerlo antes de llamar a cualquiera
de los inicializadores designados de su superclase.
Una clase puede anular las propiedades, los mtodos, los subndices y los
inicializadores de su superclase.Propiedades alteradas temporalmente, los mtodos, los
subndices y inicializadores designados deben estar marcados con
la anulacin modificador declaracin.
Exigir que las subclases implementan inicializador de una superclase, marcan
inicializador de la superclase con el requerido modificador declaracin. La
implementacin de la subclase de que inicializador tambin debe estar marcado con
el requerido modificador declaracin.
Aunque las propiedades y mtodos declarados en la superclase son heredados por la
clase actual, inicializadores designados declarados en la superclase no lo son. Dicho
esto, si la clase actual anula todos los inicializadores designados de la superclase, hereda
inicializadores de conveniencia de la superclase.Clases Swift no heredan de una clase
base universal.
Hay dos maneras de crear una instancia de una clase declarada con anterioridad:
Llame a uno de los inicializadores declarados dentro de la clase, como se describe
en inicializadores .
Si son declarados no inicializadores, y todas las propiedades de la declaracin de
clase se les dio valores iniciales, llame inicializador por defecto de la clase, como se
describe en Inicializadores predeterminados .
Propiedades de acceso de una instancia de la clase con el punto ( . ) sintaxis, como se
describe en Acceso a las propiedades .
Las clases son tipos de referencia; instancias de una clase se denominan, en lugar de
copiar, cuando se asigna a las variables o constantes, o cuando se pasa como
argumentos de una llamada de funcin. Para obtener informacin acerca de los tipos de
referencia, consulte Estructuras y enumeraciones son tipos de valor .
Puede extender el comportamiento de un tipo de clase con una ampliacin de
declaracin, como se discuti en la Declaracin de extensin .
GRAMTICA DE UNA DECLARACIN DE CLASE
class-declaration attributesoptaccess-level-modifieroptclassclass-namegenericparameter-clauseopttype-inheritance-clauseoptclass-body
class-name identifier
class-body {declarationsopt}
Declaracin Protocolo
Una declaracin protocolo introduce un tipo de protocolo llamado en su
programa. Declaraciones de protocolo se declaran usando la palabra clave de
protocolo y tienen la siguiente forma:
347
}
El cuerpo de un protocolo contiene cero o ms declaraciones de miembros de
protocolo , que describen los requisitos de conformidad que cualquier tipo que adoptan
el protocolo debe cumplir. En particular, un protocolo puede declarar que los tipos se
ajusten deben implementar ciertas propiedades, mtodos, inicializadores y
subndices. Los protocolos tambin pueden declarar los tipos especiales de alias de tipo,
llamados tipos asociados , que pueden especificar las relaciones entre las diversas
declaraciones del protocolo. Las declaraciones de miembros protocolo se discuten en
detalle a continuacin.
Tipos de protocolo pueden heredar de cualquier nmero de otros protocolos. Cuando un
tipo de protocolo hereda de otros protocolos, el conjunto de requisitos de los otros
protocolos se agregan, y cualquier tipo que hereda de la actual protocolo debe cumplir
con todos los requisitos. Para ver un ejemplo de cmo utilizar la herencia de protocolo,
vea Herencia Protocolo .
NOTA
Tambin puede agregar los requisitos de conformidad de mltiples protocolos que
utilizan tipos de composicin del protocolo, segn se describe en el Protocolo Tipo
Composicin y Composicin Protocolo .
Usted puede agregar la conformidad de protocolo a un tipo declarado previamente
mediante la adopcin del protocolo en una ampliacin de declaracin de ese tipo. En la
extensin, debe implementar todos los requisitos del protocolo aprobado. Si el tipo ya se
implementa todos los requisitos, se puede dejar el cuerpo de la ampliacin de
declaracin vaca.
De forma predeterminada, los tipos que se ajustan a un protocolo deben implementar
todas las propiedades, mtodos y subndices declaradas en el protocolo. Dicho esto,
puede marcar estas declaraciones de miembros de protocolo con
el opcional modificador de declaracin para especificar que su aplicacin por un tipo
de conformacin es opcional. El opcional modificador slo puede aplicarse a los
protocolos que estn marcados con el objc atributo. Como resultado, slo los tipos de
clase pueden adoptar y cumplir con un protocolo que contiene requisitos miembro
opcionales. Para obtener ms informacin acerca de cmo utilizar
la opcin modificador de declaracin y de orientacin sobre cmo acceder opcional
ejemplo de protocolo miembros-para, cuando no ests seguro de si un tipo de
conformacin implementa ellos-vase Requisitos del Protocolo Facultativo .
Para restringir la adopcin de un protocolo para los tipos de clases solamente, marque el
protocolo con laclase de requerimiento por escrito la clase de palabras clave
como el primer elemento en el protocolos heredados lista despus de los dos
puntos. Por ejemplo, el siguiente protocolo puede ser adoptada slo por los tipos de
clases:
}
Cualquier protocolo que hereda de un protocolo que est marcado con la clase
de requisito puede igualmente adoped slo por los tipos de clase.
NOTA
348
349
350
init( parameters ) {
351
statements
}
Un inicializador designado de una clase inicializa todas las propiedades de la clase
directamente. No se puede llamar a cualquier otro inicializadores de la misma clase, y si
la clase tiene una superclase, debe llamar a uno de los inicializadores designados de la
superclase. Si la clase hereda todas las propiedades de su superclase, uno de
inicializadores designados de la superclase debe ser llamado antes de cualquiera de estas
propiedades pueden ser establecidas o modificadas en la clase actual.
Inicializadores designados pueden ser declarados en el contexto de slo una declaracin
de clase y, por tanto, no se pueden agregar a una clase utilizando una ampliacin de
declaracin.
Inicializadores en estructuras y enumeraciones pueden llamar a otros inicializadores
declarados a delegar parte o la totalidad del proceso de inicializacin.
Declarar inicializadores de conveniencia para una clase, marcar la declaracin
inicializador con la convenience modificador declaracin.
}
Inicializadores de Conveniencia pueden delegar el proceso de inicializacin a otro
inicializador conveniencia o para uno de los inicializadores designados de la
clase. Dicho esto, los procesos de inicializacin deben terminar con una llamada a un
inicializador designado que en ltima instancia se inicializa las propiedades de la
clase. Inicializadores de conveniencia no pueden llamar inicializadores de una
superclase.
Puede marcar designado y los inicializadores de conveniencia con el required
modificador de declaracin para exigir que cada subclase implementar el
inicializador. Aplicacin de una subclase de que inicializador tambin debe estar
marcado con el requirted modificador declaracin.
Por defecto, los inicializadores declarados en una superclase no son heredados por las
subclases. Dicho esto, si una subclase inicializa todas sus propiedades almacenados con
valores por defecto y no define ningn inicializadores de su propia, hereda todos los
inicializadores de la superclase. Si la subclase sobreescribe todos los inicializadores
designados de la superclase, hereda inicializadores de conveniencia de la superclase.
Al igual que con los mtodos, propiedades y subndices, es necesario marcar
inicializadores designados anulados con la override modificador declaracin.
NOTA
Si marca un inicializador con la required modificador de declaracin, no es tambin
marca el inicializador con la override modificador cuando omite el inicializador
requerido en una subclase.
Para ver ejemplos de inicializadores en diversas declaraciones de tipo,
consulte inicializacin .
352
deinit {
statements
}
A deinitializer se llama automticamente cuando ya no hay ninguna referencia a un
objeto de clase, justo antes de que se cancela la asignacin del objeto de clase. A
deinitializer se puede declarar slo en el cuerpo de una clase de declaracin-, pero no en
una extensin de una clase y cada clase puede tener como mximo una.
Una subclase hereda deinitializer de su superclase, que se llama implcitamente justo
antes de se desasigna el objeto subclase. El objeto subclase no se cancela la asignacin
hasta que todos deinitializers en su cadena de herencia han terminado de ejecutarse.
Deinitializers no se llaman directamente.
Para ver un ejemplo de cmo utilizar un deinitializer en una declaracin de clase,
vase deinicializacin .
GRAMTICA DE UNA DECLARACIN DEINITIALIZER
deinitializer-declaration attributesoptdeinitcode-block
Declaracin de Extensin
Una ampliacin de declaracin le permite extender el comportamiento de los tipos de
clase, estructura, enumeracin y existentes. Declaraciones de extensin se declaran
usando la palabra clave de extensin y tienen la siguiente forma:
declarations
El cuerpo de una ampliacin de declaracin contiene cero o
ms declaraciones . Estas declaraciones pueden incluir propiedades calculadas,
propiedades estticas calculadas, mtodos de instancia, los mtodos estticos y de clase,
inicializadores, declaraciones subndice, e incluso de clase, la estructura, y las
declaraciones de enumeracin. Declaraciones de extensin no pueden contener
deinitializer o protocolo declaraciones, propiedades almacenadas, observadores de
propiedad, u otras declaraciones de extensin.Para una discusin y varios ejemplos de
extensiones que incluyen diversos tipos de declaraciones, veaExtensiones .
Declaraciones de extensin pueden aadir conformidad protocolo para una clase,
estructura y tipo de enumeracin existente en los protocolos aprobados . Declaraciones
de extensin no pueden aadir herencia de clases para una clase existente, y por lo tanto
353
slo se puede especificar una lista de protocolos despus de que el nombre del tipo y el
colon.
Propiedades, mtodos y inicializadores de un tipo existente no se pueden sustituir en
una extensin de ese tipo.
Declaraciones de extensin pueden contener declaraciones de inicializador. Dicho esto,
si el tipo que est extendindose est definida en otro mdulo, una declaracin
inicializador debe delegar en un inicializador ya definido en ese mdulo para asegurar
que los miembros de ese tipo se inicializan correctamente.
GRAMTICA DE UNA AMPLIACIN DE DECLARACIN
extension-declaration access-level-modifieroptextensiontype-identifiertypeinheritance-clauseoptextension-body
extension-body {declarationsopt}
Declaracin Subndice
Un subndice declaracin le permite aadir soporte subndices para los objetos de un
tipo determinado y se utilizan normalmente para proporcionar una sintaxis conveniente
para acceder a los elementos de una coleccin, una lista o secuencia. Declaraciones
subndices se declaran utilizando la palabra clave subndice y tienen la siguiente
forma:
statements
}
Declaraciones subndices pueden aparecer slo en el contexto de una estructura,
enumeracin, extensin, o declaracin protocolo clase.
Los parmetros especifican uno o ms ndices que se utilizan para acceder a los
elementos del tipo correspondiente en una expresin de subndice (por ejemplo, la i en
la expresin object[i] ). Aunque los ndices utilizados para acceder a los elementos
pueden ser de cualquier tipo, cada parmetro debe incluir una anotacin de tipo para
especificar el tipo de cada ndice. El tipo de retorno especifica el tipo de elemento que
se est accediendo.
Al igual que con las propiedades calculadas, declaraciones subndice apoyar la lectura y
la escritura el valor de los elementos de los que se accede. El captador se utiliza para
leer el valor, y el colocador se utiliza para escribir el valor. La clusula setter es
opcional, y cuando slo se necesita un captador, puede omitir ambas clusulas y
354
devuelva directamente el valor solicitado. Dicho esto, si usted proporciona una clusula
setter, tambin debe proporcionar una clusula getter.
El nombre del organismo y los parntesis que encierran son opcionales. Si proporciona
un nombre de setter, que se utiliza como el nombre del parmetro al setter. Si no se
proporciona un nombre de setter, el nombre del parmetro por defecto para el setter
es valor . El tipo del nombre setter debe ser el mismo que el tipo de retorno .
Usted puede sobrecargar una declaracin subndice en el tipo en el que se declara,
siempre y cuando losparmetros o el tipo de retorno son diferentes de la que usted est
sobrecargando. Tambin puede anular una declaracin subndice heredado de una
superclase. Al hacerlo, debe marcar la declaracin subndice se reemplaza con
la anulacin modificador declaracin.
Tambin puede declarar subndices en el contexto de una declaracin de protocolo, tal
como se describe en la Declaracin Protocolo Subndice .
Para obtener ms informacin acerca de subndices y para ver ejemplos de
declaraciones de subndice, versubndices .
GRAMTICA DE UNA DECLARACIN SUBNDICE
subscript-declaration subscript-headsubscript-resultcode-block
subscript-declaration subscript-headsubscript-resultgetter-setter-block
subscript-declaration subscript-headsubscript-resultgetter-setter-keyword-block
subscript-head attributesoptdeclaration-modifiersoptsubscriptparameter-clause
subscript-result ->attributesopttype
Declaracin del operador
Una declaracin de operador introduce un nuevo infijo, prefijo, o operador de sufijo en
su programa y se declara utilizando la palabra clave operator .
Puede declarar los operadores de tres empotramientos diferentes: infijo, prefijo, y
postfix. La fijeza de un operador especifica la posicin relativa de un operador a sus
operandos.
Hay tres formas bsicas de una declaracin del operador, una para cada fijeza. La fijeza
de la operadora se especifica mediante el marcado de la declaracin del operador con
el infijo , prefijo o de sufijo modificador declaracin ante el operador
de la palabra clave. En cada formulario, el nombre del operador puede contener slo los
caracteres operadores definidos en Operadores .
El siguiente formulario se declara un nuevo operador infijo:
associativity associativity
}
Un operador infijo es un operador binario que se escribe entre sus dos operandos, como
el operador de suma familiarizados ( + ) en la expresin 1 + 2 .
Operadores infijos pueden especificar opcionalmente una precedencia, asociatividad, o
ambos.
355
356
357
358
@ attribute name
359
message= message
El mensaje consiste en una cadena literal.
El renamed argumento se utiliza para proporcionar un mensaje de texto
que indica el nuevo nombre para una declaracin que se ha cambiado el
nombre. El nuevo nombre se muestra por el compilador cuando se emite un
error acerca de la utilizacin de una declaracin renombrado. Tiene la
siguiente forma:
o
360
// Primera versin
o
protocol MyProtocol {
// Definicin de protocolo
protocol MyRenamedProtocol {
// Definicin de protocolo
o
o
o
Aplique este atributo a una declaracin de la funcin o mtodo para indicar que
el tipo correspondiente de esa funcin o mtodo, T , se noreturn T . Puede
marcar un tipo de funcin o mtodo con este atributo para indicar que la funcin
o el mtodo no devuelve a su invocador.
Puede sustituir una funcin o mtodo que no est marcado con
la NoReturn atributo con una funcin o mtodo que es. Dicho esto, no se
puede anular una funcin o mtodo que est marcado con el NoReturnatributo
con una funcin o mtodo que no es. Reglas similares se aplican cuando se
implementa un mtodo de protocolo en un tipo conforme.
NSCopying
Aplique este atributo a un almacenado propiedad de variable de una clase. Este
atributo hace setter de la propiedad que se sintetiza con una copia del valor
devuelto de la propiedad por el copyWithZone mtodo-en lugar del valor de
la propiedad en s. El tipo de la propiedad debe cumplir con
la NSCopying protocolo.
El NSCopying atributo se comporta de una manera similar a la de ObjectiveC copia atributo de propiedad.
NSManaged
Aplique este atributo a un almacenado propiedad de variable de una clase que
hereda de NSManagedObjectpara indicar que el almacenamiento y la
aplicacin de la propiedad se proporciona dinmicamente de Datos Bsicos en
tiempo de ejecucin basado en la descripcin de la entidad asociada.
objc
361
Aplique este atributo a toda declaracin que se puede representar en ObjectiveC, por ejemplo, las clases no anidadas, protocolos, propiedades y mtodos
(incluyendo getters y setters) de las clases y los protocolos, inicializadores,
deinitializers y subndices. El objc atributo le dice al compilador que la
declaracin est disponible para su uso en el cdigo de Objective-C.
Si aplica el objc atributo a una clase o un protocolo, se aplica implcitamente a
los miembros de esa clase o protocolo. El compilador tambin se aaden
automticamente las objc atributo a una clase que hereda de otra clase marcada
con el objc atributo. Protocolos marcados con el objc atributo no pueden
heredar de protocolos que no son.
El objc atributo opcionalmente acepta un solo argumento atributo, que consta
de un identificador. Utilice este atributo cuando desee exponer un nombre
diferente a Objective-C para la entidad la objc atributo se aplica a. Usted puede
utilizar este argumento para nombrar clases, protocolos, mtodos getters, setters,
y inicializadores. El ejemplo a continuacin expone el comprador para
el habilitado propiedad delExampleClass al cdigo de Objective-C
como isEnabled y no slo como el nombre de la propiedad en s.
@objc
class ExampleClass {
@objc(isEnabled) get {
}
UIApplicationMain
Aplicar este atributo para una clase para indicar que es el delegado aplicacin. El
uso de este atributo es equivalente a llamar la UIApplicationMain funcin
y pasando el nombre de esta clase como el nombre de la clase delegada.
Si no se utiliza este atributo, suministrar un main.swift archivo con
un principal funcin que llama a laUIApplicationMain funcin. Por
ejemplo, si su aplicacin utiliza una subclase personalizada
de UIApplicationcomo su clase principio, llame a
la UIApplicationMain funcin en lugar de utilizar este atributo.
Atributos Declaracin usados por Interface Builder
Atributos Interface Builder son atributos de declaracin utilizados por Interface Builder
para sincronizar con Xcode. Swift proporciona atributos de la interfaz siguiente
Constructor: IBAction , IBDesignable , IBInspectabley IBOutlet . Estos
atributos son conceptualmente lo mismo que sus homlogos de Objective-C.
Se aplica la IBOutlet y IBInspectable atributos a las declaraciones de
propiedades de una clase. Se aplica laIBAction atributo a declaraciones de mtodos
de una clase y la IBDesignable atributo a las declaraciones de clase.
362
Tipo Atributos
Puede aplicar los atributos de texto a slo tipos. Sin embargo, tambin se puede aplicar
el NoReturn atributo a una funcin o mtodo declaracin .
autoclosure
Este atributo se utiliza para demorar la evaluacin de una expresin envolviendo
automticamente esa expresin en un cierre sin argumentos. Aplique este
atributo a una funcin o mtodo de tipo que no toma ningn argumento y que
devuelve el tipo de la expresin. Para ver un ejemplo de cmo utilizar
elautoclosure atributo, vea Tipo de funcin .
NoReturn
Aplicar este atributo para el tipo de una funcin o mtodo para indicar que la
funcin o el mtodo no devuelve a su llamador. Tambin puede marcar una
funcin o declaracin de mtodo con este atributo para indicar que el tipo
correspondiente de esa funcin o mtodo, T , es noreturn T .
GRAMTICA DE UN ATRIBUTO
attribute @attribute-nameattribute-argument-clauseopt
attribute-name identifier
attribute-argument-clause (balanced-tokensopt)
attributes attributeattributesopt
balanced-tokens balanced-tokenbalanced-tokensopt
balanced-token (balanced-tokensopt)
balanced-token [balanced-tokensopt]
balanced-token {balanced-tokensopt}
balanced-token Any identifier, keyword, literal, or operator
balanced-token Any punctuation except (, ), [, ], {, or }
Patrones
Un patrn representa la estructura de un solo valor o un valor compuesto. Por ejemplo,
la estructura de una tupla (1, 2) es una lista separada por comas de dos
elementos. Dado que los patrones representan la estructura de un valor en lugar de
cualquier valor particular, puede hacer coincidir con una variedad de valores. Por
ejemplo, el patrn (x, y) coincide con la tupla (1, 2) y cualquier otro elemento de
la tupla de dos. Adems de hacer coincidir un patrn con un valor, puede extraer parte o
todo de un valor compuesto y unir cada parte a un nombre constante o variable.
En Swift, los patrones se producen en las declaraciones de variables y constantes (en su
lado izquierdo), en for- in las declaraciones y en los switch declaraciones (en
sus etiquetas de caso). Aunque ningn patrn puede ocurrir en las etiquetas de caso de
un switch de declaracin, en los otros contextos, slo los patrones de comodn,
patrones de identificador, y los patrones que contienen esos dos patrones pueden
ocurrir.
363
for _ in 1...3 {
let someValue = 42
Cuando el partido tiene xito, el valor 42 est obligado (asignado) para el nombre de
constante someValue .
Cuando el patrn en el lado izquierdo de una declaracin de variable o constante es un
patrn de identificador, el identificador de modelo es implcitamente un sub-patrn de
un patrn de enlace de valor-.
GRAMTICA DE UN PATRN IDENTIFICADOR
identifier-pattern identifier
Valor de Unin Patrn
Un patrn de enlace de valor- ata el valor corresponde a los nombres de variables o
constantes. Patrones de enlace de valor-que se unen un valor coincidente con el nombre
364
de una constante comenzar con la palabra clave dejar ; los que se unen al nombre de
la variable comienzan con la palabra clave var .
Identificadores de patrones dentro de un patrn de enlace de valor-se unen las nuevas
variables o constantes con nombre a sus valores coincidentes. Por ejemplo, se puede
descomponer los elementos de una tupla y enlazar el valor de cada elemento a un patrn
identificador correspondiente.
switch point {
let points = [(0, 0), (1, 0), (1, 1), (2, 0), (2, 1)]
/* ... */
365
Los parntesis alrededor de un patrn tupla que contiene un solo elemento no tienen
ningn efecto. El patrn coincide con los valores de tipo de ese solo elemento. Por
ejemplo, los siguientes son equivalentes:
let a = 2 // a: Int = 2
is type
pattern as type
El es el patrn coincide con un valor si el tipo de valor que en tiempo de ejecucin es
el mismo que el tipo especificado en el lado derecho de la que is patrn o una
subclase de ese tipo. El is el patrn se comporta como el is operador en que ambos
realizan una conversin de tipos, pero descartan el tipo devuelto.
El as patrn coincide con un valor si el tipo de ese valor en tiempo de ejecucin es el
mismo que el tipo especificado en el lado derecho de la as patrn o una subclase de
ese tipo. Si el partido tiene xito, el tipo del valor coincidente se convierte
al modelo especificado en el lado izquierdo de la as patrn.
Para ver un ejemplo que utiliza un switch de declaracin para que coincida con los
valores es y comopatrones, vea la conversin de tipos para Todas y AnyObject .
366
switch point {
default:
switch point {
default:
367
if x < y {
return y
return x
}
Debido a que Int y double , por ejemplo, ambos se ajustan a
la Comparable protocolo, esta funcin acepta argumentos de cualquier tipo. En
368
contraste con los tipos genricos, no se especifica una clusula argumento genrico
cuando se utiliza una funcin genrica o inicializador. Los argumentos de tipo en
cambio se infiere a partir del tipo de los argumentos que se pasan a la funcin o
inicializador.
369
generic-parameter type-name:protocol-composition-type
requirement-clause whererequirement-list
requirement-list requirement requirement,requirement-list
requirement conformance-requirement same-type-requirement
conformance-requirement type-identifier:type-identifier
conformance-requirement type-identifier:protocol-composition-type
same-type-requirement type-identifier==type-identifier
Clusula Argumento Genrico
Una clusula argumento genrico especifica los argumentos de tipo de un tipo
genrico. Una clusula argumento genrico est entre corchetes angulares (<>) y tiene
la siguiente forma:
< generic argument list >
La lista de argumentos genricos es una lista separada por comas de los argumentos de
tipo. Un argumento de tipo es el nombre de un tipo concreto real que sustituye a un
parmetro de tipo correspondiente en la clusula genrica de un parmetro de tipo
genrico. El resultado es una versin especializada de este tipo genrico. Como
ejemplo, la biblioteca estndar Swift define un tipo de diccionario genrico como:
/* ... */
}
La versin especializada de la genrica Diccionario tipo, Diccionario
<String, int> se forma mediante la sustitucin de los parmetros
genricos KeyType: Hashable y ValueType con los argumentos de tipo
concreto de Cuerda y Int . Cada argumento de tipo debe satisfacer todas las
restricciones del parmetro genrico al que sustituye, incluidos cualesquiera requisitos
adicionales especificados en donde clusula. En el ejemplo anterior,
el KeyType parmetro de tipo est obligado a cumplir con la Hashable protocolo y,
por tanto, de cuerdastambin debe ajustarse a la Hashable protocolo.
Tambin puede sustituir un parmetro de tipo con un argumento de tipo que es en s una
versin especializada de un tipo genrico (siempre que cumplan las restricciones y los
requisitos apropiados). Por ejemplo, puede reemplazar el parmetro de tipo T en
el array <T> con una versin especializada de una matriz, array <Int> , para
formar una matriz cuyos elementos son a su vez matrices de enteros.
370
371
switch-statement switchexpression{switch-casesopt}
switch-cases switch-caseswitch-casesopt
switch-case case-labelstatements default-labelstatements
switch-case case-label; default-label;
case-label casecase-item-list:
case-item-list patternguard-clauseopt patternguard-clauseopt,case-item-list
default-label default:
guard-clause whereguard-expression
guard-expression expression
GRAMMAR OF A LABELED STATEMENT
labeled-statement statement-labelloop-statement statement-labelswitch-statement
statement-label label-name:
label-name identifier
GRAMMAR OF A CONTROL TRANSFER STATEMENT
control-transfer-statement break-statement
control-transfer-statement continue-statement
control-transfer-statement fallthrough-statement
control-transfer-statement return-statement
GRAMMAR OF A BREAK STATEMENT
break-statement breaklabel-nameopt
GRAMMAR OF A CONTINUE STATEMENT
continue-statement continuelabel-nameopt
GRAMMAR OF A FALLTHROUGH STATEMENT
fallthrough-statement fallthrough
GRAMMAR OF A RETURN STATEMENT
return-statement returnexpressionopt
Generic Parameters and Arguments
GRAMMAR OF A GENERIC PARAMETER CLAUSE
generic-parameter-clause <generic-parameter-listrequirement-clauseopt>
generic-parameter-list generic-parameter generic-parameter,generic-parameter-list
generic-parameter type-name
generic-parameter type-name:type-identifier
generic-parameter type-name:protocol-composition-type
requirement-clause whererequirement-list
requirement-list requirement requirement,requirement-list
requirement conformance-requirement same-type-requirement
conformance-requirement type-identifier:type-identifier
conformance-requirement type-identifier:protocol-composition-type
same-type-requirement type-identifier==type-identifier
GRAMMAR OF A GENERIC ARGUMENT CLAUSE
generic-argument-clause <generic-argument-list>
generic-argument-list generic-argument generic-argument,generic-argument-list
372
generic-argument type
Declarations
GRAMMAR OF A DECLARATION
declaration import-declaration
declaration constant-declaration
declaration variable-declaration
declaration typealias-declaration
declaration function-declaration
declaration enum-declaration
declaration struct-declaration
declaration class-declaration
declaration protocol-declaration
declaration initializer-declaration
declaration deinitializer-declaration
declaration extension-declaration
declaration subscript-declaration
declaration operator-declaration
declarations declarationdeclarationsopt
GRAMMAR OF A TOP-LEVEL DECLARATION
top-level-declaration statementsopt
GRAMMAR OF A CODE BLOCK
code-block {statementsopt}
GRAMMAR OF AN IMPORT DECLARATION
import-declaration attributesoptimportimport-kindoptimport-path
import-kind typealias struct class enum protocol var func
import-path import-path-identifier import-path-identifier.import-path
import-path-identifier identifier operator
GRAMMAR OF A CONSTANT DECLARATION
constant-declaration attributesoptdeclaration-modifiersoptletpattern-initializer-list
pattern-initializer-list pattern-initializer pattern-initializer,pattern-initializer-list
pattern-initializer patterninitializeropt
initializer =expression
GRAMMAR OF A VARIABLE DECLARATION
variable-declaration variable-declaration-headpattern-initializer-list
variable-declaration variable-declaration-headvariable-nametype-annotationcodeblock
variable-declaration variable-declaration-headvariable-nametype-annotationgettersetter-block
variable-declaration variable-declaration-headvariable-nametype-annotationgettersetter-keyword-block
variable-declaration variable-declaration-headvariable-nametype-annotationinitializeroptwillSet-didSet-block
373
variable-declaration-head attributesoptdeclaration-modifiersoptvar
variable-name identifier
getter-setter-block {getter-clausesetter-clauseopt}
getter-setter-block {setter-clausegetter-clause}
getter-clause attributesoptgetcode-block
setter-clause attributesoptsetsetter-nameoptcode-block
setter-name (identifier)
getter-setter-keyword-block {getter-keyword-clausesetter-keyword-clauseopt}
getter-setter-keyword-block {setter-keyword-clausegetter-keyword-clause}
getter-keyword-clause attributesoptget
setter-keyword-clause attributesoptset
willSet-didSet-block {willSet-clausedidSet-clauseopt}
willSet-didSet-block {didSet-clausewillSet-clause}
willSet-clause attributesoptwillSetsetter-nameoptcode-block
didSet-clause attributesoptdidSetsetter-nameoptcode-block
GRAMMAR OF A TYPE ALIAS DECLARATION
typealias-declaration typealias-headtypealias-assignment
typealias-head attributesoptaccess-level-modifieropttypealiastypealias-name
typealias-name identifier
typealias-assignment =type
GRAMMAR OF A FUNCTION DECLARATION
function-declaration function-headfunction-namegeneric-parameter-clauseoptfunction-signaturefunction-body
function-head attributesoptdeclaration-modifiersoptfunc
function-name identifier operator
function-signature parameter-clausesfunction-resultopt
function-result ->attributesopttype
function-body code-block
parameter-clauses parameter-clauseparameter-clausesopt
parameter-clause () (parameter-list...opt)
parameter-list parameter parameter,parameter-list
parameter inoutoptletopt#optexternal-parameter-nameoptlocal-parameter-nametypeannotationdefault-argument-clauseopt
parameter inoutoptvar#optexternal-parameter-nameoptlocal-parameter-nametypeannotationdefault-argument-clauseopt
parameter attributesopttype
external-parameter-name identifier _
local-parameter-name identifier _
default-argument-clause =expression
GRAMMAR OF AN ENUMERATION DECLARATION
enum-declaration attributesoptaccess-level-modifieroptunion-style-enum
enum-declaration attributesoptaccess-level-modifieroptraw-value-style-enum
union-style-enum enumenum-namegeneric-parameter-clauseopttype-inheritanceclauseopt{union-style-enum-membersopt}
374
union-style-enum-members union-style-enum-memberunion-style-enum-membersopt
union-style-enum-member declaration union-style-enum-case-clause
union-style-enum-case-clause attributesoptcaseunion-style-enum-case-list
union-style-enum-case-list union-style-enum-case union-style-enum-case,unionstyle-enum-case-list
union-style-enum-case enum-case-nametuple-typeopt
enum-name identifier
enum-case-name identifier
raw-value-style-enum enumenum-namegeneric-parameter-clauseopttype-inheritanceclause{raw-value-style-enum-members}
raw-value-style-enum-members raw-value-style-enum-memberraw-value-styleenum-membersopt
raw-value-style-enum-member declaration raw-value-style-enum-case-clause
raw-value-style-enum-case-clause attributesoptcaseraw-value-style-enum-case-list
raw-value-style-enum-case-list raw-value-style-enum-case raw-value-style-enumcase,raw-value-style-enum-case-list
raw-value-style-enum-case enum-case-nameraw-value-assignmentopt
raw-value-assignment =literal
GRAMMAR OF A STRUCTURE DECLARATION
struct-declaration attributesoptaccess-level-modifieroptstructstruct-namegenericparameter-clauseopttype-inheritance-clauseoptstruct-body
struct-name identifier
struct-body {declarationsopt}
GRAMMAR OF A CLASS DECLARATION
class-declaration attributesoptaccess-level-modifieroptclassclass-namegenericparameter-clauseopttype-inheritance-clauseoptclass-body
class-name identifier
class-body {declarationsopt}
GRAMMAR OF A PROTOCOL DECLARATION
protocol-declaration attributesoptaccess-level-modifieroptprotocolprotocol-nametypeinheritance-clauseoptprotocol-body
protocol-name identifier
protocol-body {protocol-member-declarationsopt}
protocol-member-declaration protocol-property-declaration
protocol-member-declaration protocol-method-declaration
protocol-member-declaration protocol-initializer-declaration
protocol-member-declaration protocol-subscript-declaration
protocol-member-declaration protocol-associated-type-declaration
protocol-member-declarations protocol-member-declarationprotocol-memberdeclarationsopt
GRAMMAR OF A PROTOCOL PROPERTY DECLARATION
protocol-property-declaration variable-declaration-headvariable-nametypeannotationgetter-setter-keyword-block
GRAMMAR OF A PROTOCOL METHOD DECLARATION
375
protocol-method-declaration function-headfunction-namegeneric-parameter-clauseoptfunction-signature
GRAMMAR OF A PROTOCOL INITIALIZER DECLARATION
protocol-initializer-declaration initializer-headgeneric-parameter-clauseoptparameter-clause
GRAMMAR OF A PROTOCOL SUBSCRIPT DECLARATION
protocol-subscript-declaration subscript-headsubscript-resultgetter-setter-keywordblock
GRAMMAR OF A PROTOCOL ASSOCIATED TYPE
DECLARATION
protocol-associated-type-declaration typealias-headtype-inheritance-clauseopttypealias-assignmentopt
GRAMMAR OF AN INITIALIZER DECLARATION
initializer-declaration initializer-headgeneric-parameter-clauseoptparameter-clauseinitializer-body
initializer-head attributesoptdeclaration-modifiersoptinit
initializer-body code-block
GRAMMAR OF A DEINITIALIZER DECLARATION
deinitializer-declaration attributesoptdeinitcode-block
GRAMMAR OF AN EXTENSION DECLARATION
extension-declaration access-level-modifieroptextensiontype-identifiertypeinheritance-clauseoptextension-body
extension-body {declarationsopt}
GRAMMAR OF A SUBSCRIPT DECLARATION
subscript-declaration subscript-headsubscript-resultcode-block
subscript-declaration subscript-headsubscript-resultgetter-setter-block
subscript-declaration subscript-headsubscript-resultgetter-setter-keyword-block
subscript-head attributesoptdeclaration-modifiersoptsubscriptparameter-clause
subscript-result ->attributesopttype
GRAMMAR OF AN OPERATOR DECLARATION
operator-declaration prefix-operator-declaration postfix-operator-declarationinfix-operator-declaration
prefix-operator-declaration prefixoperatoroperator{}
postfix-operator-declaration postfixoperatoroperator{}
infix-operator-declaration infixoperatoroperator{infix-operator-attributesopt}
infix-operator-attributes precedence-clauseoptassociativity-clauseopt
precedence-clause precedenceprecedence-level
precedence-level A decimal integer between 0 and 255, inclusive
associativity-clause associativityassociativity
associativity left right none
GRAMMAR OF A DECLARATION MODIFIER
376
declaration-modifier class convenience dynamic final infix lazy mutatingnonmutating optional override postfix prefix required static unownedunowned(safe) unowned(unsafe) weak
declaration-modifier access-level-modifier
declaration-modifiers declaration-modifierdeclaration-modifiersopt
access-level-modifier internal internal(set)
access-level-modifier private private(set)
access-level-modifier public public(set)
access-level-modifiers access-level-modifieraccess-level-modifiersopt
Patterns
GRAMMAR OF A PATTERN
pattern wildcard-patterntype-annotationopt
pattern identifier-patterntype-annotationopt
pattern value-binding-pattern
pattern tuple-patterntype-annotationopt
pattern enum-case-pattern
pattern type-casting-pattern
pattern expression-pattern
GRAMMAR OF A WILDCARD PATTERN
wildcard-pattern _
GRAMMAR OF AN IDENTIFIER PATTERN
identifier-pattern identifier
GRAMMAR OF A VALUE-BINDING PATTERN
value-binding-pattern varpattern letpattern
GRAMMAR OF A TUPLE PATTERN
tuple-pattern (tuple-pattern-element-listopt)
tuple-pattern-element-list tuple-pattern-element tuple-pattern-element,tuple-patternelement-list
tuple-pattern-element pattern
GRAMMAR OF AN ENUMERATION CASE PATTERN
enum-case-pattern type-identifieropt.enum-case-nametuple-patternopt
GRAMMAR OF A TYPE CASTING PATTERN
type-casting-pattern is-pattern as-pattern
is-pattern istype
as-pattern patternastype
GRAMMAR OF AN EXPRESSION PATTERN
expression-pattern expression
Attributes
GRAMMAR OF AN ATTRIBUTE
attribute @attribute-nameattribute-argument-clauseopt
377
attribute-name identifier
attribute-argument-clause (balanced-tokensopt)
attributes attributeattributesopt
balanced-tokens balanced-tokenbalanced-tokensopt
balanced-token (balanced-tokensopt)
balanced-token [balanced-tokensopt]
balanced-token {balanced-tokensopt}
balanced-token Any identifier, keyword, literal, or operator
balanced-token Any punctuation except (, ), [, ], {, or }
Expressions
GRAMMAR OF AN EXPRESSION
expression prefix-expressionbinary-expressionsopt
expression-list expression expression,expression-list
GRAMMAR OF A PREFIX EXPRESSION
prefix-expression prefix-operatoroptpostfix-expression
prefix-expression in-out-expression
in-out-expression &identifier
GRAMMAR OF A BINARY EXPRESSION
binary-expression binary-operatorprefix-expression
binary-expression assignment-operatorprefix-expression
binary-expression conditional-operatorprefix-expression
binary-expression type-casting-operator
binary-expressions binary-expressionbinary-expressionsopt
GRAMMAR OF AN ASSIGNMENT OPERATOR
assignment-operator =
GRAMMAR OF A CONDITIONAL OPERATOR
conditional-operator ?expression:
GRAMMAR OF A TYPE-CASTING OPERATOR
type-casting-operator istype
type-casting-operator astype
type-casting-operator as?type
GRAMMAR OF A PRIMARY EXPRESSION
primary-expression identifiergeneric-argument-clauseopt
primary-expression literal-expression
primary-expression self-expression
primary-expression superclass-expression
primary-expression closure-expression
primary-expression parenthesized-expression
primary-expression implicit-member-expression
primary-expression wildcard-expression
GRAMMAR OF A LITERAL EXPRESSION
literal-expression literal
378
379
postfix-expression explicit-member-expression
postfix-expression postfix-self-expression
postfix-expression dynamic-type-expression
postfix-expression subscript-expression
postfix-expression forced-value-expression
postfix-expression optional-chaining-expression
GRAMMAR OF A FUNCTION CALL EXPRESSION
function-call-expression postfix-expressionparenthesized-expression
function-call-expression postfix-expressionparenthesized-expressionopttrailingclosure
trailing-closure closure-expression
GRAMMAR OF AN INITIALIZER EXPRESSION
initializer-expression postfix-expression.init
GRAMMAR OF AN EXPLICIT MEMBER EXPRESSION
explicit-member-expression postfix-expression.decimal-digits
explicit-member-expression postfix-expression.identifiergeneric-argument-clauseopt
GRAMMAR OF A SELF EXPRESSION
postfix-self-expression postfix-expression.self
GRAMMAR OF A DYNAMIC TYPE EXPRESSION
dynamic-type-expression postfix-expression.dynamicType
GRAMMAR OF A SUBSCRIPT EXPRESSION
subscript-expression postfix-expression[expression-list]
GRAMMAR OF A FORCED-VALUE EXPRESSION
forced-value-expression postfix-expression!
GRAMMAR OF AN OPTIONAL-CHAINING EXPRESSION
optional-chaining-expression postfix-expression?
Lexical Structure
GRAMMAR OF AN IDENTIFIER
identifier identifier-headidentifier-charactersopt
identifier `identifier-headidentifier-charactersopt`
identifier implicit-parameter-name
identifier-list identifier identifier,identifier-list
identifier-head Upper- or lowercase letter A through Z
identifier-head _
identifier-head U+00A8, U+00AA, U+00AD, U+00AF, U+00B2U+00B5, or
U+00B7U+00BA
identifier-head U+00BCU+00BE, U+00C0U+00D6, U+00D8U+00F6, or
U+00F8U+00FF
identifier-head U+0100U+02FF, U+0370U+167F, U+1681U+180D, or
U+180FU+1DBF
identifier-head U+1E00U+1FFF
380
381
382
operator-character operator-head
operator-character U+0300U+036F
operator-character U+1DC0U+1DFF
operator-character U+20D0U+20FF
operator-character U+FE00U+FE0F
operator-character U+FE20U+FE2F
operator-character U+E0100U+E01EF
operator-characters operator-characteroperator-charactersopt
dot-operator-head ..
dot-operator-character . operator-character
dot-operator-characters dot-operator-characterdot-operator-charactersopt
binary-operator operator
prefix-operator operator
postfix-operator operator
Types
GRAMMAR OF A TYPE
type array-type dictionary-type function-type type-identifier tuple-type optionaltype implicitly-unwrapped-optional-type protocol-composition-type metatype-type
GRAMMAR OF A TYPE ANNOTATION
type-annotation :attributesopttype
GRAMMAR OF A TYPE IDENTIFIER
type-identifier type-namegeneric-argument-clauseopt type-namegeneric-argumentclauseopt.type-identifier
type-name identifier
GRAMMAR OF A TUPLE TYPE
tuple-type (tuple-type-bodyopt)
tuple-type-body tuple-type-element-list...opt
tuple-type-element-list tuple-type-element tuple-type-element,tuple-type-element-list
tuple-type-element attributesoptinoutopttype inoutoptelement-nametype-annotation
element-name identifier
GRAMMAR OF A FUNCTION TYPE
function-type type->type
GRAMMAR OF AN ARRAY TYPE
array-type [type]
GRAMMAR OF A DICTIONARY TYPE
dictionary-type [type:type]
GRAMMAR OF AN OPTIONAL TYPE
optional-type type?
GRAMMAR OF AN IMPLICITLY UNWRAPPED OPTIONAL TYPE
implicitly-unwrapped-optional-type type!
GRAMMAR OF A PROTOCOL COMPOSITION TYPE
383
protocol-composition-type protocol<protocol-identifier-listopt>
protocol-identifier-list protocol-identifier protocol-identifier,protocol-identifier-list
protocol-identifier type-identifier
GRAMMAR OF A METATYPE TYPE
metatype-type type.Type type.Protocol
GRAMMAR OF A TYPE INHERITANCE CLAUSE
type-inheritance-clause :class-requirement,type-inheritance-list
type-inheritance-clause :class-requirement
type-inheritance-clause :type-inheritance-list
type-inheritance-list type-identifier type-identifier,type-inheritance-list
class-requirement class
384