1、介绍Kotlin
Kotlin是jvm新的开发语言。
谷歌推广Kotlin作为其基于java的Android平台上的第一类语言在五月份。从那之后我就纳闷:这是什么语言?Kotlin已经有好几年了,并且在2016年2月正式在生产系统上运行,语言后的1.0版本,为期一年左右。该语言已经获得很多的赞赏和喜爱。
在这篇文章中我们将涵盖语法等基本构建块,在介绍Kotlin第二部分,我们将接触变量,函数,类,接口和对象。最后,在第三部分,我们来看一看控制流程的几个例子。
1、构建过程
当Kotlin在发展的时候,您的构建过程或多或少和旧的java程序类似。既然您已经熟悉了这些,就没有必要学习新的东西,Gradle/Maven插件:引入Kotlin的构建过程和构建工具。
您可以通过添加Kotlin插件在您的Gradle/Maven中构建脚本。如何做到这一点以及了解更多信息,可以从官方文档Kotlin中找到关于 Maven /Gradle的更多介绍。
2、Kotlin语法
一位伟人曾经说过 talk is cheap, show me the code。
貌似在接触新语言时第一句学到的总是以Hello World开始的。那我们就从这里开始吧。
print("Hello World")
现在,我们已经看到了不同于java的地方。有一些我们熟悉的东西()表示函数调用,但没有分号去结尾,不过看起来也很整齐。好了,下面让我们开始去了解Kotlin吧。
① Kotlin变量
在Kotlin中声明变量有一些不同,我们有关键字val和var,这看起来很相似,但其实有一个重要的区别:
当变量被声明为val时是不可变的(只读),你只能给它分配一次值。变量被声明为var是可变的,可以给它重新分配。
val hello: String = "hello"
val world: String
world = "world"
var helloWorld: String = "Hello"
helloWorld = "Hello World"
注意,变量类型如何定义?用冒号分隔。这背后还有一个理由,编译器现在可以决定是否要进行类型推断。这意味着Kotlin比Java有着更强大的类型推断。实际上,你也可以不用声明这些类型编译器也会明白你的意思。
val hell0 = "hi"
val w0rld = "earth"
只有当变量被赋值的时候,该变量的类型才能被推断出来。
② fun
这是什么样的功能呢?由于我们用fun来声明它们,它一定很有趣!哈哈。😁
// 无返回值. (也可以这么写 --> fun sayIt (a: String): Unit)
fun sayIt (a: String) {
println(a)
}
// 有返回值
fun returnIt (returnable: String): String {
return returnable
}
//作为具有推断返回类型和自动返回的单表达式函数
fun returnIt2 (turntable: String) =
turntable
类型声明遵循相同的模式在这里-它排在后面。在我们的第一个我们不返回任何东西,所以我们可以省略到类型,在这种情况下可以使用Unit。在第二个函数中,我们定义必须返回一个String,使用return语句。最后一个比较令人费解,没有大括号,只是一个等号。这意味着fun是一个表达式,它可以自动返回。
正如你所看到的,在表达式的返回类型上是可选的。可以省略或者留在原位,什么让你更方便(经验法则:长的表达式,把它放在后面。短的表达式,它可以省略)。
Kotlin还引入了可选的命名函数参数的概念。这是很有用的,特别是如果你的函数成长为很多同类型和多种不同参数的时候。
fun optFun(isItFun: Boolean = true, whyIsItFun: String = "Because") = if (isItFun) whyIsItFun else "It's not fun"
println(optFun()) // Because
println(optFun(false)) // It’s not fun
println(optFun(whyIsItFun = "It's Summer!")) // It's Summer!
在这个代码块中,我们使用默认值来定义我们的函数参数。当我们这么写的时候,我们可以直接调用该函数的0个、1个或者多个它的参数。
③ 类,接口和对象
与Java一样,Kotlin也具有类和接口。Kotlin团队决定让代码组织更加愉快和语言更加简洁。让我们先了解一下类。
A、类
class SimpleClass
// 或者 --> class constructor SimpleClassWithConstructor(val chop: String)
class SimpleClassWithConstructor(val chop: String)
在Kotlin中有很多方式可以创建类。在上面的代码块中给了我们提示:
- 命名约定以大写字母开头
- 没有花括号
- 还有就是在这个例子中没有可见性修改
- 我们仍然使用class关键字
第二个例子是相似的,但它有一个构造函数。构造函数绑定类的属性(在大多数情况下可以不用关键字constructor,只需要添加类的注解或类的可见性),另一种方式,使得Kotlin更加简洁,当我们实例化这个类时需要给chop赋值。
val lamb = SimpleClassWithConstructor("Hello")
在Kotlin中属性默认是公有的,所以访问该属性的最简单方法:
println(lamb.chop)
这个类不具有任何功能,它只是为我们的数据提供容器。我们可以自定义在里面添加fun类功能。在这种情况下,我们需要使用花括号来包裹我们的声明:
class SimpleClassWithConstructor(val chop: String) {
fun sayItMate(): String = chop + ", mate"
}
我们可以在这里添加附加的属性,其它类,额外的构造函数或初始化块,我们可以给这些单独分配可见性。
init在Kotlin中做的事情,就是我们通常在Java构造函数中做的事情。如果你想在类中创建一个类,你可以使用inner关键字标记它,以便访问外层类的成员。
class Kenny(val celly: String) {
lateinit var wheel: CanadianPerson
val friend: String
init {
friend = "buddy"
}
fun initializeWheel (wheeler: String) {
wheel = CanadianPerson(wheeler)
}
inner class CanadianPerson(val snipe: String)
// 美元符号使用字符串插值,并使用该属性中定义的toString实现替换$ -prefixed属性名称
fun sayItCanadianWay(): String = "${wheel.snipe} $celly, $friend"
}
val d = Kenny("friend")
d.initializeWheel("I’m not")
print(d.sayItCanadianWay()) // I'm not your friend, buddy
我们通过使用lateinit关键字来告诉编译器,这个属性不为空,即使我们不立即初始化它,这对于不在构造函数中初始化属性很有用。注意,我们的lateinit属性必须是可变的。
init相当于Java中的构造函数块,在那里,我们实例化类时,我们可以执行所需的动作。在这种情况下,我们将一个String赋值给我们的属性。
接下来,我们有一个函数,最终赋值给我们的lateinit属性,实例化一个内部类CanadianPerson,这个内部类只是我们数据的载体。
最后,我们将调用一个函数,这个函数将返回一个String,它使用字符串插值将它们解析并展示出来。
当向类添加其他构造函数时,我们需要调用它们原始的构造函数。
class DoubleTrouble(val str: String){
constructor(lamb: SimpleClassWithConstructor): this(lamb.chop)
}
我们在类中添加一些简单的功能,除了保存数据什么都不做。
对于这些类型的数据传输对象。Kotlin引入了一个关键字来定义它们:data class。它不同于标准的类,一个data class自动生成equals,hashcode,toString和copy功能。前三个对Java开发者来说是比较熟悉的,第四个是个很好的补充,可以帮助我们从只读数据类创建类似的对象。该copy功能可以这么用:
data class DataClass(val str: String, val num: Int)
val daata = DataClass("Hello", 3)
val peeta = daata.copy(str = "Goodbye")
在这种情况下,我们的peeta包含了num=3和str=“Goodbye”。
我们也可以去获取component数据类对象,这些组件函数通过解构来访问数据类中数据的一种方式。这有利于通过简单的一行调用来获取数据类中的单个属性。
val (str, num) = peeta
有了这个技巧,我们的变量str和num的值分别为"Goodbye"和3。请注意,解构变量的顺序取决于数据类中属性的顺序;这些名字根本不重要。
另外还有两个顶级结构interface和objects。
b、接口
Kotlin中接口与Java中没有什么不同,
interface Sayer {
val value: String
fun sayIt(): String
}
class SayerClass: Sayer{
override val value: String = "Hello"
override fun sayIt(): String = "$value, world"
}
println(SayerClass().sayIt()) // Hello, world
如您所见,这与Java非常相似,像Java8一样,Kotlin也可以在接口中提供默认实现,我们可以利用这个特性实现上面一样的效果。
interface Sayer {
val value: String
fun sayIt(): String {
return "$value, world"
}
}
使用这个我们不必重新实现类中的函数。请注意,override关键字在Kotlin中是强制性的。
c、对象
object SingletonClass{
fun sayIt(): String = "Hello world"
}
class CompaniedClass(val str: String){
companion object Printer{
fun sayIt(): String = "Hello world"
}
}
这是什么呢?你可以使用object关键字创建SingletonClass的单例。
SingletonClass.sayIt() // Hello world
Companied对象是略有不同的,它在一个类中定义,它仍然是一个单例,它可以使用包装类的名称来访问。
CompaniedClass.sayIt() // Hello world
4、控制流程(if,when,for)
a、if
if在Kotlin中的语句或多或少与Java类似,下面我们来看一下它们的不同:
val three = 4
if (three != 3) {
println("Liar!")
} else{
println("Good job")
}
这看起来与Java完全相同。但是也略有不同。
val three = 4
val goodOrNot = if(three != 3) {
"Liar!"
} else{
"Good job"
}
println(goodOrNot) // Liar!
如果Kotlin语句实际上是表达式,它返回它们块中的最后一个值,
b、when
我们常用的switch-case与三元运算符有着同样的命运,它已被Kotlin的when所取代。
when (three) {
3 -> print("three is three")
2 -> print("three is two?!?")
else -> print("I don't know what's going on anymore")
}
正如你所看到的,else替代了default,->替换了:字符,关键字break也不再需要,因为when表达式将在第一个为真时停止。这些when表达式有一些有趣的地方,它们可以使用任何类型的表达式进行判断,许多情况下,可以捆绑在一起,而对于数值,可以判断它们的范围。
when (three) {
3 -> print("three is three")
1,2 -> print("three is two or one?!?")
in 4..10 -> print("What? Three can't be between 4 and 10!")
else -> print("I don't know what's going on anymore")
}
同样的,我们也可以使用when来返回具体值。虽然这看起来有点像if表达式。
val three = 4
val goodOrNot = when {
three != 3 -> "Liar!"
else -> "Good job"
}
println(goodOrNot) // Liar!
c、for
for循环相对于Java有挺大的改动。
for (i in 1..10) {
print(i)
} // 12345678910
for (i in 1..10 step 2) {
print(i)
} // 13579
val lst = listOf(1,2,3)
for (i in lst){
print(i)
} // 123
在第一个例子中我们使用in关键从range中通过..来分配i的值。第二个例子中使用step关键字,表示我们要从这个范围中取其它值。第三个例子循环列表,将listof值打印出来。
总结
以上就是Kotlin语言的基本组成部分,有了这些你就可以使用Kotlin了。希望在看完这篇文章后,你对Kotlin会有自己的看法,在下一章中我们将介绍null safety, lambdas, collections, and types以及Kotlin语言中几个便利的功能。