Swift教程之函数

import Foundation

//func 函数名(形参: 形参类型) -> 返回类型
//MARK:----------1.函数定义-----------
//单参数
func sayHello(name: String) -> String
{
    return "Hello again, " + name + "!"
}
//函数调用
print(sayHello("小红"))

//多参数
func sub(a: Int, b: Int) -> Int
{
    return b - a
}
print(sub(1, b: 10))

//无参数
func sayHelloWorld() -> String
{
    return "hello, world"
}
print(sayHelloWorld())
// prints "hello, world”

//无返回值
func sayGoodbye(personName: String)
{
    print("Goodbye, \(personName)!")
}
sayGoodbye("小红")
// prints "Goodbye, 小红!”

//1.3.1被调用时,一个函数的返回值可以被忽略
func printAndCount(str: String) -> Int
{
    print(str)
    return str.characters.count //定义了有返回值的函数必须返回一个值
}
func printWithoutCounting(str: String)
{
    printAndCount(str)        //printAndCount 函数的返回值可以被忽略
}
printAndCount("hello, world")
printWithoutCounting("hello, world")

//1.4多重返回值函数(Functions with Multiple Return Values)
//你可以用元组(tuple)类型让多个值作为一个复合值从函数中返回
func count(string: String) -> (vs: Int, cs: Int, os: Int)
{
    var vowels = 0, consonants = 0, others = 0
    for character in string.characters
    {
        switch String(character).lowercaseString
        {
            case "a", "e", "i", "o", "u":
                ++vowels
            case "b", "c", "d", "f", "g", "h", "j", "k", "l", "m",
            "n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z":
                ++consonants
            default:
                ++others
        }
    }
    //返回元组
    return (vowels, consonants, others)
}
let total = count("some arbitrary string!")
print("\(total.vs) 元音字母 and \(total.cs) 辅音字母")
// prints "6 vowels and 13 consonants”


//MARK:-------2.参数名---------
//2.1外部参数名
func someFunction(name: String,age:Int)
{
    
}
someFunction("John", age: 20)


//2.3默认参数值(Default Parameter Values)
//你可以在函数体中为每个参数定义默认值。当默认值被定义后,调用这个函数时可以略去这个参数
func join(string s1: String, toString s2: String, withJoiner joiner: String = " ") -> String
{
    return s1 + joiner + s2
}
//1、指定第三个参数
let str1 = join(string: "hello", toString: "world", withJoiner: "-")
print("str1:"+str1)
// returns "str1:hello-world"

//2、不指定参数,将使用默认值
let str2 = join(string: "hello", toString:"world")
print("str2:"+str2)
// returns "str2:hello-world"


//MARK:---------3.可变参数------------
//一个函数最多能有一个可变参数
//可变参数必须放在参数表中最后的位置

//求所有数的平均值
func arithmeticMean(numbers: Double...) -> Double
{
    var sum: Double = 0
    for i in numbers
    {
        sum += i
    }
    return sum / Double(numbers.count)
}
print(arithmeticMean(1, 2, 3, 4, 5))
print(arithmeticMean(3, 8, 19))

//MARK:-----------4.常量参数和变量参数------------

//通过在参数名前加关键字 var 来定义变量参数
func changeString(var name: String, i: Int, char: Character) -> String
{
    let number = i - name.characters.count
    for _ in 1...number
    {
        //在字符串的前面添加字符(char)
        name.insert(char, atIndex: name.startIndex)
        //        name = char + name
    }
    return name
}
let string1 = "hello"
let string2 = changeString(string1, i: 10, char: "-")
print("string1:" + string1)
print("string2:" + string2)


//MARK---------5.输入输出参数----------

/*
定义一个输入输出参数时,在参数定义前加 inout 关键字
输入输出参数不能有默认值,而且可变参数不能用 inout 标记。如果你用 inout 标记一个参数,这个参数不能被 var 或者 let 标记。
*/
//交换a和b的值
func changeAandB(inout a: Int, inout b: Int)
{
    let tempA = a
    a = b
    b = tempA
}
//只能传入一个变量作为输入输出参数
var a = 3
var b = 107
//当传入的参数作为输入输出参数时,需要在参数前加&符,表示这个值可以被函数修改
changeAandB(&a, b: &b)
print("a现在是 \(a), and b现在是 \(b)")


//MARK:------6.函数类型------------
//(是一种数据类型,类似 C语言函数指针、OC语言的Block)
//分三步:1、定义函数;2、声明函数类型变量或常量;3、给函数类型变量赋值

//1、定义函数

func sum(a: Int, b: Int) -> Int
{
    return a + b
}
//2、声明函数类型变量
//3、给函数类型变量赋值
var mathFunc = sum

//4、使用
print("Result: \(mathFunc(2, b: 3))")


//6.1参数为函数
func printMathResult(mathFun: (Int, Int) -> Int, a: Int, b: Int)
{
    print("Result: \(mathFun(a, b))")
}
printMathResult(sum, a: 3, b: 5)

//6.2 返回值为函数
func add1(input: Int) -> Int
{
    return input + 1
}
func sub1(input: Int) -> Int
{
    print("input: \(input)")
    return input - 1
}
//返回函数类型
func chooseFunc(backValue: Bool)   ->    (Int) -> Int
{
    return backValue ? sub1 : add1
}

var ab = 3
//moveNearerTozero指向sub1
let moveNearerToZero = chooseFunc(ab > 0)
//let moveNearerTozero:(Int) -> Int = chooseFunc(true)  //原型
//moveNearerTozero = sub1
print(moveNearerToZero(10))   //9



//MARK:---------7.嵌套函数------------

//嵌套函数是对外界不可见的,但是可以被他的封闭函数(enclosing function)来调用。一个封闭函数也可以返回它的某一个嵌套函数,使得这个函数可以在其他域中被使用
//改写6.2
/*
func chooseFunc(backValue: Bool) -> (Int) -> Int
{
    func add1(input: Int) -> Int
    {
        return input + 1
    }
    func sub1(input: Int) -> Int
    {
        return input - 1
    }
    return backValue ? sub1 : add1
}
var ab = 3
let moveNearerToZero = chooseFunc(ab > 0)
print(moveNearerToZero(10))  //9
*/

//8.闭包(Closures)
/*
闭包表达式(Closure Expressions)
尾随闭包(Trailing Closures)
值捕获(Capturing Values)
闭包是引用类型(Closures Are Reference Types)
*/

//闭包是自包含的函数代码块,可以在代码中被传递和使用。 Swift 中的闭包与 C 和 Objective-C 中的代码块(blocks)以及其他一些编程语言中的 lambdas 函数比较相似。

//MARK:------8.1 闭包表达式--------
//闭包表达式语法一般形式如下:
/*
{ (parameters) -> returnType in
statements
}
*/
//闭包表达式语法可以使用常量、变量和inout类型作为参数,不提供默认值。 也可以在参数列表的最后使用可变参数。 元组也可以作为参数和返回值。


//不使用闭包
let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
func backwards(s1: String, s2: String) -> Bool
{
    return s1 > s2
}
//用sort进行排序。E-D-C-B-A
var reversed = names.sort(backwards)
//print(reversed)

//使用闭包
reversed = names.sort({ (s1: String, s2: String) -> Bool in
    return s1 > s2
})
reversed = names.sort({ s1, s2 in return s1 > s2 } )

//8.2 单表达式闭包隐式返回(Implicit Return From Single-Expression Clossures)
//单行表达式闭包可以通过隐藏return关键字来隐式返回单行表达式的结果,如上版本的例子可以改写为:
reversed = names.sort({s1, s2 in s1 > s2 })

//8.3 参数名称缩写(Shorthand Argument Names)
//$0和$1表示闭包中第一个和第二个String类型的参数。
reversed = names.sort({ $0.0 > $1.0 } )

//8.4 运算符函数(Operator Functions)
//Swift 的String类型定义了关于大于号 (>) 的字符串实现
reversed = names.sort(>)
print(reversed)
// reversed 为 ["Ewa", "Daniella", "Chris", "Barry", "Alex"]


//8.5 尾随闭包(Trailing Closures)
//如果您需要将一个很长的闭包表达式(以至于不能在一行中进行书写时)作为最后一个参数传递给函数,可以使用尾随闭包来增强函数的可读性。 尾随闭包是一个书写在函数括号之后的闭包表达式,函数支持将其作为最后一个参数调用。
//如果函数只需要闭包表达式一个参数,当您使用尾随闭包时,您甚至可以把()省略掉。
func funcA(closure: () -> ())
{
    // 函数体部分
}
//不使用尾随闭包进行函数调用
funcA({
    // 闭包主体部分
})
//使用尾随闭包进行函数调用
funcA() {
    // 闭包主体部分
}
reversed = names.sort { $0.0 > $1.0 }


//将Int类型数组[16,58,510]转换为包含对应String类型的数组["OneSix", "FiveEight", "FiveOneZero"]:
//字典
let digitNames = [
    0: "Zero", 1: "One", 2: "Two",   3: "Three", 4: "Four",
    5: "Five", 6: "Six", 7: "Seven", 8: "Eight", 9: "Nine"
]
//数组
let numbers = [16, 58, 510]

//number 为变量参数
let strings = numbers.map { (var number) -> String in
    var output = ""
    while number > 0
    {
        //digitNames[]字典取值有可能出现取不到值的情况,所以返回一个可选值 (optional value)
        //对10取余,然后累加字符串
        output = digitNames[number % 10]! + output
        //考虑百位数字,比如510的循环取值
        number /= 10
    }
    return output
}
print(strings)
// strings 常量被推断为字符串类型数组,即 String[]
// 其值为 ["OneSix", "FiveEight", "FiveOneZero"]

//8.6 捕获值(Capturing Values)
//闭包可以在其定义的上下文中捕获常量或变量。 即使定义这些常量和变量的原域已经不存在,闭包仍然可以在闭包函数体内引用和修改这些值。
func makeAddCount(forAddCount a: Int)  ->    () -> Int
{
    var sum = 0
    func addCount() -> Int
    {
        sum += a
        return sum
    }
    return addCount
}
let addByTen = makeAddCount(forAddCount: 10)

//累加
print(addByTen())
print(addByTen())
print(addByTen())


let addBySeven = makeAddCount(forAddCount: 7)
print(addBySeven())
print(addByTen())

//8.7 闭包是引用类型

let alsoAddByTen = addByTen
print(alsoAddByTen())
// 返回的值为50

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值