上一篇文章介绍了Kotlin对函数的基本用法,包括函数的定义、输入参数的声明、输出参数的声明等等,这些足够对付简单的场合了。当然了,倘若一门新语言仅仅满足于这些雕虫小技,那也实在没什么前途。既然Kotlin志在取代Java,就必须练成Java所不具备的功夫。本篇文章便从函数的输入参数着手,谈谈Kotlin对输入参数的改进与增强之处。

首先复习一下如何声明函数的输入参数,比如回答“中国的伟大发明有哪些?”这个问题,需要定义一个函数,根据输入的几个发明名称,然后将这几个发明拼接成完整的答案。具体的函数定义举例如下:

    fun getFourBig(general:String, first:String, second:String, third:String, fourth:String):String {
var answer:String = "$general:$first,$second,$third,$fourth"
return answer
}

该函数的目的是获取中国四大发明的回答,你可以输入中国古代的四大发明,也可以输入外国留学生票选的中国现代四大发明。两种输入对应的函数调用都很简单,只消按照参数顺序依次输入四大发明的名称即可,调用代码如下所示:

    var isOdd = true //如果从初始赋值中能够知道变量类型,就无需显式指定该变量的类型
btn_input_manual.setOnClickListener {
tv_four_answer.text = if (isOdd) getFourBig("古代的四大发明","造纸术","印刷术","火药","指南针") else getFourBig("现代的四大发明","高铁","网购","移动支付","共享单车")
isOdd = !isOdd
}

  

可是这么做不够智能,因为中国古代的四大发明人尽皆知,小学生都知道,何必还得每次都手工输入呢?于是Kotlin引入了默认参数的概念,允许在定义函数时直接指定输入参数的默认值,如果调用函数时没有给出某参数的具体值,系统就自动对该参数赋予默认值,从而免去了每次都要手工赋值的麻烦。默认参数的写法也很简单,只需在声明输入参数时在其后面加上等号与默认值,代码如下所示:

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

有了默认参数,这下函数调用简单多了,就算开发者一时脑袋浆糊想不起来四大发明,也能毫无压力轻敲代码。不信请看下面的调用代码:

    btn_input_default.setOnClickListener { tv_four_answer.text=getFourBigDefault("古代的四大发明") }

如果不满意参数的默认值,可在调用函数时输入新的值,例如四大发明的默认值不包含它们的发明者,现在想增加显示造纸术的发明者蔡伦,则调用getFourBigDefault函数于第二个参数填写符合要求的描述文字,代码示例如下:

    btn_input_part.setOnClickListener { tv_four_answer.text=getFourBigDefault("古代的四大发明","蔡伦发明的造纸术") }

有时想要改写的参数并不位于默认参数的第一个,比如第二个参数的“印刷术”,虽然印刷术起源于中国是毫无疑义的,但是韩国声称是他们的古人发明了金属活字印刷,德国也有确凿证据证明是古腾堡发明了活字印刷机,这些言论容易误导外人以为中国只是发明了雕版印刷术而已,事实上不光雕版印刷的发明属于中国,就连活字印刷都是北宋的毕昇发明的,所以为了正本清源,“印刷术”的名称可改为影响力更大的“活字印刷”。然而“印刷术”在函数声明里面排在“造纸术”后面,莫非要给“印刷术”改名,还得把前面的“造纸术”照抄一遍?为了解决这个不合理的地方,Kotlin又引进了命名参数的概念,说的是调用函数时可以指定某个参数的名称与数值,形如“参数名=参数值”这样。就前述的“印刷术”改名而言,具体到编码上面,可参见以下的例子:

    btn_input_name.setOnClickListener { tv_four_answer.text=getFourBigDefault("古代的四大发明",second="活字印刷") }

  

默认参数结合命名参数的写法,至此告一段落。不料吃瓜群众有话说,咱们中国历史悠久、地大物博,伟大发明何止四大发明呢?譬如丝绸、瓷器、茶叶,每个拎出来都是响当当的物件,其地位在古代西方人眼里,好比现代中国人爱买的LV、劳力士、欧莱雅。所以中国的伟大发明可不能只限于四大发明,必须改成允许随时添加的,想加几个就加几个。这种随时添加对应于程序的可变参数,在Java体系中,可变参数采用“Object... args”的形式;在Kotlin体系中,新增了关键字vararg表示其后的参数个数是不确定的。以可变的字符串参数为例,Java的写法为“String... args”,而Kotlin的写法为“vararg args: String?”,具体解析的时候,则把可变参数当作一个数组,循环取出每个参数值进行处理,相应的Kotlin代码如下所示:

    fun getFourBigVararg(general:String, first:String="造纸术", second:String="印刷术", third:String="火药", fourth:String="指南针", vararg otherArray: String?):String {
var answer:String = "$general:$first,$second,$third,$fourth"
for (item in otherArray) {
answer = "$answer,$item"
}
return answer
}

这样好了,同一个函数既可以输入四大发明,还可以输出七大发明,哪天你给弄个十大发明也是允许的。下面是带有可变参数的函数调用代码:

    btn_param_vararg.setOnClickListener {
tv_four_answer.text = if (isOdd) getFourBigVararg("古代的四大发明") else getFourBigVararg("古代的七大发明","造纸术","印刷术","火药","指南针","丝绸","瓷器","茶叶")
isOdd = !isOdd
}

话说中国文化博大精深,除了物质上的发明,另有不少技艺上的发明,例如国画、中医、武术等等,哪个不是国之瑰宝?因此,可变参数也要支持输入这些技巧性的发明,当然为了跟物质性的发明区分开,最好分门别类,把物质性的发明分为一组,技巧性的发明一组。如此一来,可变参数就成了可变的数组参数,同样声明数组参数时也要加上vararg前缀,告诉编译器后面的数组个数是变化的。对应的函数声明代码修改如下:

    fun getFourBigArray(general:String, first:String="造纸术", second:String="印刷术", third:String="火药", fourth:String="指南针", vararg otherArray: Array<String>):String {
var answer:String = "$general:$first,$second,$third,$fourth"
for (array in otherArray) {
for (item in array) {
answer = "$answer,$item"
}
}
return answer
}

对于数组形式的可变参数,进行函数调用时得按照数组输入了,示例代码如下:

    btn_param_array.setOnClickListener {
tv_four_answer.text = if (isOdd) getFourBigArray("古代的四大发明") else getFourBigArray("古代的N大发明","造纸术","印刷术","火药","指南针",arrayOf("丝绸","瓷器","茶叶"),arrayOf("国画","中医","武术"))
isOdd = !isOdd
}

  

总结一下,Kotlin引入了C++的默认参数概念,并加以扩展允许通过命名参数指定修改某个参数值,而Java是不存在默认参数概念的。另外,Kotlin对Java的可变参数功能进行了增强,不但支持普通类型的可变参数,而且支持数组类型的可变参数。

__________________________________________________________________________
本文现已同步发布到微信公众号“老欧说安卓”,打开微信扫一扫下面的二维码,或者直接搜索公众号“老欧说安卓”添加关注,更快更方便地阅读技术干货。

Kotlin入门(10)七十二变的输入参数的更多相关文章

  1. Kotlin入门教程——目录索引

    Kotlin是谷歌官方认可的Android开发语言,Android Studio从3.0版本开始就内置了Kotlin,所以未来在App开发中Kotlin取代Java是大势所趋,就像当初Android ...

  2. Kotlin入门(13)类成员的众生相

    上一篇文章介绍了类的简单定义及其构造方式,当时为了方便观察演示结果,在示例代码的构造函数中直接调用toast提示方法,但实际开发是不能这么干的.合理的做法是外部访问类的成员属性或者成员方法,从而获得处 ...

  3. mybatis入门系列二之输入与输出参数

    mybatis入门系列二之详解输入与输出参数   基础知识   mybatis规定mapp.xml中每一个SQL语句形式上只能有一个@parameterType和一个@resultType 1. 返回 ...

  4. 机器学习入门-随机森林预测温度-不同参数对结果的影响调参 1.RandomedSearchCV(随机参数组的选择) 2.GridSearchCV(网格参数搜索) 3.pprint(顺序打印) 4.rf.get_params(获得当前的输入参数)

    使用了RamdomedSearchCV迭代100次,从参数组里面选择出当前最佳的参数组合 在RamdomedSearchCV的基础上,使用GridSearchCV在上面最佳参数的周围选择一些合适的参数 ...

  5. 写给Android开发者的Kotlin入门

    写给Android开发者的Kotlin入门 转 https://www.jianshu.com/p/bb53cba6c8f4 Google在今年的IO大会上宣布,将Android开发的官方语言更换为K ...

  6. Kotlin入门(11)江湖绝技之特殊函数

    上一篇文章介绍了Kotlin对函数的输入参数所做的增强之处,其实函数这块Kotlin还有好些重大改进,集中体现在几类特殊函数,比如泛型函数.内联函数.扩展函数.尾递归函数.高阶函数等等,因此本篇文章就 ...

  7. Kotlin入门(14)继承的那些事儿

    上一篇文章介绍了类对成员的声明方式与使用过程,从而初步了解了类的成员及其运用.不过早在<Kotlin入门(12)类的概貌与构造>中,提到MainActivity继承自AppCompatAc ...

  8. Kotlin入门(32)网络接口访问

    手机上的资源毕竟有限,为了获取更丰富的信息,就得到辽阔的互联网大海上冲浪.对于App自身,也要经常与服务器交互,以便获取最新的数据显示到界面上.这个客户端与服务端之间的信息交互,基本使用HTTP协议进 ...

  9. Kotlin入门(16)容器的遍历方式

    Kotlin号称全面兼容Java,于是乎Java的容器类仍可在Kotlin中正常使用,包括大家熟悉的队列ArrayList.映射HashMap等等.不过Kotlin作为一门全新的语言,肯定还是要有自己 ...

随机推荐

  1. LeetCode:21_Merge Two Sorted Lists | 合并两个排序列表 | Easy

    题目:Merge Two Sorted Lists Merge two sorted linked lists and return it as a new list. The new list sh ...

  2. .NET手记-定义类和接口的扩展方法

    对于iOS开发者来说,使用扩展方法是家常便饭.因为有很多的类是有系统框架的定义的,我们不能修改或者不想修改他们的源码,但是我们又想要给他添加一些扩展方法来使用.这时定义扩展方法就是很有用的方式了,正如 ...

  3. Jupyter中python3之numpy练习

    ---恢复内容开始--- Numpy_pratice In [2]: n = 10 L = [i for i in range(n)] In [3]: L * 2 Out[3]: [0, 1, 2, ...

  4. UFLDL 教程学习笔记(三)自编码与稀疏性

    UFLDL(Unsupervised Feature Learning and Deep Learning)Tutorial 是由 Stanford 大学的 Andrew Ng 教授及其团队编写的一套 ...

  5. 使用Jexus服务器运行Asp.Net Core2.0程序

    前段时间写了篇关于.net core跨平台部署的文章.https://my.oschina.net/lichaoqiang/blog/1861977 主要讲述了,利用Nginx+CentOS+Supe ...

  6. Mac 远程连接 Windows

    推荐使用微软官方发布的 Microsoft Remote Desktop,免费.流畅. 详见:https://docs.microsoft.com/en-us/windows-server/remot ...

  7. Docker数据卷容器备份、恢复

    1.备份数据卷容器 使用数据卷来备份数据,通过指定本地的一个文件路径,对应到容器中的路径,运行tar命令将重要的文件打包备份. $ cd /home/xm6f/dev $ docker run --v ...

  8. Windows10安装Docker

    一.Docker下载安装 一般情况下,我们可以从Docker官网docker下载安装文件,但是官方网站由于众所周知的原因,不是访问慢,就是下载慢.下载docker安装包动不动就要个把小时,真是极大的影 ...

  9. Mysql半同步复制模式说明及配置示例 - 运维小结

    MySQL主从复制包括异步模式.半同步模式.GTID模式以及多源复制模式,默认是异步模式 (如之前详细介绍的mysql主从复制).所谓异步模式指的是MySQL 主服务器上I/O thread 线程将二 ...

  10. netty源码解解析(4.0)-1 核心架构

    netty是java开源社区的一个优秀的网络框架.使用netty,我们可以迅速地开发出稳定,高性能,安全的,扩展性良好的服务器应用程序.netty封装简化了在服务器开发领域的一些有挑战性的问题:jdk ...