您现在的位置是:首页 >其他 >Kotlin网站首页其他

Kotlin

杪&秋 2023-06-10 04:00:02
简介Kotlin

目录

一、简介

1、使用原因

二、基本语法

1、数据类型

 2、数组

(1、)创建

(2、)遍历

3、集合

4、方法

(1、)普通类的方法

(2、)静态类的方法

(3、)companion object伴生类的方法

(4、)方法参数

5、Lambda表达式

6、条件控制

(1、)if表达式

(2、)when

7、泛型

(1、)泛型接口/类

(2、)泛型方法

(3、)泛型约束

(4、)泛型中的out与in

8、Kotlin扩展

(1、)扩展方法

(2、)泛型扩展方法

(3、)扩展属性

 (4、)let、run、apply

三、案例


一、简介

Kotlin是一门用于现代多平台应用的静态编程语言,其中被广泛用于Android平台的开发,被称之

Android世界的Swift。它由大名鼎鼎的JetBrains公司设计开发并开源,著名的IDE 工具IntelliJ

IDEA就是他们的产品,所以无疑他们是对编程语言设计领域最为熟悉的专家。安卓世界的斯威夫

特。它由大名鼎鼎的JetBrains公司设计开发并开源,著名的IDE工具IntelliJ IDEA就是他们的产

品,所以无疑他们是对编程语言设计领域最为熟悉的专家.

Kotlin 从2016年发布1.0的release 版本开始至今,使用的开发者数量快速增长。

1、使用原因

2019年Google lO大会上,google宣布今后将优先采用Kotlin进行Android开发

Kotlin是一种新型的静态类型编程语言,不仅可以减少常见代码错误,还可以轻松集成到现有应用

中。

富有表现力且简洁可以使用更少的代码实现更多的功能。少编写样板代码。在使用Kotlin的专业开

发者中,有67%的人反映其工作效率有所提高。

更安全的代码Kotlin有许多语言功能,可帮助避免null指针异常等常见编程错误。包含Kotlin代码

Android应用发生崩溃的可能性降低了20%。

可互操作可以在Kotlin 代码中调用Java 代码,或者在Java代码中调用Kotlin代码。Kotlin 可完全

Java编程语言互操作,因此可以根据需要在项目中添加任意数量的Kotlin 代码。

结构化并发Kotlin协程让异步代码像阻塞代码一样易于使用。协程可大幅简化后台任务管理,例如

网络调用、本地数据访问等任务的管理。

二、基本语法

1、数据类型

基本数值类型、浮点类型、字符类型、字符串类型、类型强制转换、数字运算

package com.example.fristapp.lesson

fun main() {
    var str="123456"

    //字符串的模板表达式 以$开始
    println("the result is $str")
    println("the result is ${str.length}")

    println("-----------")

    //helloworld3要求它的字符串内容是json格式,
    val helloworld3 = "{"key":"value"}"
    //"""分解符,字符串内容无需转义,看起来更清爽
    val helloworld4 : String = """
            |Tell me and I forget
            |Teach me and I remember
            |{"key1": "value1"}
            |{"key2": "value3"}
    """.trimIndent()
    println("helloworld4"+helloworld4)
    println("-----------")
    println(helloworld3)
}

 2、数组

(1、)创建

arrayOf创建数组

创建一个数组并传递元素值给它,集合中的元素可以是任意类型

//arrayOf创建数组
    val arrayNumber:Array<Int> = arrayOf(1,2,3,4,5)
    val arrayObjects:Array<Any> = arrayOf(1, "2" , true)//任意类型

    //2.使用arrayOfNulls创建空数组,
    //创建一个指定大小的、所有元素都为空的数组,但必须指定集合中的元素类型
    val arrayOfNulls= arrayOfNulls<String>(5)
    arrayOfNulls[0]= "12345"
    println(arrayOfNulls)

    //3 .利用array的构造函数,动态创建数组
    //创建一个 Array<String>初始化为["O","1","4","9","16"]ll i= 0,1,2,3,4
    //i*i ="0","1","4","9","16"
    //数组创建的时候,会循环5次,i就是数组的下标l/→>右边的表达式的结果,就是数组中当前下表的元素
    val asc = Array( 5) { i : Int->(i * i).toString() }

(2、)遍历

3、集合

List是一个有序集合,可通过索引(下标)访问元素。元素可以在 list中出现多次、元素可重复

Set是唯一元素的集合。一组无重复的对象。一般来说set中元素的顺序并不重要、无序集合

Map(字典)是一组键值对。键是唯一的,每个键都刚好映射到一个值,值可以重复。

可变集合,显而易见,是指集合创建完成之后,可以对集合进行增删改查操作

不可变集合,显而易见,是指指集合创建完成之后,不能对集合进行增删操作,会抛异常

4、方法

(1、)普通类的方法

class Person{
    fun tes(){
        println("普通成员方法")
    }
}

(2、)静态类的方法

如果我们想实现一个工具util的话,可以借助关键字object来创建一个静态类

object UtilNumber{
    fun test2(){
        println("静态成员方法")
    }
}

(3、)companion object伴生类的方法

class Person{
    fun tes(){
        println("普通成员方法")
    }
    companion object{
        fun test2(){
            println("伴生成员方法")
        }
    }
}

(4、)方法参数

默认参数

方法参数可以有默认值,当省略相应的参数时使用默认值。与其Java相比,这可以减少重载数量我

们可以通过类型后面的=来设置默认值。

 fun read(offset: Int = 0 ,start: Int){
        offset+start
    }

具名参数

如果一个默认参数在一个无默认值的参数之前,那么无默认值的参数,只能通过使用具名参数调用

该方法来使用:

 fun read1(offset: Int= 1,start: Int){
        offset+start
    }

//offset:int他有一个默认值是为0start:int他没有默认值
    //第三个参数是一个方法,参数名叫作,action:()。如果参数的类型是(),说明该参数是一个方法类型//方法参数的返回值使用-> String。
    fun read2(offset: Int =2,start: Int,action:()->String){
        val ret = action()
        println("read2:${ret}")
    }

------------------
Person().read1(start = 1)

 Person().read2(1,3, action = {
        "aaaaa"
    })


Person().read2(start = 3){
        "括号外传递action参数"
    }

可变数量的参数

方法的参数(通常是最后一个)可以用vararg修饰符标记:

 fun append(vararg str:Char):String{
        val result = StringBuffer()
        for (char in str) {
            result.append(char)
        }
        return result.toString()
    }

-------------------------------

val appendStr = Person().append('1','3','5')
    println("append${appendStr}")

val world = charArrayOf('w','o','r','d')
    val result = Person().append('h','e',*world)

只有一个参数可以标注为vararg;

如果vararg 参数不是最后一个参数,可以使用具名参数语法,给后面的参数的传递值.

5、Lambda表达式

在Java 8的时候开始支持Lambda表达式,目前Lambda语法在Java中已经被广泛的运用,Lambda

表达式可以理解为是一种语法糖,值得庆幸的是,Kotlin一经开源成熟就已经支持这种语法。

Lambda表达式的本质其实是匿名方法,因为在其底层实现中还是通过匿名方法来实现的。但是我

们在用的时候不必关心起底层实现。不过Lambda的出现确实是减少了代码量的编写,同时也是代

码变得更加简洁明了。

6、条件控制

(1、)if表达式

if 是一个表达式所以它会返回一个值,表达式的值为表达式作用域内最后一行的值

(2、)when

7、泛型

Kotlin 的泛型与Java一样,都是一种语法糖。泛型(Generics)其实就是把类型参数化,它的引入给

强类型编程语言加入了更强的灵活性。

使用原因

架构开发的一把利器;

使我们的代码或开发出来的框架更加的通用;

增加程序的健壮性,避开运行时可能引发的ClassCastException;

能够帮助你研究和理解别的框架;

自己造轮子需要,能用泛型解决问题;

泛型有:泛型类、泛型接口、泛型方法和泛型属性

(1、)泛型接口/类

定义泛型类型,是在类型名之后、主构造函数之前用尖括号括起的大写字母类型参数指定:

//泛型接口
interface Drink<T> {
    fun drink(t: T):String
}
class DrinkApple:Drink<String>{
    override fun drink(t: String):String {
        println("drink:${t}")
        return t
    }
}
//泛型类
abstract class Color<T>(val t: T){
    abstract fun printColor()
}
class BlueColor(val color: String):Color<String>(color){
    override fun printColor() {
        println("printColor${color}")
    }
}

(2、)泛型方法

//泛型方法
fun <T> fromJson(json:String ,tClass:Class<T>):T?{
    val instance:T? =tClass.newInstance()
    return instance
}

(3、)泛型约束

//泛型约束(1)
//泛型类型限定-1
//所传递的类型T必须满足是User的子类或User类
class User1{

}
fun <T:User1> fromJson2(json:String ,tClass:Class<T>):T?{
    val instance:T? =tClass.newInstance()
    return instance
}
//泛型约束(2)
所传递的类型T必须同时满足where子句的所有条件,在下面的示例中,类型丁必须既实现了User,也实现了Comparable
fun <T> fromJson3(json:String , tClass : Class<T>): T? where T :JSONObject ,T:Comparable<T>{
    val instance:T? =tClass.newInstance()
    return instance
}
class User : JSONObject(),Comparable<User>{
    override fun compareTo(other: User): Int {
        return 0
    }
}



-------------
fromJson2("{}",User1::class.java)
    fromJson3("{}",User::class.java)

(4、)泛型中的out与in

out约束泛型参数的类型上限

泛型参数的类型允许传入T,以及T的子类

//out关键字
    open class Animal
    open class DogAnimal:Animal()
    class CatAnimal : Animal()
    class WhitDogAnimal: DogAnimal()
    fun animaalFuns(){
        val animal: Animal = DogAnimal()
        //传入的泛型参数可以是 Animal及Animal的子类DogAnimal,CatAnimal,WhitDogAnimal....
        // 1。使用处使用out关键字声明--泛型上限
        val animalList : ArrayList<out Animal> = ArrayList<DogAnimal>()
        // 1。定义处处使用out关键字声明--泛型上限
        val animalList2 : ArrayList<Animal> = ArrayList<DogAnimal>()

        // 使用处使用in关键字声明,约定泛型的下限,允许传入的泛型类型是DogAnimal及其父类Animal
        // 1。使用处使用in关键字声明--泛型下限
        val animalList3 : InArrayList<in DogAnimal> = InArrayList<Animal>()
        // 1。定义处处使用in关键字声明--泛型下限
        val animalList4 : InArrayList<DogAnimal> = InArrayList<Animal>()
    }
    class ArrayList<out T>{}

    class InArrayList<in T>{}

8、Kotlin扩展

(1、)扩展方法

Kotlin的扩展函数可以让你作为一个类成员进行调用的函数。这样可以很方便的扩展一个已经存在

的类,为它添加额外的方法。在Kotlin源码中,有大量的扩展函数来扩展Java,这样使得Kotlin比

Java更方便使用,效率更高。

class Jump{
    fun test(){
        println("test")
    }
}
//扩展方法的定义,就是在方法的前面加上类前缀
fun Jump.doubleJump():String{
    return "doubleJump"
}

Java中调用扩展函数

KTExtensionsKt.doubleJump(new Jump( ) );

(2、)泛型扩展方法

//泛型方法定义
fun <T> MutableList<T>.swap(index:Int,index2: Int){
    val temp = this[index]
    this[index] = this[index2]
    this[index2] = temp
}


-----------------

val list = mutableListOf<Int>(1,2,3,4,5)
    list.swap(0,3)
    for (i in list) {
        println("index->${i}")
    }

(3、)扩展属性

扩展属性提供了一种方法能通过属性语法进行访问的API来扩展。尽管它们被叫做属性,但是它们不能拥有任何状态,它不能添加额外的字段到现有的Java对象实例。

//扩展属性
val String.lastChar:Char get() = this.get(length -1)


-----------------


    val android = "android"
    println(android.lastChar)

 (4、)let、run、apply

let扩展函数

let扩展函数的实际上是一个作用域函数,当你需要去定义一个变量在一个特定的作用域范围内,那

么let函数是一个不错的选择;let函数另一个作用就是可以避免写一些判断null的操作。

//let扩展函数,类后面加上?代表参数可能为空,使用的时候注意判空
fun testLet(str:String?){
//    str.let{
//        val str2 = "android"
//        println(str2+it)
//    }
    //判空用法,当str为空,则不会触发闭包里面的逻辑
    str?.let {
        val str2 = "android"
        println(str2+it)
    }
}

run函数

run函数只接收一个lambda函数为参数,以闭包形式返回,返回值为最后一行的值或者指定的

return的表达式,在run函数中可以直接访问实例的公有属性和方法

fun testRun(jump: Jump):String {
    jump.run{
        test()
        println("111111")
        return "222"
    }
}

apply扩展

apply函数的作用是︰调用某对象的apply函数,在函数范围内,可以任意调用该对象的任意方法,

并返回该对象。

从结构上来看apply函数和run函数很像,唯一不同点就是它们各自返回的值不一样,run函数是以闭

包形式返回最后一行代码的值,而apply函数的返回的是传入对象的本身。

apply一般用于一个对象实例初始化的时候,需要对对象中的属性进行赋值。或者动态inflate出一个

XML的View的时候需要给View绑定数据也会用到,这种情景非常常见。

fun testApply(){
    ArrayList<String>().apply {
        add("111")
        add("222")
    }.run{
        for (index in indices) {
            println("apply->${index}")
        }
    }
}

三、案例

package com.example.fristapp.lesson

fun main() {
    while (true){
        println("===================请输入如你的表达式===================")
        var input= readLine()//从键盘输入
        try {
            input?.let {//不为空
                val ret = caculate(it)
                println("${input}=${ret}")
                println("是否继续使用(y/n)")
                val cmd = readLine()
                cmd?.let {
                    if (it.equals("n")){
                        System.exit(-1)
                    }else{

                    }
                }
            }
        }catch (ex:java.lang.Exception){
            ex.printStackTrace()
        }
        //结束
    }
}

fun caculate(input: String): String {
    /*input.trim()//去空格
    input.split("")//切割*/
    if (input.contains("+")){
        val nums = input.trim().split("+")
        return operate(nums[0].toDouble(),nums[1].toDouble(),"+").toString()
    }else if (input.contains("-")){
        val nums = input.trim().split("-")
        return operate(nums[0].toDouble(),nums[1].toDouble(),"-").toString()
    }else if (input.contains("*")){
        val nums = input.trim().split("*")
        return operate(nums[0].toDouble(),nums[1].toDouble(),"*").toString()
    }else if (input.contains("/")){
        val nums = input.trim().split("/")
        return operate(nums[0].toDouble(),nums[1].toDouble(),"/").toString()
    }else{
        return "您输入的程序有误"
    }
}

fun operate(num1: Double, num2: Double,operate:String): Double {
    return when (operate){
        "+" -> num1 + num2
        "-" -> num1 - num2
        "*" -> num1 * num2
        "/" -> num1 /num2
        else -> 0.0
    }
}

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。