Swift基础学习的总结(三)

今天学习的内容是有关函数、闭包的知识.
1.函数

  • 1.1 函数名、函数参数命名
    苹果编写函数的风格,就是函数的命名更加类似于自然语句,有着非常强的可读性.正常我们的函数是是这样定义的:
func sayHelloTo(name: String, greeting: String) -> String {
    return "say \(greeting) to \(name)"
}

sayHelloTo("jf", greeting: "hello")

参数:greeting 既是函数外部参数名,也是函数内部参数名
要是我们想要区分开,使得调用时,语义看起来更明确,又不会影响内部函数的参数调用,这时我们应该这样写:

func sayHelloTo(name: String, withGreeting greeting: String) -> String {
    return "say \(greeting) to \(name)"
}

sayHelloTo("jf", withGreeting: "hello")

还有一种情况,函数名已经十分明确了,这时候我们不需要函数外部参数名,该如何定义呢,请看:

func mutiply(num1: Int, _ num2: Int) -> Int {
    return num1 * num2
}

mutiply(1, 3)
  • 1.2 默认参数值和可变参数值
    有默认参数值
// 建议有默认参数值的参数放在最后面
func sayHelloTo(name: String, withGreeting greeting: String = "Hello") -> String {
    return "say \(greeting) to \(name)"
}

sayHelloTo("dd")
sayHelloTo("jf", withGreeting: "hello")

变长的参数类型,对于一个函数最多有一个变长参数类型

func sayHelloTo(names: String ..., withGreeting greeting: String) {
    for name in names {
        print("\(name), \(greeting)")
    }
}

sayHelloTo("jf", "DC", withGreeting: "Hello")
  • 1.3 常量参数、变量参数、inout参数
    一般,我们传入函数的参数是默认为常量参数,如果需要一个变量参数(事实上,由于面向函数的原则,不建议声明架构一个函数包含有变量参数。),则需要在函数体内标注:var num = num.
// 十进制数转二进制
func toBinary(num: Int) -> String {
    var num = num
    
    var res = ""
    
    repeat {
        res = String(num % 2) + res
        num /= 2
    } while num != 0
    
    return res
}

toBinary(12)

inout参数:可以改变传入的值,做到按引用传入.

// 交换两个整数
func swapTwoInts(inout a: Int, inout _ b: Int) {
    let t: Int = a
    a = b
    b = t
}

var x = 1
var y = 2

swapTwoInts(&x, &y) // 传入参数前加上&
x // 2
y // 1
  • 1.4 函数型类型
    函数本身是可以被当做变量的
// 函数本身是可以被当做变量的
var array1 = ["F", "P", "C", "D", "A", "S"]
func stringSortDesc(a: String, _ b: String) -> Bool {
    return a > b
}

let array2 = array1.sort(stringSortDesc)
array2


func sayHelloTo(names: String ..., withGreeting greeting: String) {
    for name in names {
        print("\(name), \(greeting)")
    }
}

func toBinary(num: Int) -> String {
    var num = num
    
    var res = ""
    
    repeat {
        res = String(num % 2) + res
        num /= 2
    } while num != 0
    
    return res
}

// 函数变量
let tobinary: (Int)->String = toBinary
let sayhello: (String ...,String)->() = sayHelloTo

下面了解初步的函数式编程例子

var score = [99, 20, 60, 80, 30, 21]

// map
func isPassOrFail(score: Int) -> String {
    return score < 60 ? "Fail" :"Pass"
}

score.map(isPassOrFail)

// filter
func arrayLower60(score: Int) -> Bool {
    return score < 60
}

score.filter(arrayLower60)

// reduce
func concatenate(str: String, score: Int) -> String {
    return str + "\(score)" + " "
}

score.reduce("", combine: concatenate)

// 从大到小-转成字符串
score.sortInPlace { (score1, score2) -> Bool in
    return score1 > score2
}
score.reduce("", combine: concatenate)
  • 1.5 返回值为函数类型,函数嵌套
    例如:
对于买家购买的商品,所付的钱 = 邮费 + 单价 * 体重/钱
而邮费的计算是根据体重,有不同的标准
标准1:小于20,邮费 =  体重
标准2:大于20,邮费 =  体重 * 2
func postage1(weight: Int) -> Int {
    return weight
}

func postage2(weight: Int) -> Int {
    return weight * 2
}

func choosePostage(weight: Int) -> (Int) -> Int {
    return weight < 20 ?postage1 :postage2
}

func calculateGoodPrice(weight: Int, price: Int) -> Int {
    let postage = choosePostage(weight)
    
    return postage(weight) + weight * price
}

calculateGoodPrice(30, price: 10)

函数嵌套

func postage1(weight: Int) -> Int {
    return weight
}

func postage2(weight: Int) -> Int {
    return weight * 2
}

func calculateGoodPrice(weight: Int, price: Int) -> Int {
    func choosePostage(weight: Int) -> (Int) -> Int {
        return weight < 20 ?postage1 :postage2
    }
    
    let postage = choosePostage(weight)
    
    return postage(weight) + weight * price
}

calculateGoodPrice(30, price: 10)

2.闭包
闭包和函数本质上是一致的,都属于引用类型.
学过OC的朋友,就可以把闭包当做block来理解.
闭包的基本语法

let hello = {(name: String, greeting: String) -> String in
    // 函数体
    return "\(name): \(greeting)"
}

一对大括号,参数列表,返回类型,关键字in,加上函数体

结尾闭包:若函数最后一个参数是闭包,则闭包可以写在小括号()后面,例如

let showView = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
let rectangle = UIView(frame: CGRect(x: 0, y: 0, width: 50, height: 50))

showView.addSubview(rectangle)
rectangle.center = showView.center
rectangle.backgroundColor = UIColor.redColor()

UIView.animateWithDuration(2.0) { 
    rectangle.backgroundColor = UIColor.blueColor()
    rectangle.frame = showView.frame
}

内容捕获:在闭包内,可以获取到闭包外的变量(但是得注意内存问题,还有待研究)

为大家介绍用typealias,为闭包重新定义名字

typealias SayHello = (name: String, greeting: String) -> Void

let sayHello: SayHello? = {name, greeting in
    print("\(name): \(greeting)")
}

sayHello!(name: "jj", greeting: "Hi")


let hello = {(name: String, greeting: String) -> String in
    // 函数体
    return "\(name): \(greeting)"
}

swift中没有main函数
@UIApplicationMain:表示程序入口

大家赶紧去试试吧!

刘雨波Demo地址:
Play-with-Swift-2

你可能感兴趣的:(Swift基础学习的总结(三))