Bootstrap

Kotlin教程学习-字符串拼接,数组,List

092736_JX0C_1416297.png

首先看到的就是import语句,这个很好理解,既然Kotlin有包的概念,自然就可以使用import语句引用其他包下面写好的Kotlin类(顺便提一下,Kotlin是面向对象的语言).不过令我们惊奇的是java.util.Arrays,这不是Java的类库里面的吗?难道JetBrains吃多了把所有Java类库都移植到了Kotlin上面?答案其实很简单,因为Kotlin和Java都是JVM语言,所以100%兼容(官网说是100%),因此在Kotlin中使用class文件完全不需要移植(笑,Kotlin本来最后也会被编译为class文件).换句话说,包括Java,Groovy,Scala在内的这些JVM语言写的代码,只要编译为class文件后,就可以在Kotlin中轻松引用.虽然在源代码级别不兼容(不能在一个源文件中混合使用几种语言),但是在JVM级别是兼容的.同样的,在其他JVM语言中也可以直接引用Kotlin的代码.

比如在Java中引用Kotlin

094939_fN2U_1416297.png

可以看到这是Java代码,调用了前面写的string_template函数.通过这个代码我们可以发现一些有趣的事情(string_template函数定义在BasicPackage类中),这很奇怪,因为我们并没有写BasicPackage类.我们前面写的Kotlin代码并没有使用class(函数并不是在类中定义的),但是Kotlin是面向对象的语言,Kotlin中一切都是对象,在Kotlin中甚至连原始类型都没有,前面我们在Kotlin中看到的Int,Long都是对象.那么这个BasicPackage类是怎么来的呢?

其实我们前面所写的Kotlin代码看起来虽然是全局函数,实际上却被局限在一个包中,Kotlin自动在每一个包中帮我们定义了一个默认的类,这个BasicPackage类就是默认类的名字(包名+Package),如果我们写的函数不是在类里面定义的,就会被自动归类到这个默认的类里面(换句话说虽然前面我们并没有编写类,但是所有函数都被放到一个默认的类中了),实际上在Kotlin中只有这种默认类里面的main函数才可以作为程序入口被执行,如果你把main函数写在普通的Kotlin类中是不能作为程序入口的.

再看string_template函数,可以发现字符串可以使用${} 和$等方法进行替换,这种字符串处理的风格大概是从Unix脚本里面继承过来的吧.关于字符串还有很多其他的库函数.

再看arr_test函数,在Kotlin中,数组其实是一个Array<>模版,使用arrayOf函数进行初始化,不过和Java中一样,仍然需要使用Arrays.toString()来进行输出.在Kotlin中数组其实已经几乎不能称之为数组了,在Kotlin中数组更像是 一个Collection,提供了Iterator,有get和set方法,不像Java数组有很多内置特性.

最后再看list_test函数,通过listOf函数创建了一个list对象,再使用+=操作添加了一个元素,然后通过filter方法将长度大于1的元素挑选出来放到新的List对象(posi)里面去.

函数输出如下:

104113_9aGB_1416297.png

等等,+=也就算了,那个filter是函数调用?怎么看起来这么奇怪,连圆括号都不见了.

其实filter函数是这样的

100814_P9VB_1416297.png

圆括号只是被省略了,WTF,这也能省略!其实Kotlin代码可以很简洁,代码量很少,在Kotlin代码中省略很常见.

但是仍然存在问题,filter的参数好奇怪,使用大括号括起来,而且还有->运算符.明眼人可能已经知道了,->肯定不是指针.

实际filter函数的参数是一个函数,这里又是一个lambda.

才学习Kotlin几天,就第二次碰到了lambda(说起来我对lambda也不是很了解),事实上lambda表达式可以大大减少代码量,但是却增加了代码的阅读难度(尤其对于如我这样的编程新手,笑).在C++中有函数指针的概念(当然现在C++也有lambda),将函数作为参数也不是什么罕见的事.

如果大家看不明白,可以换一个写法

101944_PCNg_1416297.png

相信这样写就明白了,这里定义了一个select函数,判断字符串长度是否大于1,再将select函数作为参数传入filter函数中,在filter函数中对每一个元素都调用select函数进行选择,如果返回true则被选中,返回false则不被选中,所以最后posi其实就是把l中所有长度大于1的字符串选出来了,这就是filter函数(是不是和C++里面的函数指针作为参数很像).

但是这一次我们又看到了一些有趣的东西,

l filter中间没有"."号,你没有看错,我也没有写错.对,你猜得没错,"."又被省略了,这个在Kotlin中叫做infix function call:中缀函数调用

其实前面说了,括号也可以省略,所以地道的infix function call其实是这样的

103026_uSFa_1416297.png

就是空格分隔而已,还有::域限定符,要是把::select换成lambda表达式,恐怕连神鬼都怕

103323_XcJM_1416297.png

没错,你没有看错,lambda表达式也可以简化,WTF!!!  { ix -> ix.length() > 1 }居然被简化成了 { it.length() > 1 }

it是一个iterator迭代器,内置的,只能是it,不能是其它的名字

通过一条语句的各种变化可以看到,在Kotlin中语法之灵活让人发指,代码量虽然可以大幅减少,但是省略和lambda的大量使用,对于没有接触过编程的人来说简直就是一场灾难.或许这就是优雅的代价.

说起来我也是才学习Kotlin呢(笑),Kotlin特性之多之复杂足以让人望而却步,不过为了优雅我也是要拼了.

转载于:https://my.oschina.net/yuanhonglong/blog/466503

;