Kotlin
中,定义变量时有如下几个方面与 Java 不同
1、位置不同:在 Kotlin 中,数据类型要放到变量后面,并且用冒号(:)分隔,这正好和 Java 相反。
2、变量和常量需要关键字:在 Kotlin 中,定义变量需要用 var 开头,定义常量需要用val 开头。
3、数据类型首字母:在 Kotlin 中,数据类型都以大写字母开头,而在 Java 中, 般只有类、接口等复杂数据类型的名字才采用首字母大写的方式。
4、如果在定义变量时未进行初始化,就必须指定数据类型,如果在定义变 时进行了初始化,就可以不指定数据类型, Kotlin编译器会自动根据等号右侧的值推导数据类型。
演示:
var n : Int = 30 //Kotlin 变量,此处也可以不初始化,等待后期初始化
var ok : Int // 仅定义了 ok 变量,并未初始化,需要在后期初始化
val m: Int = 20 //Kotlin 常量,不需要再次设置
ok = 123// 后期初始化 ok 变量
m = 10// 编译出错,因为 是常量
var k = 100// 自动推导变量 的数据类型
方法声明
无论是什么编程语言,函数的定义都分为如下几部分
> 函数头,包括函数名和标识函数的关键字,如 fun,function
> 参数,包括参数名和参数类型。
> 返回值,包括返回值类型,以及如果没有返回值时的类型是什么。
现在让我们先回顾一下 Java 方法的定义。
Kotlin
:代码
fun add(m:Int, n:Int) :Int
{
return m + n
}
fun process (m: Int): Unit
{
println(m * m)
}
定义 Kotlin 函数时,函数头除了包含函数名外,还必须包含如 关键字。至于 参数,与定义 Kotlin变量的方式相同。如果 Kotlin 函数有返回值,那么返回值类型在函数定 义部分末尾指定,与函数定义部分用冒号( :〉分隔。如果 Kotlin 函数没有返回值,那么可以 返回 Unit ,也可以什么都不返回(省略 Unit )
Kotlin
注释
对于一个复杂的程序,适当的注释是必要的。 Kotlin
中的注释与 Java 中的注释类似,也 支持单行注释和块注释。
但是Kotlin
注释更强大一些,Kotlin
块注释支持嵌套。
/*
hello
/* world */
*/
在`Kotlin`中一切都是对象,任何变量都有相应的方法和属性,不过为了提高执行效率,`Kotlin`对部分数据类型,进行的优化,变成了内置的数据。不过这些类型的变量使用起来就像是普通的类,同样有自己的方法和属性。
Kotlin 提供的内置数据类型
数据类型 | 占用字节数 |
---|---|
Double | 8 |
Float | 4 |
Long | 8 |
Int | 4 |
short | 2 |
Byte | 1 |
Kotlin 数据类型的转换:
字符类型:
布尔类型:
数组:
定义数组有多种方式,使用 arrayOf
函数定义可以存储任意值的数组:使用 arrayOfNulls
函数定义指定长度的空数组(数组元素中没有值〉:使用 Array 类的构造器指定数 组长度和初始化数据的方式定义数组:使用 intArrayOf
,shortArrayOf
等函数定义指定类型的 数组,井初始化数组。下面是 Kotlin
数组的一些典型的例子。
// 使用 arrayOf 函数定义可以存储任意值的数组
val arrl = arrayOf(l , 2, 3,’ a ’)
println (arrl [3])
arr1[2] =’b ’
println (arrl [2])
// 使用 arrayOfNulls 函数定义数组
var arr2 = arrayOfNulls(lO)
println (” arr2 的长度:”+ arr2.size)
// 使用 Array 类的构造器定义数组,其中第二个参数是指初始化每一个数组元素的值
// 每个数组元素的值就是当前数组索引的乘积
val arr3 = Array(lO, { i -> (i * i).toString() ))
println(arr3[3])
//使用 intArrayOf 函数定义数组
var arr4 : IntArray = intArrayOf(20 , 30,40 , 50 , 60)
println (”arr4[2] = ” + arr4[2 ] )
字符串:
使用 String 表示字符串类型,有如下两类字符串。
> 普通字符串 这种字符串类似于`Java ,可以在字符串中加上转义符,如山,会让转义 符后面的字符串换到下 行,这种字符串需要放在双引号中。
> 保留原始格式的字符串(raw string):这种字符串不能使用转义符,如果字符串中带有格式,如换行,直接写在字符串中即可。这种字符串需要放在 个引号对中
代码:
// 类字符串(与 Java 类似)
var sl = ” hello \nworl d ”
var s2:String 世界\ 你好
println (sl)
println (s2)
// 类字符串,保留原始格式
var s3 = ” ””
hello
world
I love you.
println (s3)
也存在包的概念,包在表达方式上与 Java 完全一样,不过 Kotlin 中的包和目录可没什么关系,Kotlin 包仅仅是为了引用文件中的资源而设计的。例如,在下面的 Kotlin代码中 ,定义了一个函数(process)和 一个个类 (MyClass)。实际上,完整的函数名和类名分别foo.bar.process和foo.bar.MyClass.
代码:
package foo.bar
fun process(){}
class MyClass{}
如果我们想引用其他Kotlin
文件中的函数或类,该怎么办呢?现在让我们来做一个试 验,首先建立两个Kotlin
文件: MyKotlin.kt
和 Person.kt
。首先,在Person.kt
文件中输入 下的代码。
package a.b
fun getName () : String
{
return ”Bill Gates ”
class MyClass {}
}
Person.kt 文件开始部分使用 package 关键字定义了a.b
包,如果这个包定义在*.java
文件中,当前源代码文件必须在 alb 目录中,而对于 Kotlin
来说, Person.kt 可以在当前目 录或 任何其他的目录。在本例中, Person.kt 和后面要建立的 MyKotlin.kt
文件在同 个目录,而MyKotlin.kt
文件中并未定义任何包
fun main(args: Array<String>)
{
println (a .b. getName ())
println (a.b.MyClass ()) // 创建对象的实例
}
在MyKotlin.kt
文件的main
函数中,直接通过引用 a.b
包的方式调用了getName
函数 MyClass
类
下面的代码分别导入了 Person.kt 中的getName
函数和MyClass
类。
import a.b.getName
import a.b.MyClass
当然,也可以像下面的代码一样, 一次导入 Person.kt
中的所有资源
import a.b.*
如果按这种方式导入Person.kt
中的资源, MyKotlin.kt
文件的 main
函数就可以按下面的方 式编写。
fun main(args: Array<String>)
{
// getName MyClass 都不需要指定包
println (getName ())
println (MyClass ())
}
Kotlin
中的import
还提供了 个功能,就是给导入资源起一个别名。
import a.b.getName as f
import a.b.MyClass as My
这段代码为 getName
函数起了一个称为 f
的别名,而 MyClass
的别名是 My
。如果资源拥 有了别名 ,在当前文件(MyKotlin.kt
)中,原来的资源名( getName
和 MyClass
)就不可用了, 因此,main
函数需要改成如下形式。
fun main(args: Array<String>)
{
println (f ())
println (My () )
}
在Kotlin
中使用某些API
是不需要 import
任何资源的,其实,Kotlin
会默 认导入一些包,这些包如下:
> kotlin.*
> Kotlin.annotation.*
> kotlin.collections. *
> kotlin.comparisons.* (since 1.1)
> kotlin.io.*
> kotlin.ranges.*
> kotlin.sequences.*
> kotlin.text.*
以上导入的包都是 Kotlin 原生的 API 。还有一些与平台有关的API也会默认导入JVM 默认导入的包如下:
java.Jang.*
kotlin.jvm.*
JavaScript 默认导入的包如下:
kotlin.js. *
条件语句:
if
语句
var a = 20
var b = 30
val max = if (a > b) a else b
println(max)
// if else 后面是一个代码块,最后一个表达式将作为返回值
val min = if (a > b) {
print (” Choose a ” )
a //返回值
) else {
print (” Choose b ” )
b // 返回值
}
when
语句
var x = 1
when (x)
1 -> {
println (” x == 1 ”)
println (”hello world”)
2 ->print (” x == 2 ”)
else - > {
print (”x is ne ther 1 nor 2”)
}
}
注意:
> when 语句会根据传入的值(这里是 )寻找第 个满足条件的分支,找到后执行分支的语句。
> 如果分支中多于 条语旬,要用{...}
> 满足条件的分支执行后,会自动终止 hen 语句的执行,因此,并不需要像 switch语句那样每 case 语句都加上 break。
when if 一样,既可以作为语句使用,也可以作为表达式使用。如果是后者 when 吾句
的第 个满足条件的分支的最后 个表达式就是 when 表达式的返回值。
如果多个分支条件执行的代码都一样,可以在一个分支用逗号(,)分隔多个条件,代码 如下 :
var x = 1
when {x) {
1,2 -> {
println (”已经符合条件”)
3 -> {
println (”不符合条件”)
else -> {
println (”条件未知”)
}
}
如果要执行相同代码的条件比较多,或无法枚举,可以使用 in关键字确定 一个范围,代 码如下:
var n = 25
when (n)
in 1 .. 10 >println ”满足条件”)
in 11 .. 20 ->println (”不满足条件”)
!i 30 .. 60 ->println (”hello world")
else->println (”条件未知”) // !in 表示不在这个范围内
}
其实, when 中的分支条件不仅可以是常量,还可以是任意表达式。例如,下面的代码分 支条件就是 个函数。
fun getValue(x :工 nt): Int{
return x * x
}
fun main(args: Array<String>){
var n = 4
when(n)
{
getValue(2)->println (”满足条件”)
getValue(3)->println (”不满足条件”)
else->println (”条件未知”)
}
}
for
循环
for 循环可以直接枚举集合中的元素,也可以按集合索引来枚举元素。下面的语法是使用迭代器( iterator )枚举集合中的所有元素。