Kotlin基础语法

基础语法

1.包定义
package my.demo

包定义在顶部,与Java语法一样,但需要注意的是,目录和包的结构无须匹配,但是最好匹配,不然一堆坑

2.函数定义
fun sum(a:Int,b:Int){
    return a+b
}

函数使用_fun_定义,变量名在前,变量类型在后,也可以将表达式作为函数体,返回值会自动推断

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

函数可以返回一个无意义的值(类似于返回一个空值或无返回值或返回一个Null,而Kotlin这里返回一个Unit类型的无意义的值),若返回一个有意义的值的话,将返回值类型写到函数后面,类似于fun sum():Int {}。kotlin中支持以占位符的形式输出语句(字符串模板),不需要类似于logback使用{},使用**$变量**方式,但是这种方式适合于测试,因为底层仍然使用的String.valueOf,调用toString方法去输出,使用logback等日志框架的时候,可以延迟构建日志信息的开销(String),提高程序性能

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

Unit这个返回类型可以省略掉,如下所示

fun printSum(a:Int,b:Int){
    println("sum of $a and $b is ${a+b}")
}
3.变量定义

分为不变和可变变量,分别使用valvar来定义(val更加类似于静态变量,但能否通过类名.变量名来调用,未测试

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

//可变变量
var x = 5
5 += 1

//顶层变量,类似于全局变量
val PI = 3.14
var x = 0
fun incrementX(){
    x += 1
}
4.注释

与java注释一样,但kotlin的块注释可以嵌套,类似于这样

/** 
 * hhhh 
 * /** 
 *  fff 
 *  /** 
 *    ggggg 
 *  */  
 * */  
 *  
 * abc  
 *  
 */
5.字符串模板

上面说过一些,这里补充下,字符串模板中支持模板表达式,类似于这样

var s1 = "try again or walk way"
val s2 = "${s1.replace("or","and")} , ${s1.length}"
6.条件表达式

类似于这样

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

也可以这样,因此在kotlin中并没有三目运算符,if就能做到

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

还可以作为代码块使用

val max = if(a>b){
    println("Choose a ")
    a
}else{
    println("Choose b ")
    b
}
7.null检测

kotlin中,变量的声明,默认都是不能为空的,如果该变量可以为空,则必须在类型后加**?**表示该引用可以为空。如果该变量标注了可以为空,则在使用该变量的一些方法时,会编译不通过。必须进行null判断,而在null判断之后,该变量会自动转换为非空值。如下所示

fun printProduct(x:Int?,y:Int?){
    //因为x和y有可能为null,因此必须进行null判断
    if(x != null && y != null){
        // 在空检测后,x 和 y 会自动转换为非空值(non-nullable)
        println(x*y)
    }else{
         println("either '$arg1' or '$arg2' is not a number")
    }
}

kotlin中没有三目运算符,但是有些地方类似三目运算,使用起来比三目运算符更方便
例如:

val l = b?.length ?: -1

如果**??*左侧表达式非空,就返回左侧表达式,否则返回右侧表达式

8.类型检测以及自动类型转换

使用is检测一个表达式是否是某类型的一个示例, 如果一个不可变的局部变量或属性已经判断出为某类型,那么检测后的分支中可以直接当作该类型使用,无需显式转换,例如

fun getStringLength(obj:Any):Int?{
    if(obj is String){
        //在当前条件分支内obj自动转换为String
        return obj.length
    }
    return null
}

fun getStringLength(obj:Any):Int?{
    if(obj !is String) return null
    //当前分支自动转换为String
    return null
}

fun getStringLength(obj: Any): Int? {
    // `obj` 在 `&&` 右边自动转换成 `String` 类型
    if (obj is String && obj.length > 0) {
        return obj.length
    }

    return null
}

注:Any表示任何类型(Anything),类似于Java中的Object

9.for循环

类似于python

val items = listOf("apple","banana","kiwi")
for(item in items){
    println(item)
}

fun main(args: Array<String>) {
    val items = listOf("apple", "banana", "kiwi")
    //indices表示该list的下标数组
    for (index in items.indices) {
        println("item at $index is ${items[index]}")
    }
}

甚至这样

//可以直接遍历对象中的属性,编译时候会优化,不会产生额外对象
for((index,value) in array.withIndex()){
    println("the element at $index is $value")
}
10.while循环

while 和 do-while与Java一样

11.when表达式

类似于Java中的switch-case语句,但是比其更强大,更好用

when(x){
    1 -> print("x == 1 ")
    2 -> print("x == 2 ")
    else ->{
        print("x is neither 1 nor 2")
    }
}

一般情况下when必须有else分支,但是如
果编译器能够检测出所有的情况都已经覆盖,则可以不加else分支
when可以使用任意表达式作为分支条件,而不只是常量,甚至还可以使用in,is,fun等表达式,这是相对Java来说很好的一个方面,例如

when(x){
    in 1..10 -> println("x is in the range")
    in validNumbers -> println("x is valid")
    !in 10..20 -> println("x is outside the range")
    is String -> println("x is String")
    else -> print("none of the above")
}

when可以用来取代if-else,若不提供条件,则为真的时候执行该分支

12.区间

类似于python,基础语法如下

//基础
for(x in 1..5){
    println(x)
}
//在某个区间
if(x in 1..5){
    println(x)
}
//不在某个区间
if(x !in 1..5){
    println("x not exist 1..5")
}
//区间迭代
for(x in 1..100 step 2){
    //step 表示步距为2
    println(x)
}

in只适合于正序,若倒序的话需要使用

for(x in 5 downTo 1){
    //downTo中也可使用step
    println(x)
}

1…10指1-10这十个数字,如果需要包头不含尾的话,需要使用until,例如

for(i in 1 until 10){
    println(i) //1-9
}
12.集合

集合初始化

val list = listOf("apple","banana","kiwi")
val set = setOf("apple","banana","kiwi")
//使用泛型规定map类型
val map = mapOf<String,Int>(Pair("1",21),Pair("2",53))
println(map.get("1"))
//map中有两个函数很好用,分别是getOrDefualt和getOrElse,如果map中没有找到key对应的value的话,就可以这么使用
map.getOrDefault("3", 99)
map.getOrElse("4", defaultValue = { 1 })

对集合进行迭代

for(item in items){
    println(item)
}

用in判断集合是否包含某个示例

when{
    "orange" in items -> println("juicy")
    "apple" in items -> println("apple is fine too")
}

在kotlin中也可以使用类似于Java8的lambda表达式,因此可以这么做

list.filter{it.}
13.类和对象的基本使用
abstract class Shape(private val sides: List<Double>) {
    val perimeter: Double get() = sides.sum()
    abstract fun calculateArea(): Double
}

interface RectangleProperties {
    val isSquare: Boolean
}

//这里省略了一个关键字constructor,相当于自动构建了Rectangle的主构造函数,如果构造函数中的所有参数都有默认值,则kotlin会多创建一个无参数的构造函数
class Rectangle(
        //在idea中,变量会占据两个tab
        private var height: Double,
        private var length: Double,
) : Shape(listOf(height, length, height, length)), RectangleProperties {
    //使用:来继承或实现接口,在kotlin中没有@Override注解,但是需要在方法前加一个override来标记为重写方法
    override fun calculateArea(): Double = height * length

    override val isSquare: Boolean get() = length == height

}

class Triangle(
        private var sideA: Double,
        private var sideB: Double,
        private var sideC: Double
) : Shape(listOf(sideA, sideB, sideC)) {
    override fun calculateArea(): Double {
        var s = perimeter / 2
        return Math.sqrt(s * (s - sideA) * (s - sideB) * (s - sideC))
    }
}

fun main(args: Array<String>) {
    val rectangle = Rectangle(5.0, 2.0)
    val triangle = Triangle(3.0, 4.0, 5.0)
    println("Area of rectangle is ${rectangle.calculateArea()}, its perimeter is ${rectangle.perimeter}")
    println("Area of triangle is ${triangle.calculateArea()}, its perimeter is ${triangle.perimeter}")

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值