kotlin基础

1、函数和变量


1.1 变量

kotlin中变量的声明和java不一样。
假如你直接为变量名赋值的话不需要指定变量的类型(即kotlin的类型推导机制):

val m="I love you"

如果你没有为变量名赋值的话需要指定变量的类型:

val m:String

声明变量的关键字有两个:
val——不可变引用。对应于java的final变量
var——可变引用。对应于java中的普通变量(不用final修饰)

1.2 函数

这个有点像JS,声明一个函数时必须要用fun关键字

fun max(a:Int,b:Int):Int{
    return if(a>b) a else b
}

我们以上面的代码为例:函数的声明以关键字fun开始,函数名称紧随其后。
本例中函数的基本结构为

开篇的这个小例子主要是想介绍两点:
一是在kotlin中函数的基本声明格式。
二是kotlin和java在if语句上的唯一区别:kotlin中if语句是可以有返回值的,所以才有了上面这种书写方式。
例子中if表达式和java中的三元运算符相似:(a>b)?a:b.

表达式函数体
在书写上我们可以让上例变得更简单,当函数体只有一行代码时,可以省略return关键字,又因为kotlin自动进行类型推导,所以函数声明的返回类型也可以省略。
因为上面的函数它的函数体是由单个表达式构成的,所有可以写成这样的形式:

fun max(a:Int,b:Int):Int=if(a>b)a else b

这种形式的函数就叫做表达式体的函数。

1.3 字符串模板

fun main(args:Array<String>){
    val name=if(args.size>0) args[0] else "kotlin"
    println("hello,$name")
}

$字符不仅可以引用简单的变量名称,还可以引用表达式,不过要把表达式用{}括起来。

${if(args.size>0) args[0] else "someone"}

像上面这个样子的:字符串可以包含模板表达式,即一小段代码,以美元字符$开头被称为字符串模板。

2、类和属性


2.1 属性

class Person{
    val name:String, //只读属性,相当于java中声明了一个变量并提供了一个getter方法
    var isMarried:Boolean//可写属性,相当于java中声明了一个变量并提供了getter,setter方法
}

Person类的使用

val person=Person("Bob",true)
println(person.name)
println(person.isMarried)
运行结果:
Bob
true

2.2 自定义访问器

声明一个矩形,它能自己判断自己是否是正方形。这样的就是自定义访问器。

class Rectangle(val height:Int,val width:Int){
    val isSquare:Boolean
    get(){
        return height==width
    }
}

像上面的代码属性isSquare不需要字段来保存它的值。它的值是每次访问属性的时候计算出来的。

get()方法也可以这样写:get()=height==width

调用的时候

val rectangle=Rectangle(41,43)
println(rectangle.isSquare)
false

3、枚举和"when"关键字


3.1 声明枚举类

声明一个简单的枚举类

enum class Color{
        Red,Green,Yellow
}

声明一个带属性的枚举类

enum class Color(val r:Int,val g:Int,val y:Int){
    Red(255,0,0),Green(0,255,0),Yello(75,0,0);//kotlin中唯一需要使用分号的地方
    fun rgy()=(r*24+g)*23+y    //给枚举类定义一个方法
}
println(Color.Yello.rgy())

3.2 使用"when"处理枚举类

kotlin中的"when"相当于java中的"switch"

fun getMNEMONIC(color:Color)=when(color){
    Color.Red->"I"
    Color.Green->"Love"
    Color.Yello->"You"
}
println(getMNEMONIC(Color.Green))
结果:Love

在这里when它的作用和switch一样,同时它也是一个有返回值的表达式。

在使用when结构中不需要为每个分支写上break语句,这避免了我们忘记写break而造成的bug。对于类似于switch中

case Color.Red:
case Color.Green:
return "I'm cold"

的情况
可以把多个值合并到同一分支,各个值用逗号隔开

Color.Red,Color.Green->"I'm cold"

3.3 在"when"结构中使用任意对象

java中的switch JDK1.7前只能传入类型短于等于int类型的变量作为条件,1.7后增加对String类型的支持,但when允许使用任何对象作为条件。
例如:

fun mix(c1:Color,c2:Color)=when(setOf(c1,c2)){
    setOf(Red,Yello)->ORANGE
    setOf(Red,Green)->BLUE
    else->throw Exception("Dirty color")
}

3.4 使用不带参数的"when"

fun mixOptimized(c1:Color,c2:Color)=when{
    (c1==Red&&c2==Yello)||(c1==Yello&&c2==Red)->ORANGE
    (c1==Red&&c2==Green)||(c1==Green&&c2==Red)->BLUE
    else->throw Exception("Dirty color")
}

3.4中的代码和3.3中的代码实现效果是一样的,不过3.3中代码每次调用setOf()函数都会创建Set实例,调用频繁很容易参数垃圾对象。

4、迭代事物:"while"循环和"for"循环


4.1 "while"循环

kotlin中的"while"循环、do-while循环和java中相应的循环没有什么区别。

4.2 迭代数字:区间和数列

区间:区间本质上就是两个值之间的间隔,这两个值通常是数字:一个起始值,一个结束值。使用...运算符来表示区间
val oneToTen=1..10
ClosedRange的子类,IntRange最常用
0..100表示[0,100]
0 until 100表示[0,100)

数列:能迭代区间中所有的值,这样的区间被称作数列。
for...in循环的最常见的场景是迭代集合

for(i in 1..100){
    println(i)
}

4.3 迭代map

val binaryReps=TreeMap<Char,String>()
for(c in 'A'..'F'){
    val binary=Integer.toBinaryString(c.toInt())//把ASCII码转换为二进制
    binaryReps[c]=binary//根据键c把值存储到map中 等价于java版binaryReps.put(c,binary)
}
for((letter,binary)in binaryReps){
    println("$letter=$binary")
}

可以用展开语法在迭代集合的同时跟踪当前项下标。不需要像上面那样创建单独的变量c来存储下标。

val list=arrayListOf("10","11","1001")
for((index,element)in list.withIndex()){//迭代集合时使用下标
    println("$index:$element")
}

4.4 "in"检查集合和区间的成员

我们通常用in运算符来检查一个值是否在区间中,或者它的逆运算!in来检查这个值是否不在区间中。

fun isLetter(c:Char)=c in 'a'..'z'||c in 'A'..'Z'
fun isNotDigit(c:Char)=c !in '0'..'9'
>>>pirntln(isLetter('q'))
true
>>> println(isNotDigit('x'))
true

5、kotlin中的异常


5.1 "try""catch"和"finally"

和java一样,使用带有catch和fianally字句的try结构来处理异常。

fun readNumber(reader:BufferedReader):Int?{    //不必显式地指定这个函数可能抛出的异常
    try{
        val line=reader.readLine()
        return Interger.parseInt(line)
        }catch(e:NumberFormatEcxeption){
            return null
        }finally{
        reader.close()
        }
}

和java最大的区别就是throws子句没有出现在代码中,如果是java代码的话会显式地在函数声明后写上thrwos IOException.

5.2 "try"作为表达式

fun readNumber(reader:BufferedReader){
val number=try{
        val line=reader.readLine()
        return Interger.parseInt(line)    //没有异常的时候返回这个值
        }catch(e:NumberFormatEcxeption){
            return null    //发生异常的情况下使用null
        }
        println(number)
}

本系列博客参考《kotlin实战》

posted @   我的小鱼干嘞  阅读(167)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· Vue3状态管理终极指南:Pinia保姆级教程
点击右上角即可分享
微信分享提示