Swift基础教程(三)

9. 函数

  • 函数的定义,就是把一些代码封装在一起,有可能有输入,也可能有输出,然后可以被调用执行.

9.1. 无参数, 无返回值的函数

func introduce() {
    print("Hello, world!")
}
introduce()  // 调用

9.2 有一个参数无返回值的函数

// 参数先写形参名字,再用冒号隔开,写类型名称
func introduce(name:String) {
    print("hello, \(name)")
}
introduce(name:"world")  // 调用时, 先写入形参名字,再跟:, 最后写入实参

9.3 有返回值的函数

// 有多个参数,则用都好隔开, 返回值,用->进行分开,如果返回的只是一个值,直接跟类型,如果返回的是多个,则需要返回一个元组,
func login(name:String, pwd:String) ->Bool{
    if name == "zhangsan" && pwd == "123456" {
        return true
    }
    return false
}
if login(name:"zhangsan", pwd:"111111") {
    print("Login Succeed!")
} else {
    print("Login Failed!")
}

9.4 有多个返回值的函数

// 多个值返回,返回是一个元组,可以指定名称,也可以不指定名称
func MaxMin(a:Int, b:Int)->(max:Int, min:Int) {
    if a > b {
        return (a, b)
        // return (max:a, min:b)
    } else {
        return (b, a)
        // return (max:b, min:a)
    }
}

9.5 参数指定外部使用名称

func MaxMin(FirstValue a:Int, SecondValue b:Int)->(max:Int, min:Int) {
    if a > b {
        return (a, b)
        // return (max:a, min:b)
    } else {
        return (b, a)
        // return (max:b, min:a)
    }
}
let (max, mix) = MaxMin(FirstValue:127, SecondValue:126) 

9.6 调用时不指定参数名称的函数

func MaxMin(_ a:Int, _ b:Int)->(max:Int, min:Int) {
    if a > b {
        return (a, b)
        // return (max:a, min:b)
    } else {
        return (b, a)
        // return (max:b, min:a)
    }
}
let (max, mix) = MaxMin(127, 126) 

9.7 参数是不定长的参数

// 参数是不定长, 需要在类型后面添加... 传入的参数可以理解是一个数组.
func CalcSum(_ vals:Int...)->Int {
    var sum = 0
    for val in vals {
        sum += val
    }
    return sum
}
var sum = CalcSum(1,2,3,4,5,6,7)
print(sum)

9.8 返回值是数组

func RandomArray(count a:Int)->[Int] {
    var ret = [Int]()
    for _ in 0...a {
        ret.append(Int.random(in:0...100))
    }
    return ret
}

9.9 参数是引用,可以函数内部进行更改

func scale(n: inout Int) {
    n *= 10
}
var val:Int = 10
scale(n:&val)
print(val)

10. 枚举类型

定义:
	有限状态的集合,如
        性别:男,女; 
        星期:星期一-星期日. 
        球类: 篮球,足球..
作用:
	可以助记
// 性别, 约定,首字母大写.
enum Sex {
    case Male, 
    case Female
}

// 推断定义
let sex = Sex.Male
print(sex, type(of: sex))

// 显示定义
let reqSex:Sex = Sex.Female
print(reqSex, type(of: sex))

// 定义类型,还可以直接一个case.
enum Dir {
    case Up, Down, Right, Left
}
let dir = Dir.Up
print(dir, type(of:dir))
dir = .Right // 前面的类型可以省略掉
// 枚举匹配
enum Dir : CaseIterable{
    case Up, Down, Right, Left
}
var dir = Dir.Up;
switch dir {
    case .Up: 
    	print("上")
   	case .Down:
    	print("下")
    case .Right:
    	print("右")
    case .Left:
        print("左")
}

// 枚举关联值.
enum PlayerState {
    case Idle
    case Walk(speed:Int)
    case Run(speed:Int)
    case fly(speed:Int, height:Int)
    case die
}

var a1 = PlayerState.Idle
var a2 = PlayerState.Walk(speed: 300) // 关联值
var a3 = PlayerState.fly(speed:300, height:800)

switch a1 {
    case .Idle:
    	print("待机")
   	case .Walk(let speed):
    	print("玩家正在以\(speed)行走")
    case .Run(let speed):
    	print("玩家正在以\(speed)奔跑")
   	case .fly(let speed, let height):
    	print("玩家正在飞行:\(speed) 高度:\(height)")
    case .die:
    	print("玩家死亡")
}

// 枚举的遍历
enum Dir:CaseIterable {
    case Up, Down, Right, Left
}

for dir in Dir.allCases {
	print(dir)
}

// 注意: 有关联值的枚举,无法进行遍历.
// 原始值, raw格式. 
enum Gender: Int {
    case Male = 10
    case Female
    Case Unknown
}
// 默认没有值.
print(Gender.Male)				// male
print(Gender.Male.rawValue)		// 10

print(Gender.Female)			// female
print(Gender.Female.rawValue)	// 11
// 原始值意义,存储一般存储原始值.

// 订单状态
// 已下单,已曲消, 已发货
case OrderState:Int {
    case AlreadyOrdered = 0
    case AlreadyCancel = 1,
    case AlreadyDeliver = 2
}
  • 枚举的描述

    enum Weather {
        case Sunny,Cloudy, Rainy, Snowy, Windy
        // 每一种数据类型,都有descriiption,  这里进行重新定义了一下
        var description : String {
            switch self {
                case .Sunnyreturn "晴天"
                case .Cloudy:
                	return "多云"
                case .Rainy:
                	return "雨天"
               	case .Snowy:
                	return "下雪"
                case .Windy:
                	return "大风"
            }
        }
    }
    
    print(Weather.Sunny.description)  // 晴天
    
    enum Shape {
        case rectangle(width:Double, height:Double)
        case circle(radius:Double)
        
        var description:Double {
            switch self {
                case .circle(let radius): 
                	return Double.pi * radius * radius
                case .rectangle(let width, let height):
                	return width * height
            }
        }
        print(Shape.rectangle(width:20, height:20).description)
    }
    

11. 闭包

闭包的本质: 一个匿名函数
// 函数 ()->Void, 因为返回值为,空,所有返回的Void无意义 
func hello() {
    print("Hello")
}

// 函数调用
hello()

// 匿名函数
let hi = {
    print("Hello")
}
// 调用
hi()

有参数: 对于闭包,需要将参数和返回放到匿名函数体.

// 参数放入函数体, 用in隔开 
let hi = { (name:String) in 
    	print("Hello, \{name}")
	}
// 匿名函数调用,不需要输入函数标签 name.
hi("张三")

有返回值

func sum(a:Int, b:Int) ->Int {
    a + b
}
print(sum(a:3, b:4))

// 闭包
let s = {(a:Int, b:Int)->Int in
	a + b
}
print(s(3, 8))

func hi()->String {
    "Hello, World"
}
let hi2 = { ()->String in
    "Hello, World"
}
print(hi2())

闭包可以作为参数传入函数

func sayhi(action:()->Void) {
    action()
}
let hi = {
    print("你好")
}
// 调用1
sayhi(action:hi) // 你好
// 调用2, 又称尾随闭包 
sayhi {
    print("hello")   // hello.
}
func travel(action:()->Void) {
    print("before")
    action()
    print("after")
}

travel(action:{
    print("hello, world")
}) // before, hello, world, after.

// 函数的最后一个参数是闭包函数,可以使用这个写法
travel{
    print("hello, world")
} // 输出同上.
func travel(action:(String)->Void) {
    print("before")
    action("zhengzhou")
    print("after")
}
travel{ (place:String) in
    print("I travel the \(place) by train")
}
func travel(action:(String, Int)->Void) {
    print("before")
    action("zhengzhou", 5)
    print("after")
}
travel{ (place:String, time:Int) in
    print("I travel the \(place) by train at \(time) clock")
}

闭包又返回值

func travel(action:(String, Int)->String) {
    print("before")
    print(action("zhengzhou", 5))
    print("after")
}
travel{ (place:String, time:Int)->String in
    return ("I travel the \(place) by train at \(time) clock")
}

参数可以用$0和$1替代,可以进行简写

func travel(action:(String, Int)->String) {
    print("before")
    print(action("zhengzhou", 5))
    print("after")
}
travel{
    return ("I travel the \($0) by train at \($1) clock")
}

函数返回值是函数

func travel()->(String)->Void {
    return { (place:String) in
        print("I want travel to \(place)")
    }
}
let r = travel()
r("zhengzhou")
// 下面的函数声明等效于  func read(book:String) -> ()->Void
func read(book:String) -> ()->() {
    print("我正在读\(book)")
    var count = 0
    return {
        count += 1
        print("第\(count)次读\(book)")
    }
}
let a = read("三国演义")		   	//我正在读三国演义
a()								   //第1次读三国演义 
a() 							   //第2次读三国演义	
  • 闭包在数组中的应用

    • 数组的map参数

      let datas = [1,2,3,4,5]
      let n1 = datas.map { item in 
         item * item
      }
      print(n1)   // [1, 4, 9, 16, 25]
      
      let n2 = datas.map {
          $0 * $0
      }
      print(n2)   // [1, 4, 9, 16, 25]
      
      
      说明:
      	1. lambda表达式,如果使用自定义参数,则需要用in进行隔开, 如果使用内置的$0,则不需要
      	2. 如果只有一条语句,则不需要return
      
    • 数组filter使用

      let datas = [1,2,3,4,5]
      let n = datas.filter {
          $0>2
      }
      print(n)  // [3,4,5]
      
    • 数组reduce的使用

      reduce 是 Sequence 类型(包括数组)的一个方法,它可以将序列中的所有元素组合成一个单一的输出值。reduce 方法接受一个初始值和一个闭包作为参数,闭包定义了如何将序列中的元素与累积值结合。
      
      let datas = [1,2,3,4,5]
      let n = datas.reduce(1, {
          $0 * $1
      }print(n)  // 120, = 1*2*3*4*5
                           
      let n2 = datas.reduce(0, +)
      print(n2) // 15
                           
      let n3 = datas.reduce(1, *) // 等效于上面的
      print(n3) // 120       
      
      // 字符串拼接
      let words = ["Hello", " ", "world", "!"]  
       
       // 使用字符串拼接作为闭包                     
      let sentence = words.reduce("", {
          $0 + $1
      })
      print(sentence)  // 输出:Hello world!                        
                           
      // 最后一个参数是闭包,可以将其从括号中拿出来.                     
      let sentence2 = words.reduce("") { $0 + $1 } 
      print(sentence2) // 输出:Hello world!  
                           
      // 将内部参数$0,$1改成自定义的名称有意义的参数,更正规
      let sentense3 = words.reduce(""){(accumulator, currentWord) in 
           accumulator + currentWord                             
      }    
      print(sentense3) // 输出:Hello world!                                  
      

12. 结构体

结构体可以存放多个类型数据,也可以存放函数.

结构体的定义

struct Rectangle {  
    // 静态名字,需要用static进行定义
    static let name = "Rectangle"
    var width: Double  
    var height: Double  
    var perimeter: Double? = nil  
    // 可以通过计算属性得到矩形的面积  
    var area: Double {  
        return width * height  
    }  
    
    // 计算周长, 由于更改内部属性,需要使用mutating关键字.
    mutating func CalcPerimeter() {
        self.perimeter = (self.width + self.height) * 2
    }
    
    // 初始化方法  
    init(width: Double, height: Double) {  
        self.width = width  
        self.height = height  
    }  
      
    // 结构体方法  
    func describe() {  
        print("Rectangle with width \(width) and height \(height)")  
    }  
}
说明:
	1. 如果定义init函数,则该用函数为构造函数,如果未定义init函数,则会有默认的init构造函数
	2. 如果内部有更改属性的方法(含有mutating), 外部如果要调用,则外部对象不能是let声明.

结构体的使用

// 1. 创建结构体
var rect = Rectangle(width: 10.0, height: 5.0)
// 2. 读取结构体的属性
print(rect.width)
print(rect.area)
// 3. 调用方法
rect.CalcPerimeter()
print(area.perimeter!)
  • 25
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值