Buscar..


Uso básico

Las funciones pueden ser declaradas sin parámetros o un valor de retorno. La única información requerida es un nombre ( hello en este caso).

func hello()
{
    print("Hello World")
}

Llame a una función sin parámetros escribiendo su nombre seguido de un par de paréntesis vacío.

hello()
//output: "Hello World"

Funciones con parámetros

Las funciones pueden tomar parámetros para que su funcionalidad pueda ser modificada. Los parámetros se dan como una lista separada por comas con sus tipos y nombres definidos.

func magicNumber(number1: Int)
{
    print("\(number1) Is the magic number")
}

Nota: La sintaxis \(number1) es una Interpolación de cadena básica y se utiliza para insertar el número entero en la Cadena.

Las funciones con parámetros se llaman especificando la función por nombre y proporcionando un valor de entrada del tipo utilizado en la declaración de función.

magicNumber(5)
//output: "5 Is the magic number
let example: Int = 10
magicNumber(example)
//output: "10 Is the magic number"

Cualquier valor de tipo Int podría haber sido usado.

func magicNumber(number1: Int, number2: Int)
{
    print("\(number1 + number2) Is the magic number")
}

Cuando una función usa múltiples parámetros, el nombre del primer parámetro no es necesario para el primero, pero está en los parámetros posteriores.

let ten: Int = 10
let five: Int = 5
magicNumber(ten,number2: five)
//output: "15 Is the magic number"

Utilice nombres de parámetros externos para hacer que las llamadas de función sean más legibles.

func magicNumber(one number1: Int, two number2: Int)
{
    print("\(number1 + number2) Is the magic number")
}

let ten: Int = 10
let five: Int = 5
magicNumber(one: ten, two: five)

Establecer el valor predeterminado en la declaración de función le permite llamar a la función sin dar valores de entrada.

func magicNumber(one number1: Int = 5, two number2: Int = 10)
{
    print("\(number1 + number2) Is the magic number")
}

magicNumber()
//output: "15 Is the magic number"

Valores de retorno

Las funciones pueden devolver valores especificando el tipo después de la lista de parámetros.

func findHypotenuse(a: Double, b: Double) -> Double
{
    return sqrt((a * a) + (b * b))
}

let c = findHypotenuse(3, b: 5)
//c = 5.830951894845301

Las funciones también pueden devolver múltiples valores utilizando tuplas.

func maths(number: Int) -> (times2: Int, times3: Int)
{
    let two = number * 2
    let three = number * 3
    return (two, three)
}
let resultTuple = maths(5)
//resultTuple = (10, 15)

Errores de lanzamiento

Si desea que una función pueda generar errores, debe agregar la palabra clave de throws después de los paréntesis que contienen los argumentos:

func errorThrower()throws -> String {}

Cuando quieras lanzar un error, usa la palabra clave throw :

func errorThrower()throws -> String {
  if true {
    return "True"
  } else {
    // Throwing an error
    throw Error.error 
  }
}

Si desea llamar a una función que puede generar un error, debe usar la palabra clave try en un bloque do :

do {
  try errorThrower()
}

Para más información sobre los errores de Swift: Errores

Métodos

Los métodos de instancia son funciones que pertenecen a instancias de un tipo en Swift (una clase , estructura , enumeración o protocolo ). Los métodos de tipo se llaman en un tipo en sí.

Métodos de instancia

Los métodos de instancia se definen con una declaración de func dentro de la definición del tipo, o en una extensión .

class Counter {
    var count = 0
    func increment() {
        count += 1
    }
}

El método de instancia increment() se llama en una instancia de la clase Counter :

let counter = Counter()  // create an instance of Counter class   
counter.increment()      // call the instance method on this instance

Métodos de tipo

Los métodos de tipo se definen con las palabras clave static func . (Para las clases, class func define un método de tipo que puede ser reemplazado por subclases).

class SomeClass {
    class func someTypeMethod() {
        // type method implementation goes here
    }
}
SomeClass.someTypeMethod()  // type method is called on the SomeClass type itself

Parámetros de entrada

Las funciones pueden modificar los parámetros pasados ​​a ellos si están marcados con la palabra clave inout . Al pasar un inout parámetro a una función, la persona que llama debe agregar una & al que se pasa la variable.

func updateFruit(fruit: inout Int) {
    fruit -= 1
}

var apples = 30 // Prints "There's 30 apples"
print("There's \(apples) apples")

updateFruit(fruit: &apples)

print("There's now \(apples) apples") // Prints "There's 29 apples".

Esto permite que la semántica de referencia se aplique a tipos que normalmente tendrían una semántica de valor.

Sintaxis de cierre de seguimiento

Cuando el último parámetro de una función es un cierre.

func loadData(id: String, completion:(result: String) -> ()) {
    // ...
    completion(result:"This is the result data")
}

la función se puede invocar mediante la sintaxis de cierre de seguimiento

loadData("123") { result in
    print(result)
}

Los operadores son funciones

Operadores como + , - , ?? son un tipo de función nombrada usando símbolos en lugar de letras. Se invocan de forma diferente a las funciones:

  • Prefijo: - x
  • Infijo: x + y
  • Postfijo: x ++

Puede leer más sobre operadores básicos y operadores avanzados en The Swift Programming Language.

Parámetros variables

A veces, no es posible enumerar la cantidad de parámetros que una función podría necesitar. Considere una función de sum :

func sum(_ a: Int, _ b: Int) -> Int {
    return a + b
}

Esto funciona bien para encontrar la suma de dos números, pero para encontrar la suma de tres tendríamos que escribir otra función:

func sum(_ a: Int, _ b: Int, _ c: Int) -> Int {
    return a + b + c
}

y uno con cuatro parámetros necesitaría otro, y así sucesivamente. Swift hace posible definir una función con un número variable de parámetros utilizando una secuencia de tres períodos: ... Por ejemplo,

func sum(_ numbers: Int...) -> Int {
    return numbers.reduce(0, combine: +)
}

Observe cómo el parámetro numbers , que es variadic, se fusiona en una única Array de tipo [Int] . Esto es cierto en general, los parámetros variables del tipo T... son accesibles como [T] .

Esta función ahora se puede llamar así:

let a = sum(1, 2) // a == 3
let b = sum(3, 4, 5, 6, 7) // b == 25

Un parámetro variadic en Swift no tiene que aparecer al final de la lista de parámetros, pero solo puede haber uno en cada firma de función.

A veces, es conveniente poner un tamaño mínimo en el número de parámetros. Por ejemplo, realmente no tiene sentido tomar la sum de ningún valor. Una manera fácil de hacer cumplir esto es colocando algunos parámetros requeridos no variados y luego agregando el parámetro variadic después. Para asegurarnos de que solo se pueda llamar a la sum con al menos dos parámetros, podemos escribir

func sum(_ n1: Int, _ n2: Int, _ numbers: Int...) -> Int {
    return numbers.reduce(n1 + n2, combine: +)
}

sum(1, 2) // ok
sum(3, 4, 5, 6, 7) // ok
sum(1) // not ok
sum() // not ok

Subíndices

Las clases, estructuras y enumeraciones pueden definir subíndices, que son accesos directos para acceder a los elementos miembros de una colección, lista o secuencia.

Ejemplo

struct DaysOfWeek {
  
  var days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
  
  subscript(index: Int) -> String {
    get {
      return days[index]
    }
    set {
      days[index] = newValue
    }
  }
}

Uso de subíndices

var week = DaysOfWeek()
//you access an element of an array at index by array[index].
debugPrint(week[1])
debugPrint(week[0])
week[0] = "Sunday"
debugPrint(week[0])

Opciones de subíndices:

Los subíndices pueden tomar cualquier número de parámetros de entrada, y estos parámetros de entrada pueden ser de cualquier tipo. Los subíndices también pueden devolver cualquier tipo. Los subíndices pueden usar parámetros variables y parámetros variadic, pero no pueden usar parámetros in-out o proporcionar valores de parámetros predeterminados.

Ejemplo:

struct Food {
  
  enum MealTime {
    case Breakfast, Lunch, Dinner
  }
  
  var meals: [MealTime: String] = [:]
  
  subscript (type: MealTime) -> String? {
    get {
      return meals[type]
    }
    set {
      meals[type] = newValue
    }
  }
}

Uso

var diet = Food()
diet[.Breakfast] = "Scrambled Eggs"
diet[.Lunch] = "Rice"

debugPrint("I had \(diet[.Breakfast]) for breakfast")

Funciones con cierres

El uso de funciones que toman y ejecutan cierres puede ser extremadamente útil para enviar un bloque de código para que se ejecute en otro lugar. Podemos comenzar permitiendo que nuestra función tome un cierre opcional que (en este caso) devolverá Void .

func closedFunc(block: (()->Void)? = nil) {
    print("Just beginning")

    if let block = block {
        block()
    }
}

Ahora que nuestra función ha sido definida, llamémosla y pasemos algún código:

closedFunc() { Void in
    print("Over already")
}

Al utilizar un cierre final con nuestra llamada de función, podemos pasar el código (en este caso, print ) para que se ejecute en algún punto dentro de nuestra función closedFunc() .

El registro debe imprimir:

Recién empezando

Sobre ya


Un caso de uso más específico de esto podría incluir la ejecución de código entre dos clases:

class ViewController: UIViewController {

    override func viewDidLoad() {
        let _  = A.init(){Void in self.action(2)}
    }

    func action(i: Int) {
        print(i)
    }
}


class A: NSObject {
    var closure : ()?

    init(closure: (()->Void)? = nil) {
        // Notice how this is executed before the  closure
        print("1")
        // Make sure closure isn't nil
        self.closure = closure?()
    }
}

El registro debe imprimir:

1

2

Funciones de paso y retorno.

La siguiente función está devolviendo otra función como su resultado, que puede ser asignada posteriormente a una variable y llamada:

func jediTrainer () -> ((String, Int) -> String) {
  func train(name: String, times: Int) -> (String) {
    return "\(name) has been trained in the Force \(times) times"
  }
  return train
}

let train = jediTrainer()
train("Obi Wan", 3)

Tipos de funciones

Cada función tiene su propio tipo de función, compuesto por los tipos de parámetros y el tipo de retorno de la función en sí. Por ejemplo la siguiente función:

func sum(x: Int, y: Int) -> (result: Int) { return x + y }

tiene un tipo de función de:

(Int, Int) -> (Int)

Por lo tanto, los tipos de función se pueden usar como tipos de parámetros o como tipos de retorno para funciones de anidamiento.



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow