Kotlin学习笔记六、函数运用

1、函数基本用法:
A、与java的对比、区别:

Java常规方法:

@Override protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.activity_main);
}

Kotlin常规方法:

override fun onCreate(savedInstanceState: Bundle?) {
	super.onCreate(savedInstanceState)
	setContentView(R.layout.activity_main)
}

二者对比,我们可以发现二者以下的几点区别:

  1. Java使用“@Override”表示该函数是重载父类的方法,而Kotlin使用“override”并且放在方法开头,表示该函数是重载父类的方法。
  2. Java使用“public”关键字表示该函数是公共的方法,而在kotlin里面函数默认就是公开的,所以用不着关键字“public”。
  3. Java使用“void”表示定义一个方法且无返回值,若有其他返回值,那么void就被替换为返回值的类型即可。比如我要返回一个字符串,那么将“void”改为“String”即可。而在
    Kotlin里面不存在关键字“void”,若无返回值,则不用特别说明。
  4. Kotlin新增了关键字“fun”,表示这里是定义了一个函数,其格式类似于Java的“void”或者其他返回值类型。而Java不存在关键字“fun”。
  5. Kotlin引入了空安全机制,如果允许某个变量为空,那么在该变量的类型后面加“?”即可。
  6. Kotlin里面,如果某个“class”类允许被别的类继承,那么记载其关键字“class”前面添加关键字“open”,表示这个类是开放的,可以被继承或者实现。
B、入参与出参格式:

Kotlin的函数写法跟Java有很大的不一样。一个完整的Java函数格式如下:

方法公私有属性 返回值类型 函数名(入参类型Ⅰ,入参类型II…){return …}

与之对应的Kotlin函数格式如下:

fun 函数名(入参变量名I:入参类型, 入参变量名II:入参类型…):返回值类型{return ……}

当不要求有返回值时:

fun 函数名(入参变量名I:入参类型, 入参变量名II:入参类型…){……}

当不要求有入参的时候:

fun 函数名(){……}

相比Java,kotlin的方法定义简单了太多。

C、默认参数:

像上面的的函数,作为入参,我们有时候,希望它能够有默认值,尤其是对一些大众都知道的一些信息。因此kotlin引入了默认参数的概念,就像Python里面方法的参数带值的那样:

fun getFourBigDefault(general: String, 
					first: String = "造纸术", 
					second: String = "印刷术",
				    third: String = "火药", 
				    fourth: String = "指南针"): String {
	var answer = "$general: $first, $second, $third, $fourth"
	return answer
}

// 完全不设置参数
var oldAnswer = getFourBigDefault()
logging(oldAnswer)

选择性的设置参数,设置一部分参数,这时候需要注意的是参数名要与方法里面的参数名完全一样。否则,参数匹配失败,编译不通过,也就是“具名参数”。

var changeAnswer = getFourBigDefault(second = "毕昇的活字印刷术")
logging(changeAnswer)

所有参数完全重新设置赋值。

var newAnswer = getFourBigDefault("中国当代四大发现:", "高铁", "网购","移动支付","共享单车")
logging(newAnswer)

另外,当我们只想给函数传一部分参数,但顺序和数量又没有什么规律的时候,我们可以传“具名参数”,也就是给函数的入参名称name=value的格式传参:

    var nameAnswer = getFourBigDefault(general = "中国当代四大发现", second = "5G网络通信技术")
	logging(nameAnswer)

在这里插入图片描述

这个几乎就跟Python的默认入参是一样的了,有传参进来,就用传进来的参数,没有传参进来的话就用默认的参数值。

D、可变参数:

这点对应Java的可变参数,Java中,可变参数采用的是“Object……args”的形式,而Kotlin里面,则是新增了可变参数关键字vararg,表示其修饰的参数是一个不确定的。以可变的字符串参数为例,Java的写法为:String……args,而换成Kotlin的写法则为” vararg args:String?”。函数内部在解析的时候会把可变参数args解析为一个数组,开发者需要循环去除每隔参数值进行处理。举个例子:

给带可变参数的函数赋值的时候,要注意:
1、可变参数一般都位于主参数的后面,排在最后;
2、给前面的主参数赋值的时候,赋值的数量要跟主参数的数量保持一致,这样,参数队列才不会发生错乱
3、比如下面的例子:主参数5个:general、first、second、third、fourth,那么赋值的参数也要5个
否则:
------少一个的话,就会造成后面的可变参数里面的第一项前移,变成主参数,造成错乱。
------多一个的话,那么原本主参数的最后一项则会被函数解析为可变参数的一部分。
------无论是多一个还是少一个都会造成参数错乱,进而影响函数功能的实现,
而且这种问题有时候还不好排查,所以使用的时候要特别注意。

var changeParams = getFourBigDefault("中国古代四大发明:", "造纸术", "印刷术",
	"火药", "指南针", "茶叶", "丝绸", "瓷器")
logging(changeParams)

var changeParamsArray = getFourBigDefault("中国古代四大发明:", "造纸术", "印刷术",
          "火药", "指南针", arrayOf("茶叶", "丝绸", "瓷器"), arrayOf("国画", "中医", "武术"))
logging("数组可变参数的例子:$changeParamsArray")

另外、当我们在声明一个数组参数的时候也要在其前面加上“vararg”关键字,告诉编译器后面的这个数组是变化的。另外要注意函数入参设置默认值的格式:变量名:变量类型=变量值

fun getFourBigDefault(general: String="中国古代四大发明:", first: String = "造纸术",
	second: String = "印刷术", third: String = "火药", fourth: String = "指南针",
	 vararg otherParams:Array<String>?): String {
	var answer = "$general: $first, $second, $third, $fourth"
	
	//这里循环取出可变参数的值的操作是经过嵌套的for循环实现的,而且内层循环不要忘记了非空判断
	for (mArray in otherParams){
    	if (mArray != null) {
			for (item in mArray){
	    		answer = "$answer, $item"
			}
    	}
	}
	return answer
}

这里我们可以看到getFourBigDefault()函数的最后一个参数otherParams,我们在前面就加了关键字vararg,表示他是一个可变参数。

vararg:定义可变参数,参数的数量/个数不确定,其实可以直接把他放做一个数组列表来处理。

2、几种特殊的函数:
A、泛型函数:

在前面我们学习过程中,函数的入参的类型都是确定的,但是开发的时候,往往函数的入参我们是无法确定的,尤其是网络请求数据解析的对象类型的时候,只有在函数调用执行的时候方才知晓,如此一来我们又该怎么声明函数呢?其实不难,Java中为解决这样的问题,提出了泛型的概念,Kotlin里面同样有泛型的概念,而且用法跟Java是一样的。举例如下:

var mod = (System.currentTimeMillis() % 3).toInt()
when (mod){
	0 -> logging(genericity("中国古代四大发明", arrayOf("造纸术","印刷术","火药","指南针")))
	1 -> logging(genericity("小于10的自然数", 1, 2, 3, 4, 5, 6, 7, 8, 9))
	else -> logging(genericity("中国古代畅销海外的产品有", "茶叶", "丝绸", "瓷器"))
}
fun <T> genericity(functions: String, vararg otherParams: T?):String{
	var appendResult = functions
	for (item in otherParams){
    	if (item is Array<*> && item.isNotEmpty()){
			for (content in item){
	    		appendResult = "$appendResult, ${content.toString()}"
			}
    	}else {
			appendResult = "$appendResult, ${item.toString()}"
    	}
	}
	return appendResult
}

从上面例子中,外层for循环里面的if判断条件语句我们可以看到:在Kotlin里面,定义泛型数组的时候不再是Array的格式,而是Array<*>这样的格式,这一点跟Java不一样,需要引起注意。

另外,上面when(){}循环内部还可以写成这样,指定参数类型,也就是**<*>**里面的部分:

when (mod){
	0 -> logging(genericity<Array<T>>("中国古代四大发明", arrayOf("造纸术","印刷术","火药","指南针")))
	1 -> logging(genericity<Int>("小于10的自然数", 1, 2, 3, 4, 5, 6, 7, 8, 9))
	else -> logging(genericity<String>("中国古代畅销海外的产品有", "茶叶", "丝绸", "瓷器"))
}

前面的例子中,方法genericity后面省略了最终的泛型类型,而上面添加上了,但二者执行的结果是完全一样的,另外在编译器里面,加下划线的两行代码里面指定泛型类型的<Int>和<String>其实被置灰了,说明是不必要指定泛型类型的。因此为了简单,我们可以省略在方法名后面指定泛型类型,然后将泛型类型体现在后面的传参上。
另外,genericity(……)函数既可以写在class类的里面,也可以写在class类的外面。

B、内联函数:

没理解到具体有什么作用,以后用到了再来具体学习。

C、简化函数:

没理解到具体有什么作用,以后用到了再来具体学习。

D、尾递归函数:

没理解到具体有什么作用,以后用到了再来具体学习。

E、高阶函数:

没理解到具体有什么作用,而且看起来增加了代码的可读性难度,以后用到了再来具体学习。

3、增强系统函数
A、扩展函数、扩展高阶函数作用:

Java中,系统自带的类已经提供了许多方法,但是还是无法完全满足开发时的也无需求,这是开发者往往需要写一个工具类(如字符串工具类StringTools、日期工具类DateTools、数字处理工具类NumberTools等)来补充相关功能,长此以往,工具类工具类将会越来越多,后加入开发团队的人对工具类不熟悉,又会加入新的工具类,这样就越来越难以管理。

Kotlin为了避免以上情况,就推出了扩展函数的概念,就是允许开发者给系统类补充新的方法,而无需另外编写额外的工具类。比如系统自带的数组Array提供了求最大值max的方法,也提供了排序sort的方法,可是并未提供交换数组元素的方法,于是我们打算给Array数组新增数组元素交换的方法。

扩展函数的有一个特殊的标识符:swap定义如下:

fun <T> Array<T>.swap(pos1:Int, pos2:Int){
	var temp = this[pos1]
	this[pos1] = this[pos2]
	this[pos2] = temp
}

说明:pos1和pos2都是位置下标。具体用到的时候再来学这个。

4、日期函数函数:

开发中这个使用的非常多,就不再多说看例子:

//获取当前时间的格式
var sdf = SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS")
//Kotlin中,创建类的对象不再是通过关键字new,而是直接-->>类名(),比如下面Date的对象就是Date()
logging("当前时间:${sdf.format(Date())}")
5、函数返回多个数据:
fun getParamas(){
	var mTriple = someParamas()
	println("${mTriple.first.reversed()}${mTriple.second}, ${mTriple.third}")
}

fun someParamas():Triple<String, String, Int>{
	return Triple("qwertyuikfdszxcvbn", "jhgf", 25)
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值