Kotlin语言基础学习


简单介绍

定义包

包的声明应处于源文件顶部:

package my.demo
import java.util.*
//...

目录与包的结构无需匹配:源代码可以放在文件系统的任意位置。

定义函数

带有两个Int参数,返回Int函数:

fun sum (a:Int,b:Int):Int{
    return a+b
}

将表达式作为函数体,返回值类型自动推送的函数:

fun sum (a:Int,b:Int) = a + b

函数返回无意义的值:

fun printSum(a:Int,b:Int){
    println("sum $a and $b is ${a+b}")
}

Unit返回类型可以省略:

fun printSum(a:Int,b:Int){
    println("sum of $a and $b is ${a+b}")
}

定义变量

定义只读局部变量使用关键字val定义。只能为其赋值一次。

val a:Int = 1    //立即赋值
val b = 2        //自动推出‘Int’类型
val c:Int        //如果没有赋初值,则不能省略
c = 2            //明确赋值

可重新赋值的变量使用var关键字:

var x = 5
x += 1

顶层变量:

val PI = 3.14
var x = 0

注释

正如Java,Kotlin支持行注释及块注释。

// 这是一个行注释
/* 这是一个多行的
   块注释。*/

与Java不同的是,Kotlin的块注释可以嵌套。

使用字符串模板

使用字符串模板的符号为($)。在$符号后面加上变量名或大括号中的表达式

var a = 1

val s1 = "a is $a"
// 模板中的简单名称

a = 2
val s2 = "${s1.replace("is","was")},but now is $a"
//模板中的任意表达式

println(s2)

执行结果:

a was 1, but now is 2

声明可空变量

在Kotlin中当我们不确定某个属性或变量一定不为空时,我们就把它声明为可空变量.

可空变量的特点:

  • 在声明的时候一定要用标准的声明格式定义。不能用可推断类型的简写;
  • 变量类型后面的?符号不能省略。不然就和普通的变量没区别了;
  • 其初始化的值可以为null或确定的变量值。
class Test{
    //声明可空变量
    var a:Int? = 0;
    val b:Int? = null;
}

常量的用法

在Kotlin中val修饰的还不是常量,他只是个不能修改的变量。常量的定义还需要再val关键字前加上const关键字。即:

const val NUM_A = 6

其特点:const只能修饰val,不能修饰var

声明常量的三种方式:

  1. 在顶层声明;
  2. object修饰的类中声明,在kotlin中称为对象声明
  3. 在伴生对象中声明。

例如:

// 1.顶层声明
const val Str_A :String = "顶层声明"

// 2.在object修饰的类中
object TestConst{
    const val Str_B = "object修饰的类中"
}
// 3.在伴生对象中
class TestClass{
    companion object{
        const val Str_C = "在伴生对象中"
    }
}

数据类型

数值类型

1. 数字的内置类型

  • Byte => 字节 => 8位
  • Short => 短整型 => 16位
  • Int => 整型 => 32位
  • Long => 长整型 => 64位
  • Float => 浮点型 => 32位
  • Double => 双精度浮点型 => 64位

注意:

  • 长整型在数值末用大写字母L标记
  • 单精度浮点型由字母F(大写小写无妨)标记

    2. 进制数

Kotlin不支持八进制数

3. 数字类型字面常量的下划线

作用:分割数字进行分组,使数字常量更易读

例如:

val oneMillion = 1_000_000
val phoneNum = 155_0746_2014

4. 装箱与拆箱

装箱就是值类型转换为object类型,拆箱相反:object转化为值类型。在kotlin中,存在数字的装箱,但是没有拆箱。因为kotlin是没有基本数据类型的,Kotlin是万物皆对象的原则。

kotlin中要实现装箱操作,首先要了解可空引用。即类似Int?(只限数值类型)此类的:

val numValue:Int = 1
// 装箱的过程,装箱后其值是没有变化的
val numValueBox:Int = numValue

两个数值的比较

  • 判断两个数值是否相等==
  • 判断两个数值在内存中的地址是否相等===

5. 转换

  • 显式转换

    较小的类型不会被隐式转换位更大的类型,故而系统提供了显式转换:

    • toByte() => 转换为字节型
    • toShort() => 转换为短整型
    • toInt() => 转换为整型
    • toLong() => 转换为长整型
    • toFloat() => 转换为浮点型
    • toDouble() => 转换为双精度浮点型
    • toChar() => 转换为字符型
    • toString() => 转换为字符串型
  • 隐式转换

    类型是从上下文推断出来的,即算术运算则被重载为适当的转换:

    val num = 30L + 12
    println(num)
    // 30L + 12 -> Long + Int => Long

6. 位运算符

// 。。。。。

布尔类型

1. 关键字

Boolean关键字表示布尔类型,并且其值有turefalse

var isNum:Boolean
isNum = false

2. 逻辑操作符

  • ‘||’ => 逻辑或
  • ‘&&’ => 逻辑与
  • ‘ ! ’ => 逻辑非

字符型

1. 关键字

Char表示字符型,字符变量用单引号(‘’)表示。并且不能直接视为数字,不过可以通过显式转换为数字:

var char_1:Char
char = 'a'
char = 1    //报错

2. 显示转换为其他类型

字符型的变量不仅会可以转换为数字,同时也可转换为其他类型:

var var1 = char_1.toByte()
var var2 = char_1.toInt()
//...

除了类型转换,当变量为英文字母时还支持大小写转换:

var charA:Char = 'a'
var charB:Char = 'B'
var result:Char

result = charA.toUpperCase()    //转换为大写
result = charB.toLowerCase()    //转换为小写

3. 字符转义

  • \t => 制表符
  • \n => 换行符
  • \b=> 退格键
  • \r=> 回车键
  • \\=> 反斜杠
  • \'=> 单引号
  • \$ => 美元符号
  • **其他的任何字符请使用Unicode转义序列语法,例如:’\uFF00’

字符串类型

1. 关键字

String表示字符串类型。其实不可变的。所以字符串的元素可以通过索引操作的字符:str[index]来访问。可以使用for循环迭代字符串:其中str[index]中的str要为目标字符串,index才能为索引:

val str:Sting = "kotlin"
//迭代
for (s in str){
    print(s)
    print("\t")
}

2. 字符串字面量

Kotlin中,字符串字面量有两种类型:

  • 包含转义字符的字符串,转义包括(\t, \n等),不包括转义字符串的也同属此类型
  • 包含任意字符的字符串,有三重引号("""...""")表示

数组型

  • Kotlin中数组由Array<T>表示
  • 创建数组的三个函数:
    • arrayOf()
    • arrayOfNulls()
    • 工厂函数(Array()

1. arrayOf()

创建一个数组,参数是一个可变参数的泛型对象:

val arr1 = arrayOf(1,2,3,4,5)
for (v in arr1){
    print(v)
    print("\t")
}

2. arrayOfNulls()

用于创建一个指定数据类型且可以为空元素的,给定元素个数的数组:

var arr2 = arrayOfNulls<Int>(3)
// 若不予数组赋值则arr3内元素皆为null

3. 工厂函数

  • 使用工厂函数Array(),它使用数组大小和返回给定其索引的每个数组元素的初始值的函数。
  • Array()=> 第一个参数表示的个数,第二个参数则为使用其下标组成的表达式
var arr3 = Array(5,{index -> (index*2).toString()})
for (v in arr4){
    print(v)
    print("\t")
}

执行结果:

0    2    4    6    8

4. 原始类型数组

kotlin还有专门的类来表示原始类型的数组,没有装箱开销,它们分别是:

  • ByteArray => 表示字节型数组
  • ShortArray => 表示短整型数组
  • IntArray => 表示整型数组
  • LongArray => 表示长整型数组
  • BooleanArray => 表示布尔型数组
  • CharArray => 表示字符型数组
  • FloatArray => 表示浮点型数组
  • DoubleArray => 表示双精度浮点型数组

Kotlin不支持字符串类型这种原始类型的数组

var intArr:IntArray = intArrayOf(1,2,3,4,5)

var charArr:CharArray = charArrayOf('a','b','c','1','2')

控制语句

if语句

kotlin中的if语句很灵活,除了普通的判断,还可以实现表达式(实现三元运算符),及作为一个块的作用

1. 传统写法

var numA = 2
if (numA == 2){
    println($numA)
}else{
    println($numA-1)
}

2. Kotlin中的三元运算符

Kotlin中其实不存在三元运算符(condition ? then : else)这种运算,那是因为if语句的特性:if表达式会返回一个值,所以不需要三元运算符。

var numB:Int = if (numA > 2) 3 else 5
println(numB)

3. 作为一个块结构,并且最后一句表达式为块的值

var numA:Int = 2
var numC:Int = if(numA > 2){
    numA = 10
    numA
}else if (numA == 2){
    numA = 20
    numA
}else{
    numA = 30
    numA
}

for语句

  • for循环提供迭代器用来遍历任何东西
  • for循环数组被编译为一个基于索引的循环,它不会创建一个迭代器对象

规则

  • 递增

    • 关键字:until

    • 范围:until[n,m] => 大于等于n,小于m

    • 例如:

    // 循环5次,且步长为1的递增
    for (i in 0 until 5){
        print(i)
    }
  • 递减

    • 关键字:downTo
    • 范围:downTo[n,m] => 大于等于n,小于等于m,n > m

    • 例如:

      // 循环5次,且步长为1的递减
      for(i in 15 downTo 11){
          print(i)
      }
  • 符号(..)

    表示递增循环的另外一种操作

    • 使用符号..

    • 范围:..[n,m] => 即大于等于n,小于等于m

    • until有区别,但更为简便,且范围不同

    • 例如:

      for (i in 20..25){
          print(i)
      }
  • 设置步长

    • 关键字:step

    • 例如:

      for (i in 10 until 16 step 2){
          print(i)
      }

遍历字符串

例如:

for (i in "asdfghjk"){
    print(i)
}

遍历数组

例如:

var arrayList = arrayOf(1,3,5,7,9)
for (i in arrayList){
    print(i)
}
var arrayList = arrayOf(1,3,5,7,9)
for (i in arrayListTwo.indices){
    println("arrayList[$i] => " + arrayList[i])
}
var arrayList = arrayOf(1,3,5,7,9)
for ((index,value) in arrayList.withIndex()){
    println("index => $index \t value => $value")
}

使用列表或数组的扩展函数遍历

  • 数组或列表有一个成员或扩展函数iterator()实现了Iterator<T>接口,且该接口提供了next()hasNext()两个成员或扩展函数
  • 其一般和while循环一起使用

例如:

var arrayList = arrayOf(2,'a',3,false,9)
var iterator: Iterator<Any> = arrayList.iterator()

while (iterator.hasNext()){
    println(iterator.next())
}

when语句

when语句类似于C类语言中的switch语句,不过比它更强大。

实现switch语句功能

when(5){
    1 -> {
        print("1")
    }
    2 -> {
        print("2")
    }
    esle -> {
        print("5")
    }
}

与逗号结合

when(1){
    // 即值为1,2,3时都输出1
    1,2,3 -> {
        print("1")
    }
    else -> {
        print("0")
    }
}

条件可以使用任意表达式

var num:Int = 5
when (num > 5){
    true -> {
        print("num > 5")
    }
    false -> {
        print("num < 5")
    }
    else -> {
        print("num = 5")
    }
}

检查值是否存在于集合或数组中

  1. 操作符

    • in
    • !in不在
  2. 限定:只适用于数值类型

例如:

var arrayList = arayOf(1,2,3,4,5)
when(1){
    in arrayList.toIntArray() -> println("1 存在于arrayList数组中")
    in 0 .. 10 -> println("1 属于0~10中")
    !in 5 ..10 -> println("1 不属于5~10中")
    else -> println("都错了!")
}

检查值是否为指定类型的值

  1. 操作符

    • is
    • 不是!is
  2. 注意:kotlin的智能转换可以访问类型的方法和属性

例如:

when("abc"){
    is String -> println("是字符串")
    else -> println("不是字符串")
}
//智能转换
var a:Int = 2
when(a){
    !is Int -> println("$a 不是一个整型的数")
    else -> {
        a = a.shl(2)
        println("a => $a")
    }
}

不使用表达式的when语句

表示为最简单的布尔表达式

var array = arrayOfNulls<String>(3)
when{
    true -> {
        for (i in array){
            print(" $i \t")
        }
        println()
    }
    else -> {

    }
}

其它语句

  • while语句

  • do while语句

  • 跳转语句:return,break,continue

与C类语言一致,不做赘述。

操作符

一元操作符

简单一元

操作符 重载
+a a.unaryPlus()
-a a.unaryMinus()
!a a.not()

复杂一元

操作符 重载 表示
a++ a.inc() a = a.also{ a.inc() }
a– a.dec() a = a.also{ a.dec() }
++a a.inc() a = a.inc().also{ a = it }
–a a.dec() a = a.dec().also{ a = it }

二元操作符

简单二元

操作符 重载
a + b a.plus(b)
a - b a.minus(b)
a * b a.tiems(b)
a / b a.div(b)
a % b a.rem(b)
a .. b a.rangTo(b)

复杂二元

操作符 表示 重载
a += b a = a + b a = a.plus(b)
a -= b a = a - b a = a.minus(b)
a *= b a = a * b a = a.tiems(b)
a /= b a = a / b a = a.div(b)
a %= b a = a % b a = a.rem(b)

区间操作

区间操作符:..,注意两个操作数都是整型

操作符 表示 重载
a .. b a 到 b 中间的值 a.rangeTo(b)

进阶操作

可空类型,空安全

定义一个可空类型的变量

修饰符 变量名 : 类型? = 值

判断可空类型的两种方式

  • if…else… 判断

  • 使用符号?.判断

    该符号的用法为:可空类型变量?.属性/方法。如果可空类型变量为null是,返回null;

    这种方法大量用于链式操作的用法中,能有效避免空引用异常,因为只要链式中有一个null,则整个表达式都为null


文章作者: Mahoo Huang
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Mahoo Huang !
评论
  目录