понедельник, 16 октября 2017 г.

Язык Swift: функции


  • Функция - это самодостаточный кусок кода (слова ни о чем, но с чего то ж надо начинать);
  • Функция может быть быть без параметров и/или без возвращаемого типа;
  • Функция может возвращать несколько значений (пользуемся для этого кортежами);
  • У параметров функции есть два имени: внутреннее (локальное) имя и внешнее имя (в Swift3 оно стало называться меткой аргумента). Внутреннее имя доступно только внутри тела функции, метка аргумента может использоваться при вызове функции. Метки аргумента могут быть полезны с точки зрения читаемости кода. Метки аргументов являются частью имени функции и их наличие обязательно при вызове функции. При отсутствии меток аргумента используются локальные имена. При наличии меток аргумента - их надо обязательно использовать во время вызова функции. Если хочется писать вызов функции без метки аргумента в вызове, используйте знак подчеркивания _;
  • Метка аргумента у параметра есть всегда. По умолчанию она равна локальному имени; 
  • Параметры функции могут иметь значения по умолчанию. Эти параметры размещаются в конце списка параметров;
  • Функция может иметь переменное число параметров. Для этого используется так называемый variadic (варируемый?) параметр. Внутри функции такой параметр рассматривается как массив соответствующего типа. Список параметров функции может иметь только один варируемый параметр и он должен размещаться в самом конце этого списка и при наличии параметров со значением по умолчанию - после них.
  • Функция может изменять внешние относительно ее переменные не только через возвращаемое значение, но через список параметров. Для этого используется модификатор inout перед типом параметра при определении функции и амперсанд & перед аргументом функции при ее вызове;
  • Каждая функция имеет свой тип, который состоит из типов параметров функции и типа, возвращаемого ею. Этот тип можно использовать как и любой другой тип; Это можно использовать при передаче функции как параметра в другую функцию и/или при возвращении функции как результат работы этой другой функции;
  • Функции, в соответствии с их областью видимости, могут быть глобальными и вложенными.  Глобальные видимы во внешней области видимости. Вложенные видимы только внутри тела другой функции, где они определены, хотя они могут быть переданы "наружу" как возвращаемые объекты.
  • Замыкание в Swift - это самодостаточный блок кода, который может быть рассматриваться изолированно от других частей кода. Замыкание аналогично блоку в языках Си и объектный Си или лямбда-выражению.
  • Функции, как вложенные так и глобальные могут расматриваться как частный случай замыкания. Глобальные функции - это замыкания, которые имеют имя и не "захватывают" переменные, вложенные функции - это замыкания, которые имеют имя и могут "захватывать" переменные, находящиеся в охватывающей функции, а замыкания вообще - это функции без имени (анонимные функции, лямбда-функции), которые могут "захватывать" переменные из окружающего контекста. Что такое "захватывать" нигде явно не говорится. Такое себе интуитивное понятие.
Продемонстрируем сказанное выше кодом для playground:
 import Cocoa

func myFunc(){
    print("Hello!")
}
myFunc()

func myFunc1 () -> Void{
    print("Hello1!")
}
myFunc1()

func myFunc2() -> String{
    return "Hello2!"
}
print(myFunc2())

func myFunc3(numberOgGreatings: Int, textOfGreating: String) -> Void{
    for _ in 1...numberOgGreatings{
        print("\(textOfGreating)")
    }
}
myFunc3(numberOgGreatings: 3, textOfGreating: "Hello3!")

func theFunc() -> Void{
    print("theNothing")
}

func myFunc4(funcParameter: ()->Void){
    funcParameter()
}
myFunc4(funcParameter: theFunc)

func myFunc5()->(param1:String, param2:Int){
    let myInt: Int = 1
    let myString: String = "one"
    return (myString, myInt)
}
let returnedTuple = myFunc5()
print("string=\(returnedTuple.param1)\tinteger=\(returnedTuple.param1)")

func myFunc6(externalName1 localName1: Int, externalName2 localName2: String){
    print("\(localName1)\t\(localName2)")
}
myFunc6(externalName1: 2, externalName2: "two")

func myFunc7(labelArgument1 paramName1: Int, _ paramName2: String)->Void{
    print("\(paramName1)\t\(paramName2)")
}
myFunc7(labelArgument1:3,"three")

func myFunc8(_ myNumber:Int = 1, _ myString:String = "default hello") -> Void{
    print("\(myNumber)\t\(myString)")
}
myFunc8()

func myFunc7(_ mySum :Double , myArrayParam :Double...) -> Double{
    var sum:Double = 0;
    for term in myArrayParam{
        sum += term
    }
    return sum + mySum
}

print(myFunc7(1.1, myArrayParam: 1.2, 3.4, 5.6))

func mySwap( _ forSwap1: inout Int, _ forSwap2: inout Int) -> Void{
    let temp:Int=forSwap1
    forSwap1 = forSwap2
    forSwap2 = temp
}

var a:Int = 1
var b:Int = 2
print("\(a)\t\(b)")
mySwap(&a, &b)
print("\(a)\t\(b)")

func myFunc8(myVar1: Int, myVar2: String) -> String{
    if myVar1 < 0 || myVar2.isEmpty{
            return "False"
        }else{
            return "True"
    }
}

var myFunc9: (Int, String)->String = myFunc8
print(myFunc9(1, "0"))

func myFunc10(funcPar: (Int, String)->String)->Void{
    print(funcPar(1, "str"))
}

var myArr: [Int] = [14, 15, 16]
func myFunc11(summator: (Int, Int, Int) -> Int,members: [Int])->Int{
    return summator(members[0], members[1], members[2])
}
func mySummator(memb1: Int, memb2: Int, memb3: Int)->Int{
    return memb1 + memb2 + memb3
}
print(myFunc11(summator: mySummator, members: myArr))
Ну и добавлю еще, что, на мое мнение, концепция функции в Swift, достигла своего максимально возможного и полного развития.

Комментариев нет: