kotlin语言

news2025/1/22 15:39:11

简介

Kotlin由JetBrains公司开发。谷歌宣布其成为安卓第一开发语言。

兼容Java,可以和Java混编。

语言类型

  • 编译型

编译器直接将源代码一次性编译成与CPU相配的二进制文件,计算机可直接执行,例如C,C++。

特点:一次编译。不同操作系统(编译的后二进制文件需要调用此OS的api)和CPU(指令集)需要重新编译。

tip:编译后的文件,如果想要在另一个机器上跑,需要相同的操作系统(需要调用此系统的API),还需要相同的CPU(指令集)

  • 解释型

程序运行时,解释器会将源码一行一行实时解析成二进制再执行。例如JS,Python。

特点:安装对应的VM即可运行。效率低。

Java的语言类型:

java准确来说属于混合型语言,但更偏向于解释型。

编译:java存在JIT和AOT,JIT将可将热点代码直接编译成机器码,AOT可在安装时把代码编译成机器码

解释:java运行时需编译成class文件,JVM在解释class文件。

基本

变量、函数

fun main(args: Array<String>){
    val a = 1   // 定义变量。推导为Int(包装类)。
    var b = 2   // 定义常量
    println(myFun(4, 5))
}


fun test() {}	// 无参无返

// 下面等效
fun myFun(a: Int, b: Int): Int {	// 有参有返
    return a + b
}
fun myFun(a: Int, b: Int): Int = a + b
fun myFun(a: Int, b: Int) = a + b	// 推导类型

val:定义只读变量,可以是任何类型

const:常量,值必须在编译时已知,并且只能是基本数据类型或 String

条件

fun getMax(a: Int, b: Int) = if (a > b) a else b	// 此处必须有else,否则无返报错

// Kotlin中==等价于Java的equals比较的时是对象里的内容
fun myIf(name: String): String{
    if (name == "D") return "不及格"
    else return "Others"	// 此处必须有else,否则无返报错
}



fun getScore(name: String) = when (name) {
    "A" -> "best"	
    "B" -> "better"
    else -> "bad"	// 此处必须有else,否则无返报错
}

// when 参数检查
fun checkNumber(num: Number) {
    when(num){
        is Int -> println("Integer")
        is Double -> println("Double")
        else -> println("others")	// 可以省略,因为无返
    }
}

循环

// 输出 0 ≤ ..  ≤ 10
val range = 0..10	// [0, 10]
val range = 0 until 10	// [0, 10)
val range = 0 until 10 step 2	// 同上,步长为2
val range = 10 downTo 0	// [10, 0]

for (i in range) {      
    println(i)
}

// Demo1: 拥有主构造器
// 如果不带open,decompile则为final,不可继承
open class Person(val name: String, val age: Int) {
    init {
        println("name = " + name + ", age = " + age)
    }

}

// 主构造。如果父类有主构造则子类必须调用。无参的主构造也是
class Student(name: String, age: Int, val number: String, val grade: Int) : Person(name, age) {
    // 次构造调用主构造
    constructor(name: String, age: Int, number: String) : this(name,age,number,0)
    constructor() : this("", 0, "", 0)
}

fun main(args: Array<String>){
    // 每次创建类都会调用Person类中的init代码块
    val  s1 = Student("Tom", 18, "123456", 6) // 打印信息。
    val  s2 = Student("Tommy", 19, "123457")
    val  s3 = Student()
    
}


// Demo2: 没有主构造器
open class Person(name: String, age: Int) {
    init {
        println("name = " + name + ", age = " + age)
    }

}
class Student : Person{
    // num不可以在其他地方使用,报错。
    constructor(name: String, age: Int, num: String) : super(name, age) // 调用父类的构造器

}
fun main(args: Array<String>){
    val  s1 = Student("Tom", 18, "123456")
}

接口

interface Study {
    fun read()
    // 和java(default,static除外)不同,可以在接口中直接实现
    fun eat() {
        println("eat...")
    }
}
// 类继承父类和接口
class Student : Person, Study{
    override fun read() {
        println("read...")
    }
}

数据类data

Idea中创建Data类

// 在java中
public class UserBean {
    
    private String id;
    private String name;
    private String pwd;

    // 拥有get/set方法,空构造器和所有属性的构造器
	// 重写equals、hashCode、toString方法
}



// 在kotlin中
// 拥有有get/set方法
class UserBean(var id: String, var name: String, var pwd: String)
// data会自动重写equals、hashCode、toString方法
data class UserBean(var id: String, var name: String, var pwd: String)
    
fun main(args: Array<String>){
    val user = UserBean("123", "Tom", "123456")    
    user.name = "Bob"	// 本质在调用set方法
    println(user.name)	// 本质在调用get方法
} 

单例object

Idea中创建object类

object Singleton {
    fun test() {
        println("test")
    }
}

// 使用
fun main(args: Array<String>){
    Singleton.test()		// 相等于java代码为Singleton.INSTANCE.test();
}

decomplie的java文件

public final class Singleton {
   @NotNull
   public static final Singleton INSTANCE;

   public final void test() {
      String var1 = "test";
      System.out.println(var1);
   }

   private Singleton() {
   }

   static {
      Singleton var0 = new Singleton();
      INSTANCE = var0;
   }
}

集合

// Demo1: List
val list = ArrayList<Int>();
list.add(1);
list.add(2);
val listOf = listOf<Int>(1, 2, 3)    // 不可变
println(listOf.get(1))
val mutableListOf = mutableListOf<Int>(1, 2, 3)  // 可变
mutableListOf.add(4)
println(mutableListOf.get(2))
for (i in mutableListOf) {
    println(i)
}



// Demo2: Set 相似与List



// Demo3: Map
val map = HashMap<String, String>()
map.put("1", "Tom")
map.put("2", "Alice")
map["3"] = "Bob"	// 等效上面。hashmap指向类似下标的操作
map["4"] = "Jerry"

// 等效println(map.get("3"))
println(map["3"])

val mapOf = mapOf<String, String>("1" to "Tom", "2" to "Bob")   // 不可变

val mutableMapOf = mutableMapOf<String, String>("1" to "Tom", "2" to "Bob") // 可变
mutableMapOf.put("3", "alice")

// Hashmap遍历
for (mutableEntry in mutableMapOf) {
    println(mutableEntry.toString())
}
for ((key, value) in mutableMapOf) {
    println(key + " " + value)
}

Lambda

List

val listOf = listOf<String>("a", "bb", "ccc", "dddd")
var maxLengthString = ""		// 常规方法
for (s in listOf) {
    if (s.length > maxLengthString.length) maxLengthString = s;
}
println(maxLengthString)

// 等效
var lambda = {str: String -> str.length}
println(listOf.maxByOrNull(lambda)) // maxByOrNull是一个普通方法,需要一个Lambda参数

// 等效
listOf.maxByOrNull(){str: String -> str.length} // 若Lambda为方法的最后一个参数,则可将{}提到外面
listOf.maxByOrNull {str: String -> str.length}  // 若有且仅有一个参数且是Lambda,则可去掉()
listOf.maxByOrNull {str -> str.length}  // kotlin有推导机制
listOf.maxByOrNull {it.length}  // 若Lambda只有一个参数,则可用it(iterator)替代参数名

// 类型的方法
listOf.filter { it.length > 2 }    // 过滤长度大于2的字符串
listOf.map { it.toUpperCase() }    // 字符全部转为大写
listOf.any {it.length > 3}      // 是否有长度大于3的字符串
listOf.all { it.length > 1 }    // 是否有长度均大于1的字符串

Thread

// object用于实现接口,即声明匿名内部类
Thread(object : Runnable {
    override fun run() {
        println("test")
    }
}).start()

// Runnable是Java单抽象方法接口,可对代码进行简化
Thread( Runnable {
    println("test")
}).start()

//  Runnable接口只用一个方法,使用Lambda
Thread({
    println("test")
}).start()

//  Thread只需一个参数Runnable参数,则可省略()
Thread { println("test") }.start()

只要是只接受一个函数式接口的,都可以这样写。比如button.setOnClickListener { println("test") }

空指针检查机制

在java中处理空指针

public void doStudy(Study study) {
    study.doHomework();
    study.readBooks();
}

// 上述代码时存在空指针风险的,传入null,则程序崩溃
public void doStudy(Study study) {
    if (study != null) {
        study.doHomework();
        study.readBooks();
    }
}

对于kotlin来说

// kotlin会在编译期自动检查
fun study(study: Study) {
    study.doHomework()
    study.readBooks()
}

fun main() {
    study(null) //报错
    study(Student()) //正确
}


// `?`表示可以传入null
fun study(study: Study?) {
    if (study != null) {	// 程序员必须要保证不会空
        study.doHomework()
        study.readBooks()
    }
}

// `?.`表示非空才执行
fun study(study: Study?) {
    study?.doHomework()	// study不空才执行方法
    study?.readBooks()
}
//此时靠?.则保证了study肯定不为空,才会执行let函数
fun study(study: Study?) {
    study?.let {
        //it为study
        it.doHomework()
        it.readBooks()
    }
}


// `?:` 表示a不空才为b
val c = a ?: b

// Demo: 例子
fun getTextLength(text: String?) = text?.length ?: 0
fun getTextLength(text: String?): Int {
    if (text != null) {
        return text.length
    }
    return 0
}


// 强行通过编译,就需要依靠`!!`,这时就是程序员来保证安全
fun study(study: Study?) {
    //假设此时为空抛出异常,则和java一样
    study!!.doHomework()
    study!!.readBooks()
}

// study可以为Study也可为空
var study: Study? = null

内嵌表达式

fun main(args: Array<String>){

    val name = "World"
    println("Hello $name")      // $name等效于${name}
    println("Win ${if (2 > 1) 2 else "1"}")	// ${if...}
    println("fun ${say("World")}")			// // ${fun()}
}

fun say(content: String): String = "say $content"

函数参数默认值

// Demo1: 
fun main(args: Array<String>){
    say(100)
    say(100, "World")
}

fun say(num: Int, str: String = "default") {
    println("num = $num, str = $str")
}

// Demo2: 指定形参传实参
fun main(){
    say(2, "Tom")
    say(str = "Bob")	// 不传具有默认值的
}

fun say(num: Int = 100, str: String) {	// 默认值在前面
    println("num = $num, str = $str")
}

构造器中的默认值

class Student(name: String,  age: Int, val number: String, val grade: Int) : Person(name, age){
    constructor(name: String, age: Int, number: String) : this(name, age, number, 0) {

    }
    ...
}

// 等效于上面
class Student(name: String,  age: Int, val number: String, val grade: Int = 0) : Person(name, age){
	...
}

TODO

TODO() 是一个有效的表达式,且返回类型是 Nothing,表示该代码永远不会正常返回。

public fun TODO(reason: String? = null): Nothing = throw NotImplementedError(reason)

为什么不会报错?

override fun onBind(intent: Intent): IBinder {
    TODO("Return the communication channel to the service.")
}

因为 Nothing 是所有类型的子类型,可以暂时替所有类的返回值。编译正确,运行抛出相应异常。

block

作为高阶参数

// 高阶函数参数,允许将代码块(函数或 lambda 表达式)作为参数供函数使用,实现更灵活的代码逻辑和复用。
inline fun <T> myFun(condition : Boolean, block: () -> T): T? {
    return if (condition) block() else null
}


fun main() {
    val myFun = myFun(true) {
        println("hello world")
        "abc"
    }
    println(myFun)
}

T.() 的形式就是定义扩展函数的方式。

// kotlin的Unit( = Java中的void)
// 定义一个扩展函数类型 T.() -> Unit
fun <T> myFun(obj: T, block: T.() -> Unit) {
    // 在 T 对象上调用扩展函数
    obj.block()
}

// 为 String 类型定义一个扩展函数
fun String.printToupper() {
    println(this.uppercase())
}

fun main() {
    val str = "hello"
    myFun(str){
        printToupper()	// 调用扩展函数
    }

}

//Demo2 : apply 函数本质上就是一个 T.() -> Unit 类型的函数
val mutableList = mutableListOf<Int>(1, 2, 3).apply {
    add(4)
    add(5)
}

apply源码

@kotlin.internal.InlineOnly
public inline fun <T> T.apply(block: T.() -> Unit): T {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    // 等效this.block(),this就是调用apply的对象
    block()		
    return this
}

委托模式

fun main(){
    val consolePrint = ConsolePrinter()
    val document = Document(consolePrint)

    document.printer("hello")   // ConsolePrint : hello
    document.say("hello")       // say : hello
}

interface Printer{
    fun printer(content : String)
    fun say(content : String)
}

class ConsolePrinter : Printer{
    override fun printer(content : String) {
        println("ConsolePrint : $content")
    }

    override fun say(content: String) {
        println("say : $content")
    }
}

// Document类通过by printer委托了Printer接口的所有方法给了printer对象
class Document(printer : Printer) : Printer by printer {}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2280439.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

wireshark工具简介

目录 1 wireshark介绍 2 wireshark抓包流程 2.1 选择网卡 2.2 停止抓包 2.3 保存数据 3 wireshark过滤器设置 3.1 显示过滤器的设置 3.2 抓包过滤器 4 wireshark的封包列表与封包详情 4.1 封包列表 4.2 封包详情 参考文献 1 wireshark介绍 wireshark是非常流行的网络…

「2024·我的成长之路」:年终反思与展望

文章目录 1. 前言2.创作历程2.1 摆烂期2.2 转变期3. 上升期 2. 个人收获3.经验分享4. 展望未来 1. 前言 2025年1月16日&#xff0c;2024年博客之星入围公布&#xff0c;很荣幸获得了这次入围的机会。2024年对我个人是里程碑的一年&#xff0c;是意义非凡的一年&#xff0c;是充…

【RAG落地利器】向量数据库Chroma入门教程

安装部署 官方有pip安装的方式&#xff0c;为了落地使用&#xff0c;我们还是采用Docker部署的方式&#xff0c;参考链接来自官方部署: https://cookbook.chromadb.dev/running/running-chroma/#docker-compose-cloned-repo 我们在命令终端运行&#xff1a; docker run -d --…

电阻电位器可调电阻信号隔离变送器典型应用

电阻电位器可调电阻信号隔离变送器典型应用 产品描述&#xff1a; 深圳鑫永硕科技的XYS-5587系列是一进一出线性电子尺(电阻/电位计信号及位移)信号隔离变送器&#xff0c;是将输入电阻,线性电子尺,角度位移传感器信号进行采集,隔离,放大并转换成模拟量信号的小型仪表设备,并以…

[创业之路-259]:《向流程设计要效率》-1-让成功成熟业务交给流程进行复制, 把创新产品新业务新客户交给精英和牛人进行探索与创造

标题&#xff1a;成功与创新的双轨并行&#xff1a;以流程复制成熟&#xff0c;以精英驱动新知 在当今这个日新月异的商业环境中&#xff0c;企业要想持续繁荣发展&#xff0c;就必须在稳定与创新之间找到完美的平衡点。一方面&#xff0c;成熟业务的稳定运营是企业生存和发展的…

模拟飞行入坑(五) P3D 多通道视角配置 viewgroup

背景&#xff1a; P3D进行多个屏幕显示的时候&#xff0c;如果使用英伟达自带的屏幕融合成一个屏&#xff0c;或者使用P3D单独拉伸窗口&#xff0c;会使得P3D的画面被整体拉伸&#xff0c;又或者,当使用Multichannel进行多个设备联动时&#xff0c;视角同步组合需要配置&#…

Java中的错误与异常详解

Java中的错误与异常详解 Java提供了一种机制来捕获和处理程序中的异常和错误。异常和错误都继承自 Throwable 类&#xff0c;但它们有着不同的用途和处理方式。 1. Error&#xff08;错误&#xff09; Error 是程序无法处理的严重问题&#xff0c;通常由 JVM&#xff08;Java…

免费开源的三维建模软件Blender

软件介绍 Blender是一款功能强大且免费开源的三维建模、动画制作和渲染软件&#xff0c;广泛应用于影视制作、游戏开发、建筑可视化、教育及艺术创作等多个领域。 核心功能 Blender是一款全能型3D软件&#xff0c;涵盖了从建模、动画到渲染、后期合成的完整工作流程。 1、建…

ElasticSearch DSL查询之排序和分页

一、排序功能 1. 默认排序 在 Elasticsearch 中&#xff0c;默认情况下&#xff0c;查询结果是根据 相关度 评分&#xff08;score&#xff09;进行排序的。我们之前已经了解过&#xff0c;相关度评分是通过 Elasticsearch 根据查询条件与文档内容的匹配程度自动计算得出的。…

iOS 网络请求: Alamofire 结合 ObjectMapper 实现自动解析

引言 在 iOS 开发中&#xff0c;网络请求是常见且致其重要的功能之一。从获取资料到上传数据&#xff0c;出色的网络请求框架能夠大大提升开发效率。 Alamofire 是一个极具人气的 Swift 网络请求框架&#xff0c;提供了便据的 API 以完成网络请求和响应处理。它支持多种请求类…

面向对象编程——对象实例化

在python中&#xff0c;对象实例化是根据类的定义创建具体对象的过程。也就是将类当成模板&#xff0c;从而定义了对象的结构和行为&#xff0c;而实例化则是根据这个模板创建具体的对象实例。每个实例都有自己独立的状态&#xff0c;但是却共享类的结构和方法。 代码&#xff…

阿里云-银行核心系统转型之业务建模与技术建模

业务领域建模包括业务建模和技术建模&#xff0c;整体建模流程图如下&#xff1a; 业务建模包括业务流程建模和业务对象建模 业务流程建模&#xff1a;通过对业务流程现状分析&#xff0c;结合目标核心系统建设能力要求&#xff0c;参考行业建 模成果&#xff0c;形成结构化的…

Unreal Engine 5 C++ Advanced Action RPG 九章笔记

第九章 Hero Special Abilities 2-Challenges Ahead(前方的挑战) 本次章节主要解决三件问题 怒气能力特殊武器能力治疗石怒气能力 对于这个能力我们需要处理它的激活和持械状态,当没有怒气时应该取消该能力当这个能力激活时,我希望角色是进入无敌状态的,不会受到伤害怒气状…

cursor重构谷粒商城05——docker容器化技术快速入门【番外篇】

前言&#xff1a;这个系列将使用最前沿的cursor作为辅助编程工具&#xff0c;来快速开发一些基础的编程项目。目的是为了在真实项目中&#xff0c;帮助初级程序员快速进阶&#xff0c;以最快的速度&#xff0c;效率&#xff0c;快速进阶到中高阶程序员。 本项目将基于谷粒商城…

【FPGA】MIPS 12条整数指令【1】

目录 修改后的仿真结果 修改后的完整代码 实现bgtz、bltz、jalr 仿真结果&#xff08;有问题&#xff09; bltz------并未跳转&#xff0c;jCe&#xff1f; 原因是该条跳转语句判断的寄存器r7&#xff0c;在该时刻并未被赋值 代码&#xff08;InstMem修改前&#xff09; i…

洛谷题目:P2742 [USACO5.1] 圈奶牛Fencing the Cows /【模板】二维凸包 题解 (本题较难)

题目传送门&#xff1a;P2742 [USACO5.1] 圈奶牛Fencing the Cows /【模板】二维凸包 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 另&#xff1a;由于一些文章的疏忽&#xff0c;导致一些错别字&#xff0c;代码错误&#xff0c;公式错误导致大家的理解和误导&#xff0c;…

多线程之旅:线程安全问题

之前说到了多线程的创建和一些属性等等&#xff0c;接下来&#xff0c;就来讲讲多线程安全问题。 小编引入这段代码讲解下&#xff1a; public class Demo13 {public static int count0;public static void main(String[] args) throws InterruptedException {Thread t1new…

html学习笔记(3)

一、文本格式标签 效果标签&#xff08;旧版&#xff09;标签&#xff08;语义化&#xff0c;强调&#xff09;加粗<b><strong>倾斜<i><em>下划线<u><ins>删除线<s><del> 前面的标签 b 、 i 、 u 、 s 就仅仅是实现加粗、倾…

Postgresql源码(141)JIT系列分析汇总

JIT的东西比较零散&#xff0c;本篇对之前的一些列分析做个汇总、整理。 涉及&#xff1a; 《Postgresql源码&#xff08;113&#xff09;表达式JIT计算简单分析》 《Postgresql源码&#xff08;127&#xff09;投影ExecProject的表达式执行分析》 《Postgresql源码&#xff08…

Maven多环境打包方法配置

简单记录一下SpringBoot多环境打包配置方法&#xff0c;分部署环境和是否包含lib依赖包两个维度 目录 一、需求说明二、目录结构三、配置方案四、验证示例 一、需求说明 基于Spring Boot框架的项目分开发&#xff0c;测试&#xff0c;生产等编译部署环境&#xff08;每一个环境…