函数

/*

函数分为函数名,参数,返回值,执行代码块四部分

有返回值函数可以作为一个值直接在print里输出

*/

//函数定义

func max(a:Int, b:Int, c:Int) -> Int

{

return 1

}

max(1, b: 2, c: 3)

func firstMethod(str:String) ->String

{

return "123"

}

print(firstMethod("123"))

//没有返回值的函数

func noReturn(str:String)

{

print("no return")

}

//多个返回值的函数

func mutableReturn(str:String) ->(String, String)

{

return ("1", "2")

}

func mutableReturnWithName() ->(height:Int, weight:Int)

{

return (1, 2)

}

var man = mutableReturnWithName()

print(man.height)

//函数调用本身  也就是递归

func doAgain(num:Int) -> String

{

if num > 5{

print("000")

return "\(doAgain(num - 1))"

}else{

return "fff"

}

}

print(doAgain(10))

/*

递归是非常有用的,例如程序希望遍历某个路径下的所有文件,但这个路径下的文件夹的深度是未知的,那就可以使用递归来实现这个需求。系统可以设定一个函数,改函数接受一个文件路径作为参数,该参数可遍历出当前路径下的所有文件和文件路径--该函数再次调用函数本身来处理该路径下的所有文件路径

*/

/*

函数的参数

第一个参数如果不写外部参数,是不会显示外部参数的,第二个和之后的参数如果不写外部参数,会自动默认外部参数和内部参数同名

也就是说,除了第一个参数,其他的参数就算不设置外部参数也会有外部参数

*/

//拥有外部参数名的函数

func haveWaiName(wainame neiname:String) ->String

{

print(neiname)

return "\(neiname)"

}

print(haveWaiName(wainame: "name"))

//外部形参名和内部形参名一样的函数

func havesameName(name name:String) ->String

{

return name

}

print(havesameName(name: "sarah"))

//只有一部分形参有外部形参名的函数

func justSomehavename(name name:String, years:Int) -> (String, Int)

{

return (name, years)

}

print(justSomehavename(name: "marry", years: 10).0)

//形参有默认值的函数 一般将带有默认值的形参放在最后面,下面这个并不是一个好的编程习惯

func valueAlready(user name:String = "marry", msg:String)

{

print("\(name),\(msg)")

}

valueAlready(msg: "hi")

valueAlready(user: "tom", msg: "hi")

//参数个数可变的函数

func varibleValue(a:Int, books:String..., name:String)

{

for tmp in books

{

print(tmp)

}

}

varibleValue(3, books: "java","swift", name: "string")

/*

数量可变的参数的本质是一个数组参数,在执行代码块中当做一个数组来使用

*/

/*

函数中的形参默认是常量,如果想要变量的形参,需要自己声明

*/

func mutableNum(var name:String) ->String

{

name = name + "sss"

return name

}

print(mutableNum("mother"))

/*

在函数中,传入的参数如果是值类型,则传进去的是该值的副本,在函数中不会对原来的值产生影响

如果想要在函数中对该值进行改变,可以使用inout标签来标注

*/

func inoutFunc(inout age:Int) ->Int

{

age = age + 1

return age

}

var age = 5

print(age)//5

print(inoutFunc(&age))//6

print(age)//6

/*

当参数是引用类型的时候,程序会赋值引用的副本,不会复制该引用指向的对象

所以,当参数是引用类型的时候,即使不适用inout标签,该值仍然会在函数中被修改

但是,如果在函数中将引用类型置为空,只会切断副本和指向对象之间的联系,在函数之外,该值仍然不为空

*/

class DataWrap

{

var a:Int = 0

var b:Int = 0

}

func swap(var dw:DataWrap!)

{

var tmp = dw.a

dw.a = dw.b

dw.b = tmp

tmp = 0

dw = nil

}

var wp:DataWrap! = DataWrap()

print(wp)

swap(wp)

print(wp)//wp没有被置为空,但是如果使用了inout标签,这里就会出错

//定义一个函数变量

var myfun : (Int, Int) ->Int //这里最好不要给参数命名,虽然也可以命名,但是在使用的时候系统不会提示

var test : (String) ->Void

func pow(base base:Int, exponent:Int) ->Int

{

var result = 1

for _ in 1...exponent

{

result *= base

}

return result

}

//将pow函数赋值给mufun,则myfun可以当成pow使用

myfun = pow

print(myfun(3,4))

/*

只要被赋值的函数类型与myfun的变量类型一致,程序就可以赋值成功

通过使用函数类型的变量,可以让myfun在不同的时间指向不同的函数,从而让程序更加灵活。

*/

//其中一个参数是函数的函数

func map(var data data:[Int],fn:(Int) ->Int) ->[Int]

{

for var i = 0, len = data.count; i<len ;i++

{

data[i] = fn(data[i])

}

return data

}

func square(val:Int) ->Int

{

return val*val

}

func cube(val:Int) ->Int

{

return val*val*val

}

var data = [1,2,3]

print(map(data: data, fn: square))

print(map(data: data, fn: cube))

//这种方式可以动态的改变一个函数中的部分代码块,类似于c中的函数指针

//返回值为函数的函数

func getMathFunc(type type:String) -> (Int) ->Int

{

switch(type)

{

case "square":

return square

default:

return cube

}

}

var mathFunc = getMathFunc(type: "cube")

print(mathFunc(5))

/*

函数重载

函数名相同,但是参数个数不同或外部参数名称不同或返回值不同

这种情况就是重载

*/

/*

嵌套函数

在swift中,函数和类享有同样的级别,函数可以直接声明在文件里,而不用单独声明在一个类里

所以,函数可以当成变量被引用,被返回,在函数中声明函数

*/

func getMathFunc2(type type:String) ->(Int) ->Int

{

func square(val: Int) ->Int

{

return val*val

}

func cube(val:Int) ->Int

{

return val*val*val

}

switch(type)

{

case "square":

return square

default:

return cube

}

}

闭包

//本质是功能更灵活的代码块,可以直接作为返回值被返回

//在闭包里不要给参数写外部参数名,因为Xcode不会提示,还要自己写,很麻烦

var square3 = {

(val:Int) -> Int in

return val*val

}

print(square3(5))

//在闭包的后面添加圆括号来调用闭包

var resultt2 = {

(base:Int,exponent:Int) -> Int in

var result = 1

for _ in 1...exponent

{

result *= base

}

return result

}(3, 4)

print(resultt2)

//省略形参类型,返回值类型的闭包

var square4:(Int) ->Int = {(val) in return val*val}

//省略了参数类型,参数列表的那个圆括号也可以省略

var square6:(Int) ->Int = {val in return val*val}

print(square6(5))

var result3:Int = {base, exponent in

var result = 1

for _ in 1...exponent

{

result *= base

}

return result

}(4, 3)//因为这个地方有声明int类型的变量,所以不用指定返回值类型

//上面两个闭包因为有声明闭包类型变量,所以也可以不声明返回值

//省略return

//如果闭包表达式的执行体只有一行代码,而且这行代码的返回值将作为闭包表达式的返回值,那么swift允许省略return关键字

var square7:(Int) ->Int = {val in val*val}

var square8 = {(val:Int) -> Int in val*val*val}

print(square7(3))

print(square8(3))

//省略形参名

var square9:(Int) ->Int = {$0 * $0}

var result4:Int = {

var result = 1

for _ in 1...$0

{

result *= $1

}

return result

}(3, 4)

//尾随闭包

//当函数的最后一个参数是一个函数类型的时候,可以用闭包来进行传参,然后把小括号放在闭包前面,把闭包给单独放置在外面

func map2(var data data:[Int], fn:(Int) -> Int) -> [Int]

{

for var i = 0, len = data.count; i<len; i++

{

data[i] = fn(data[i])

}

return data

}

var data2 = [3, 4, 5, 6, 7]

print("原数据\(data2)")//"原数据[3, 4, 5, 6, 7]\n"

var rvt1 = map2(data: data2){$0 * $0}

var rvt3 = map2(data: data2){

var result = 1

for index in 2...$0

{

result *= index

}

return result

}

//如果调用函数时只需要闭包表达式一个参数,那么使用尾随闭包时,swift甚至允许程序省略调用函数的圆括号

//闭包可以捕获上下文中的变量和常量

//每个闭包都会持有一个它所捕获的变量的副本,所以,闭包执行与原来所在的函数并没有联系

//闭包是引用类型,所以即使是声明成常量也可以改变内部值

func makeArray(ele:String) -> () ->[String]

{

var arr:[String] = []

func addElement() ->[String]

{

arr.append(ele)

return arr

}

return addElement

}

let add1 = makeArray("sun")

print(add1())

print(add1())

let add2 = makeArray("zhu")

print(add2())

print(add2())

转载于:https://www.cnblogs.com/chebaodaren/p/5501563.html

Swift -- 6.函数和闭包相关推荐

  1. Swift 的函数和闭包

    函数的关键字是 func ,函数定义的格式是: func funcName(para:paraType) -> returnType{// code } 复制代码 函数的参数标签 其中参数的那部 ...

  2. 《Swift开发实战》——第2章,第2.4节函数和闭包

    本节书摘来自异步社区<Swift开发实战>一书中的第2章,第2.4节函数和闭包,作者 李宁,更多章节内容可以访问云栖社区"异步社区"公众号查看 2.4 函数和闭包 在本 ...

  3. Swift 1.1语言第7章 函数和闭包

    Swift 1.1语言第7章  函数和闭包 在编程中,随着处理问题的越来越复杂,代码量飞速增加.其中,大量的代码往往相互重复或者近似重复.如果不采有效方式加以解决,代码将很难维护.为了解决这个问题,人 ...

  4. Swift应用案例 2.闭包入门到精通

      本文主要介绍Swift的闭包的使用并与OC的Block做比较.学习Swift是绕不过闭包的,因为无论是全局函数还是嵌套函数都是闭包的一种,本文主要介绍闭包表达式. 1.闭包表达式的使用 // 1. ...

  5. Swift 中的Closures(闭包)详解

    Swift 中的Closures(闭包)详解 在Swift没有发布之前,所有人使用OC语言编写Cocoa上的程序,而其中经常被人们讨论的其中之一 -- Block 一直备受大家的喜爱.在Swift中, ...

  6. php的匿名函数和闭包函数

    php的匿名函数和闭包函数 tags: 匿名函数 闭包函数 php闭包函数 php匿名函数 function use 引言:匿名函数和闭包函数都不是特别高深的知识,但是很多刚入门的朋友却总是很困惑,因 ...

  7. python命名空间和闭包_Python函数基础实例详解【函数嵌套,命名空间,函数对象,闭包函数等】...

    本文实例讲述了Python函数基础用法.分享给大家供大家参考,具体如下: 一.什么是命名关键字参数? 格式: 在*后面参数都是命名关键字参数. 特点: 1.约束函数的调用者必须按照Kye=value的 ...

  8. Swift 泛型函数补充

    Swift 泛型函数[中文参考文档] 泛型使用的基本原则,执行时候需要知道具体泛型类型,即要么通过参数确定类型,要么通过返回值推导类型. 参考文档中已经给出来基本的泛型使用.基本都是通过参数去定类型 ...

  9. swift_015(Swift 的函数)

    //***********swift学习之15--函数--*************************** /* Swift 定义函数使用关键字 func,由函数名.参数.返回值组成.参数和返回 ...

最新文章

  1. MFC中快速应用OpenCV(转)
  2. 最新Transformer模型大盘点,NLP学习必备,Google AI研究员出品丨资源
  3. pandas read_csv ‘utf-8‘ codec can‘t decode bytes in position 1198-1199: invalid continuation byte解决
  4. 携手百度 英特尔三大领域布局人工智能市场
  5. STM32之option bytes踩坑记录
  6. Windows 8 开发31日-第04日-新控件
  7. 计算机网络基础专业找工作,2021计算机网络技术前景怎么样? 好找工作吗
  8. 领域应用 | 知识图谱的技术与应用
  9. 3、构建并安装PHP扩展
  10. Python入门--python中的global
  11. Chrome安装Octotree插件
  12. 究竟什么是可重入锁?
  13. nvcc与nvidia
  14. C语言程序设计实践题,2020年C语言程序设计实践实验题目.doc
  15. IP一键呼叫语音对讲怎么样?
  16. 分享CFA一级考试!
  17. 一文进入Flink CDC 的世界
  18. java 监听jtextfield_java JTextField之监听器
  19. code函数oracle列子,Oracle内置函数SQLCODE和SQLERRM的使用
  20. pyspark Dataframe添加一列常量列

热门文章

  1. C++ 应用程序性能优化,第 6 章:内存池
  2. 五、Netty核心组件
  3. ThreadLocal 和 InheritableThreadLocal
  4. nginx中js修改不生效的问题
  5. Java线程池Executor框架
  6. HashSet、TreeSet、TreeMap实现原理
  7. C语言再学习 -- 运算符与表达式
  8. tar解压出错:gzip: stdin: unexpected end of file的解决
  9. Java关于equals()方法和“==”逻辑运算符的区别简介
  10. [以太坊源代码分析] I.区块和交易,合约和虚拟机