一、基本语法
1、 包:
源文件通常以包声明为开头
eg: package tian.song
fun baz(){} fun goo(){}
源文件所有内容都包含在声明的包内,所以baz全名为tian.song.baz, tian.song.goo
若没有指明包,该文件属于无名的默认包。
导入方式:
1>import foo.Bar //导入Bar,现在Bar可以不用限定符
2>import foo.*
3>import bar.Bar as bBar //如果名字冲突用as进行本地重名来解决歧义。
2、定义函数:
(1)函数定义使用的 fun 关键字,
eg: fun sum(a:Int, b:Int) :Int{
return a+b
}
(2)讲表达式作为函数体,返回值类型自动推断的函数
fun sum(a:Int, b:Int) = a + b
(3)返回值无意义的函数,相当于Java中的void
fun print(a:Int, b:int): Unit {
println(a+b)
}
这种方法Unit可以省略
fun print(a:Int, b: Int) {
println(a+b)
}
3、定义变量:
(1)只读变量:一次赋值只读的局部变量,只读关键字 val
val a: Int = 1 //变量类型在后,
val a = 1 // 自动推断出 Int 类型,类型可以省略
val c : Int //只读变量声明没有初始值,类型不能省略
c = 3 //明确赋值
(2)可变变量:关键字 var
var x = 5 //自动推断出类型 Int ,
var x : Int = 5
(3)顶层变量
val PI = 3.14
var x = 0
二、基本类型:
1、数字,kotlin数字与Java类似,但没有隐式拓宽转换,如java int可转换为long,
类型包括 Double(64bit) Float(32) Long(64) Int(32) Short(16) Byte(8)
1>字面常亮:不支持八进制
十进制: 123
十六进制:0x0f
二进制 : 0000101011
Double 123.5 124.5e10
Float 123.5f
注:数字字面值中可以使用下划线,使常量更易读
val a = 1000_1000_1000
kotlin数字会保存为jvm原生类型,当我们需要一个可空引用或泛型时,
kotlin会把数字装箱
eg: val a:Int = 100; //a为原生类型
val a:Int? = 100 //a被数字装箱
kotlin装箱保留了数字的相等性
eg: val a:Int? = 1000
val b:Int? = 1000
print(a==b) //true
封装后保存地址不在相等
print( a === b ) //false
2>显式转换
因为不同的表示方式,所以较小的类型不是较大类型的子类,不会出现隐式转换
rg: val a:Int? = 1
val b:Long? = a //错误,因为不能隐式转换,类型不同赋值报错。
println(a == b) //false,
显式转换
val i: Int = b.toInt() //显示转换
每个数字类型都支持 toByte() toShort toInt toLong toFloat toDouble toChar
需要显式转换并不太影响程序,因为类型会从上下文中推断,算数运算会重载
做适当的转换
eg: val b= 1L + 3 //Long +_Int =>long
2、字符:
字符用Char表示,不能直接当做数字
字符字面值用单引号 '1' 'a' 特殊字符用反斜杠转义 \$
显式转换为数字 '1',toInt()
3、布尔 只有true false
|| 逻辑或 &&逻辑与 !逻辑非
4、数组
kotlin中使用Array类来表示数组,定义了get set函数和size属性。
我们可以使用库函数arrayof()来穿件一个数组并传值给他,eg:arrayof(1,2,3)
库函数arrayOfNulls(),用来创建一个指定大小,元素为null的数组。
Array还可以接受一个数组大小和一个函数作为参数构造array,函数可以根据返回值为
给定索引的每一个元素赋值
eg: val arr = Array(5, {i -> (i * i).toString()})
//创建一个Array(String) 初始值为"0" "1" "4" "9" "16"
[]运算符代表了get和set方法 arr[1] = 1
kotlin中可以使用无装箱开销的专门的类来表示原生类型数组ByteArray ShortArray
IntArray等,这些类和Array并没有关系,但用法,方法一致,都用相应的工厂方法
eg: val x: IntArray = intArrayOf(1,2,3)
5、字符串
字符串用String 表示,字符串不可变,字符串可以用索引运算访问 s[1],或者用for循环迭代
eg: val str = "abcd"
for(c in str) { print(c) }
可以用+链接两个字符串。也可以用字符串链接其他类型的值,只要表达式中第一个元素是字符串
>字面值
转义字符串字面值用”“,字符里面带有转义字符
eg: val s = "Hello world\n"
原始字符串使用三个引号""" """ ,内部没有转义,可以包含换行和其它任何字符
eg: val str = """ for (c in "tian") { print(c) }"""
//这个会原封不动的输出""""""里面的内容
val text="""|tian|song|tao""".trimMargin()
//trimMargin(">") 设置字符前缀,默认使用|
5.1、字符串模板
字符串可以包含模板表达式,就是一小段代码,会把求得的值合并到字符串中,以美元$符号开头
eg: var i = 10
println("i = $i") //输出i=10
可以用{}表示任意表达式
eg: val s = "abc"
print("$s.length is ${s.length}") //输出 adb.length is 3
$不支持反斜杠转义,原生字符串需要使用${'$'} 来完成
eg: val price = """${'$'}9.99 """
三、控制流
if when for while
1、if kotlin中if是一个表达式,
eg: var max = a
if (a < b) max = b //传统用法
if ( a< b) {
max = b
} else {
max = a
}
var max = if (a <b) b else a //表达式写法, 使用表达式,需要有else分支。
var max = if (a < b) { //表达式分支可以是代码块,最后的表达式表示该快的值
print("")
a //这里表示该块的值
} else {
print("")
b
}
2、 when表达式,类似c语言的switch语句,
when将他的参数与所有的分支条件顺序比较,直到某一分支满足条件,若都不满足,则执行else
when(x) {
1 -> print("x == 1")
2,3 -> print("x == 2") //多个条件一起用,隔开
parseInt(x) -> print(" s is Int") //条件可以是一个表达式,并不一定要是常量。
is String -> print(" s.length is ${s.length}")
else -> {
print(" x is neither 1 or 2")
}
}
3、for循环,
for循环可以对任何提供迭代器的对象遍历,
for( item :Int in ints) { print("") }
//通过索引遍历数组
for(i in array.indices) {
println(array[i])
}
这里有一个withIndex()函数比较有用,
val array = arrayof("a". "b", "c")
for((index, value) in array.withIndex()) {
println("the element at $index is $value")
}
所谓提供迭代器的对象:
有一个成员函数或者扩展函数iterator(),他的返回类型有一个成员函数或者扩展函数net,
并且有一个成员函数或者扩展函数hasNext(),返回值为boolean.(这种方法可以去了解一下)
4、while循环
while和 do..while 照常使用
while(x > 0) {}
do {}while(X > 0)
5、循环中的break和continue ,返回和跳转。标签
kotlin中标签用标识符后跟@表示,tian@ song@ ,要为表达式添加标签,就在其前加标签
eg: loop@ for(i in 1.. 10) {
for(e in 1 : 10) {
println(e)
break@loop
}
}
break加标签跳转到该循环后面的执行点,也就是跳出这个双层循环,continue表示跳过这次迭代,进行
下一次迭代。
还有return标签返回,这里以后再介绍。