Swift -- 6.函数和闭包
函数
/*
函数分为函数名,参数,返回值,执行代码块四部分
有返回值函数可以作为一个值直接在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.函数和闭包相关推荐
- Swift 的函数和闭包
函数的关键字是 func ,函数定义的格式是: func funcName(para:paraType) -> returnType{// code } 复制代码 函数的参数标签 其中参数的那部 ...
- 《Swift开发实战》——第2章,第2.4节函数和闭包
本节书摘来自异步社区<Swift开发实战>一书中的第2章,第2.4节函数和闭包,作者 李宁,更多章节内容可以访问云栖社区"异步社区"公众号查看 2.4 函数和闭包 在本 ...
- Swift 1.1语言第7章 函数和闭包
Swift 1.1语言第7章 函数和闭包 在编程中,随着处理问题的越来越复杂,代码量飞速增加.其中,大量的代码往往相互重复或者近似重复.如果不采有效方式加以解决,代码将很难维护.为了解决这个问题,人 ...
- Swift应用案例 2.闭包入门到精通
本文主要介绍Swift的闭包的使用并与OC的Block做比较.学习Swift是绕不过闭包的,因为无论是全局函数还是嵌套函数都是闭包的一种,本文主要介绍闭包表达式. 1.闭包表达式的使用 // 1. ...
- Swift 中的Closures(闭包)详解
Swift 中的Closures(闭包)详解 在Swift没有发布之前,所有人使用OC语言编写Cocoa上的程序,而其中经常被人们讨论的其中之一 -- Block 一直备受大家的喜爱.在Swift中, ...
- php的匿名函数和闭包函数
php的匿名函数和闭包函数 tags: 匿名函数 闭包函数 php闭包函数 php匿名函数 function use 引言:匿名函数和闭包函数都不是特别高深的知识,但是很多刚入门的朋友却总是很困惑,因 ...
- python命名空间和闭包_Python函数基础实例详解【函数嵌套,命名空间,函数对象,闭包函数等】...
本文实例讲述了Python函数基础用法.分享给大家供大家参考,具体如下: 一.什么是命名关键字参数? 格式: 在*后面参数都是命名关键字参数. 特点: 1.约束函数的调用者必须按照Kye=value的 ...
- Swift 泛型函数补充
Swift 泛型函数[中文参考文档] 泛型使用的基本原则,执行时候需要知道具体泛型类型,即要么通过参数确定类型,要么通过返回值推导类型. 参考文档中已经给出来基本的泛型使用.基本都是通过参数去定类型 ...
- swift_015(Swift 的函数)
//***********swift学习之15--函数--*************************** /* Swift 定义函数使用关键字 func,由函数名.参数.返回值组成.参数和返回 ...
最新文章
- MFC中快速应用OpenCV(转)
- 最新Transformer模型大盘点,NLP学习必备,Google AI研究员出品丨资源
- pandas read_csv ‘utf-8‘ codec can‘t decode bytes in position 1198-1199: invalid continuation byte解决
- 携手百度 英特尔三大领域布局人工智能市场
- STM32之option bytes踩坑记录
- Windows 8 开发31日-第04日-新控件
- 计算机网络基础专业找工作,2021计算机网络技术前景怎么样? 好找工作吗
- 领域应用 | 知识图谱的技术与应用
- 3、构建并安装PHP扩展
- Python入门--python中的global
- Chrome安装Octotree插件
- 究竟什么是可重入锁?
- nvcc与nvidia
- C语言程序设计实践题,2020年C语言程序设计实践实验题目.doc
- IP一键呼叫语音对讲怎么样?
- 分享CFA一级考试!
- 一文进入Flink CDC 的世界
- java 监听jtextfield_java JTextField之监听器
- code函数oracle列子,Oracle内置函数SQLCODE和SQLERRM的使用
- pyspark Dataframe添加一列常量列
热门文章
- C++ 应用程序性能优化,第 6 章:内存池
- 五、Netty核心组件
- ThreadLocal 和 InheritableThreadLocal
- nginx中js修改不生效的问题
- Java线程池Executor框架
- HashSet、TreeSet、TreeMap实现原理
- C语言再学习 -- 运算符与表达式
- tar解压出错:gzip: stdin: unexpected end of file的解决
- Java关于equals()方法和“==”逻辑运算符的区别简介
- [以太坊源代码分析] I.区块和交易,合约和虚拟机