这是一种对程序猿更为友好的语言,可以减少开发者的工作量,原本由开发者干的事情,其实很多都可以由编译器实现了,这是一种更为高级的语言。Java虽然严谨,但却过于繁琐,太啰嗦了,一个小事情却要写大量的代码,而且有些代码又是非常机械式的,在实际编码过程中都是用IDE来自动生成。Java,C,C++,Object C这些都是上世纪的编程语言。
现在到了新时代了,编程也发展了很多,像lambda表达式,函数式编程,等等一些新的概念和范式在涌现。所以就有了新时代的编程语言,像水果的Swift,Groovy,Scala,以及Java阵营的Kotlin。Kotlin是新一代的编程语言,与Java完美融合,简洁,方便,可以大大提高程序可读性,特别是对于Android开发者来说。水果推出了Swift以解放水果平台的开发者,而Kotlin就是来解放Android开发者的。
虽然说Kotlin可以用在任何可以用Java的地方,但目前主要就是两大领域服务端,以及Android应用开发,特别是有了Google官方的支持,所以Kotlin对于Android开发者的意义更为重大,身为一个Android猿,是一定要学习一下这门现代的编程语言的,因为当你学过了之后 ,你会发现,之前写的代码都是在浪费生命。
有三种方式
其实,这是最好的方式,因为配置起来非常的方便。到官网去下载编译器,解压,然后把kotlinc/bin/放到PATH环境变量里面,就可以了。如果要配置Vim,还需要安装一下插件,大神们早就把插件准备好了,只需要下载,然后按照官方方法安装即可,其实就是把解压后的东西拷贝到相应的目录里面就好了。
这个看官方文档就可以了,孤未亲测,如遇困难请自行Google。
因为Kotlin官已支持了Android Studio,而Google也支持了,总而言之就是在Android Studio中可以直接使用Kotlin。所以, Android Stuido 3.0以后的版本无需特殊配置,就可以用例Kotlin了。
对于刚开始学习Kotlin而言呢,孤推荐使用命令行的方式,而不要使用Android Studio,特别是直接创建一个基于Kotlin的Android项目,因为此时对语言还不够熟悉,直接上项目,会迷失在项目配置,frameworks以及语言基础之中。刚学习一门语言的时候要先学习基本的语法以及语言本身的特性,这最好先绕开框架和项目,会更容易上手一些。
这是所有编程语言的入门必学课程,目的是让学习者快速的体验一下一门语言,我们也不用多想,照着一个字母,一个字母的把示例敲进去就好了:
1 2 3 4 5 |
|
然后,保存文件
3. 回到命令行,编译源码,如果一切顺利会得到一个叫hello.jar的文件,这就是kotlin的最终输出,也就是它的目标文件.
1 |
|
4. 运行,这里跟Kotlin其实已经没啥关系了,因为经过编译得到的是一个标准的Jar文件,像运行其他jar一样运行就好了:
1 |
|
就会得到输出Hello, world到此,第一个Kotlin程序已经完成,是不是很酷,已经迫不及待的想深入学习了!往下看吧。
一行一个语句(先不纠结语句与表达式的区别),不用加分号,不用打分号,光这个就可以节省多少时间呢?是不是感觉人生都浪费在了分号上面。如果想在一行写多个语句,前面的要加上分号。
缩进规则与Java一致,用四个空格,也可以用tab,或者不加缩进,只要没人打你。
语句块需要加上花括号{}。总之,语句结构与Java很类似。
用var来声明变量,用val来声明常量,因为Kotlin是静态强类型语言(也就是说每个变量在编译的时候必须知道类型)声明时需要带上类型,方法是在变量名的后面加冒号,空格跟上类型名字,与Pascal差不多。如果声明时直接定义,则可以不用指定类型,编译器会根据定义表达式来推测它的类型。示例:
1 2 3 |
|
主要想说一下语句和表达式的区别,简单来说就是表达式是有值的,可以放在变量赋值的右边,而语句是没有值的,不能放在赋值的右边
不多说了,跟Java一样
这个跟Java也一样: // 单行注释 / / 多行注释 /* / documentation
以fun关键字来定义一个函数格式为:fun 函数名(参数): 返回类型 {函数体},如:
1 2 3 |
|
命名参数和默认值,调用函数时可以把参数的名字带上,以增加可读性。声明函数时可以用默认值 ,以更好的支持函数的重载。如:
1 |
|
使用时,可以指定参数的名字:
1 2 3 4 |
|
表达式体如果一个函数体内只有一个表达式,且有返回值时,那么,可以直接把返回值放在函数 的后面,如:
1 |
|
甚至还可以把返回类型的声明给省略掉,如:
1 |
|
跟Java不一样的是,Kotlin的函数可以声明为toplevel也就是跟class一个级别,也就是说不必非放在类里面,也就是说跟C和C++是类似的。此外,还可以函数赋值给一个变量,这个变量就像其他变量一样。
类的声明与对象创建
用class来声明一个类型,用:来继承父类或者实现接口,不需要使用new来创建对象:
1 2 3 4 |
|
假如,一个类,是空的,没有内容,那么花括号{}是可以省略的:
1 |
|
创建对象:
1 |
|
Primary constructor
构造方法,有所谓的primary constructor,可以直接写在类名的后面:
1 |
|
一般情况下,constructor 可以省略掉:
1 |
|
初始化块因为primary constructor不能包含代码,所以,想要做些初始化工作就可以放在初始化块里面(initializer block),也可以在定义属性时直接使用:
1 2 3 4 5 6 |
|
一般情况下,如果声明的属性变量在primary constructor中都有赋值(通过initializer block)的话,可以有更简洁的表达方式:
1 |
|
这相当于:
1 2 3 |
|
如果primary construct前面要声明属性,或者有annotation的话,关键字constructor不能省略:
1 |
|
Secondary constructor
如果primary constructor不能满足需求怎么办呢?还可以声明其他constructor,所谓的secondary constructor:
1 2 3 4 5 |
|
是不是看起来舒服一些,因为跟Java一样了,可以把primary constfuctor和second constructor联合起来一起用:
1 2 3 4 5 |
|
这里要把secondary construct尽可能delegate到primary constructor,这里的delegate的意思就是primary constructor会在second constructor之前 执行,还有就是initiailzer block都是在primary construct中执行的,这就能保证initiliazer block在second constructor之前执行。即使没有显示的声明primary constructor,编译器还是会生成一个默认的primary constructor以及把secondary constructor默认的delegate到primary constrcutor上面。也就是说,会保证primary constructor以及initializer block执行在second constructor前面:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
输出:
1 2 |
|
属性和访问方法
Kotlin会为声明的属性生成默认的setter和getter:
1 2 3 4 5 |
|
如果想自定义setter和getter,也是可以的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
定义类的方法
跟声明普通函数一样,只不过是放在了类里面:
1 2 3 |
|
如果,要覆写父类的方法,需要使用在方法声明时加上override关键字。
1 2 3 |
|
访问权限
访问权限也跟Java类似分为public,protected,private以及internal,前三个意义也都一样,只不过默认值不一样,在Java里,如果对成员没有指明,则是package scope,也就是同一个package可以访问,但是Kotlin默认是public的。
internal是module内部可见,有点类似于Java中的package,但是module定义跟package不一样,module是一组编译在一起的Kotlin文件,它跟编译打包有关系,简单的理解它的范围要比package要大。
还有就是类,默认是不可被继承的,相当于final class。如果想要允许继承就要在声明类的时候加上open。
概念就不说了,大部分与Java一模一样的,像支持的方法等。唯一需要说的就是字串模板,就是说把其他类型转化为字串时,有较Java更为方便的方式:直接用$来把变量嵌入到字串之中,如:
1 2 3 4 |
|
首先要介绍一个概念,高阶函数,其实就是把另外函数当作参数的函数,或者说产生一个函数,也即把函数作为返回值 的函数。前面说过,函数是一级对象,可以像常规变量一样来使用,所以,就能把函数作为参数或者返回值来使用高阶函数。lambda表达式就是为高阶函数更方便使用而生的。
lambda 表达式
作为新时代的编程语言,都会支持函数式编程,而lambda表达 式又是函数式编程里面必不可少的一份子。其实啥是lambda表达式呢?说的简单点就是没有名字的函数,非常简短的,通常都是一两句话的没有名字的函数。就是长这个样子{A, B -> C},这里面A,B是参数,C是表达式,如:
1 |
|
其中,参数的类型是可以省略的,因为编译器能从上下文中推测出来: max(strings, { a, b -> a.length < b.length } 表达式部分,可以不止一个,最后一个表达式作为返回值。
当把一个lambda表达作为最后一参数,传给某个函数时,可以直接把lambda表达式写在参数的外面,比如:
1 |
|
而当lambda是唯一的参数时,也可以把参数的括号省略掉:
1 |
|
还有就是,如果lambda表达中只有一个参数,那么参数也可以省略,直接写表达式:
1 |
|
函数类型
前面提到了函数是可以像普通变量一样使用的一级类,也就是说它是一个类型。它的具体形式是: (A, B)->C,其中括号内的是参数,C是返回类型,如:
1 2 |
|
为啥要提一下函数类型呢,因为有时需要声明高阶函数:
1 2 |
|
Unit是一个特殊的返回值,相当于void,意思就是此函数没有返回值。
其实大部分跟Java是一样的。只不过有一些函数式的操作,要多注意使用,从而让代码更简洁,如:
这些操作,对于大家应该都不难理解,就不一一解释了,来断代码就知道了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
为了有效的减少空指针异常,Kotlin加入了Nullable类型,核心的原理是这样的:声明类型的时候要明确的告诉编译器,这个变量是否可能为null,如果可能为null,那么可以赋null给这个变量,并且在使用此变量时必须检查是否为null;假如这个变量不可能为null,那么是不可以赋null给此变量的。也就是说,编译器会帮忙做一些检查,以减少NullPointerException的发生。
Nullable变量
默认的变量声明都是不可为null的,如:
1 2 |
|
要想允许变量为null,要在类型后面加一个问号,以告诉编译器这是一个nullable类型:
1 2 |
|
使用时,nullable不能直接使用,必须检查是否为null:
1 2 |
|
检查Nullable的真伪
可以用传统方式:
1 |
|
Safe call
既然有Nullable类型,自然就有配套的方式来更方便的使用它:
1 |
|
如果danger是null就返回null,否则返回长度,注意它的返回值是一个Int?(又是一个Nullable类型)。这个还能链起来:
1 |
|
如果任何一环为null,则直接返回null。是不是感觉省了好多if (a == null)判断。
Elvis operator
假如不能接受safe call返回的null,咋办呢?想提供默认值的呢?也有方式:
1 2 |
|
稍有点绕哈,首先,danger?.length返回一个Int?吧,那么?:的作用就是如果len是null,那么就返回-1,否则返回它的值。
强制取值符!!
它的作用是如果Nullable变量为null就抛出NullPointerException,如果正常的话就取其值,返回的类型是一个non-null类型:
1 |
|
尽管,编译器可以帮助我们做一些事情,但是现实的项目中的大量的NPE并不是直接来源于,可以方便追踪的赋值为null,而多是发生在多线程环境中,以及非常复杂的逻辑之中,编译器能否追踪到并警示,还有待考察。另外,就是虽有利器,但是要运用恰当,何时用允许null,何时不允许,还是要靠工程师的设计能力,比如尽可能返回空列表,空Map,或者空字串,而不是直接简单的返回null,这就能减少一定的NPE。
光是看书或者看教程是比较乏味的,学习编程最重要的是要上手去练习,这样能加深印象,更好的理解书中或者教程中所讲的概念和知识点。官方也准备了一个非常好的练习项目叫Kotlin-koans,非常适配初学习者来练手。 下面说一下如何使用这个练习项目:
致此,我们可以看出Kotlin这门语言的设计的核心理念:简洁,这是Kotlin的核心理念,所以我们看到,一些机械的,重复的,可以从上下文中推测 出来的都 可以省略,以增加可读性。我们在使用Kotlin的时候要践行此理念,把语言的特性发挥到最大。 当然,简洁,不是牺牲可读性的方式来缩短代码,而是要使用语言中的标准的简洁的表达方式,比如lambda表达式,省略参数等。
要注意参考Kotlin conventions以及Android Kotlin conventions以写出更加简洁和容易理解的代码。
我们来新建一个项目,用纯Kotlin实现一个Hello, world Android应用,来展示一下如何在Android中使用Kotlin:
注意: 这里使用的是Android Studio 3.1.2版本,默认就支持Kotlin,如果使用小于3.0的版本需要安装Kotlin插件,可自行Google,孤还是建议先升级AS吧。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
其实,整体来看,布局和项目的结构还是按照Android的方式来,唯一的不同是代码可以用Kotlin来写了。
至此,Kotlin就算入门了,可以使用Kotlin来构建应用程序了,或者在你的项目中应用Kotlin了。