kotlin 基础概览

继承类/实现接口

继承类和实现接口都是用的 : ,如果类中没有构造器 ( constructor ),需要在父类类名后面加上 ()

class MainActivity : BaseActivity(), View.OnClickListener

空安全设计

Kotlin 中的类型分为「可空类型」和「不可空类型」:
  • 不可空类型  val editText : EditText
  • 可空类型  val editText : EditText?

lateinit 关键字

  • lateinit 只能修饰 var 可读可写变量 
  • lateinit  关键字声明的变量的类型必须是「不可空类型」
  • lateinit  声明的变量不能有「初始值」
  • lateinit  声明的变量不能是「基本数据类型」
  • 在构造器中初始化的属性不需要 lateinit 关键字

平台类型

在类型后面加上一个感叹号的类型是「平台类型」 Java 中可以通过注解减少这种平台类型的产生
  • @Nullable 表示可空类型
  • @NotNull @NonNull 表示不可空类型

类型判断

  • is 判断属于某类型
  • !is 判断不属于某类型
  • as 类型强转,失败时抛出类型强转失败异常
  • as? 类型强转,但失败时不会抛出异常而是返回 null

获取 Class 对象

  • 使用 类名 ::class 获取的是 Kotlin 的类型是 KClass
  • 使用 类名 ::class.java 获取的是 Java 的类型

setter/getter

  • Kotlin 声明属性的时候 ( 没有使用 private 修饰 ) ,会自动生成一个私有属性和 一对公开的 setter/getter 函数。
  • 在写 setter/getter 的时候使用 field 来代替内部的私有属性(防止递归栈溢 出)。

构造器

  • 使用 constructor 关键字声明构造器
class User {constructor()
}

如果我们在构造器主动调用了父类构造,那么在继承类的时候就不能在类的后面加上小括号

constructor(context: Context) : this(context, null)
// 主动调用了父类的构造器
constructor(context: Context, attr: AttributeSet?) : super(context, attr)
class CodeView : TextView {constructor(context: Context): super(context)
}

等价:

class CodeView(context: Context) : TextView(context) {
}

@JvmField 生成属性

  • 通过 @JvmField 注解可以让编译器只生成一个 public 的成员属性,不生成对 应的 setter/getter 函数

Any 和 Unit

  • Any : Kotlin 的顶层父类是 Any ,对应 Java 当中的 Object ,但是比 Object 少了 wait()/notify() 等函数
  • Unit : Kotlin 中的 Unit 对应 Java 中的 void

数组

  • 使用 arrayof() 来创建数组,基本数据类型使用对应的 intArrayOf()

静态函数和属性

  • 顶层函数
  • object
  • companion object

其中,「顶层函数」直接在文件中定义函数和属性,会直接生成静态的,在 Java 通过「文件名Kt」来 访问,同时可以通过 @file:JvmName 注解来修改这个「类名」。

需要注意,这种顶层函数不要声明在 module 内最顶层的包中,至少要在一个包中例如 com 。不然不能方便使用。

object companion object 都是生成单例对象,然后通过单例对象访问函数和属性的。

@JvmStatic

通过这个注解将 object companion object 的内部函数和属性,真正生成静态的。

单例模式/匿名内部类

  • 通过 object 关键字实现
// 单例
object Singleton {}
// 匿名内部类
object : OnClickListener {}

字符串模版

  • 通过 ${} 的形式来作为字符串模版
val number = 100
val text = "向你转账${number}元。"
// 如果只是单一的变量,可以省略掉 {}
val text2 = "向你转账$number元。"

多行字符串

val s = """我是第一行我是第⼆行我是第三行""".trimIndent()

区间

  • 200..299 表示 [200, 299]  的区间 ( 包括 299 )

when 关键字

  • Java 当中的 switch 的高级版,分支条件上可以支持表达式

声明接口/抽象类/枚举/注解

// 声明抽象类
abstract class
// 声明接口
interface
// 声明注解
annotation class
// 声明枚举
enum class

编译期常量

  • 在静态变量上加上 const 关键字变成编译期常量

标签

  • Java 中通过 「 类名 .this 例如 Outer.this 」 获取目标类引用
  • Kotlin 中通过「 this@ 类名 例如 this@Outer

遍历

记得让 IDE 来帮助生成 for 循环

for(item in items)

内部类

  • Kotlin 当中,内部类默认是静态内部类
  • 通过 inner 关键字声明为嵌套内部类

可见性修饰符

  • 默认的可见性修饰符是 public
  • 新增的可见性修饰符 internal 表示当前模块可见

注释

  • 注释中可以在任意地方使用 [] 来引用目标,代替 Java 中的 @param @link 等。

非空断言

  • 可空类型强制类型转换成不可空类型可以通过在变量后面加上 !! ,来达到类型转换。

open/final

  • Kotlin 中的类和函数,默认是被 final  修饰的 ( abstract override 例外 ) 除非加上  open  关键字才可以被子类覆写(默认方法都是 closed 关闭的,不能被重写的)

次级构造

class CodeView : TextView {constructor(context: Context): super(context)
}

主构造器

class CodeView constructor(context: Context) : TextView(context) // 如果没有被「可见性修饰符」「注解」标注,那么 `constructor` 可以省略
class CodeView(context: Context) : TextView(context)

成员变量初始化可以直接访问到主构造参数

class CodeView constructor(context: Context) : TextView(context) {val color = context.getColor(R.color.white)
}

init 代码块

主构造不能包含任何的代码,初始化代码可以放到 init 代码块中

class CodeView constructor(context: Context) : TextView(context) {init {//...}
}

在初始化的时候,初始化块会按照它们在「文件中出现的顺序」执行。

class CodeView constructor(context: Context) : TextView(context) {init {//...}val paint = Paint() // 会在 init{} 之后运行
}

构造属性

在主构造参数前面加上 var/val 使构造参数同时成为成员变量

class User constructor(var username: String?, var password: String?, var code: String?)

data class

数据类同时会生成
  • toString()
  • hashCode()
  • equals()
  • copy() (浅拷贝)
  • componentN() ...

相等比较

  • == 结构相等 ( 调用 equals() 比较 )
  • === 引用 相等 (比较 地址值 )

解构

可以把一个对象「解构」成很多变量

val (code, message, body) = response

对应的 Java 代码

val code = response.component1()
val message = response.component2()
val body = response.component3()

Elvis 操作符

  • 可以通过 ?: 的操作来简化 if null 的操作
// lesson.date 为空时使用默认值
val date = lesson.date ?:  "日期待定"// lesson.state 为空时提前返回函数
val state = lesson.state ?:  return// lesson.content 为空时抛出异常
val content = lesson.content ?: throw IllegalArgumentException("content expected")

when 操作符

  • when 表达式可以接受返回值,多个分支相同的处理方式可以放在一起,用逗号分
val colorRes = when (lesson.state) {Lesson.State.PLAYBACK, null -> R.color.playbackLesson.State.LIVE -> R.color.liveLesson.State.WAIT -> R.color.wait
}
  • when 表达式可以用来取代 if-else-if 链。如果不提供参数,所有的分支条件都是布尔表达式
val colorRes = when {(lesson.state == Lesson.State.PLAYBACK) -> R.color.playback(lesson.state == null) -> R.color.playback(lesson.state == Lesson.State.LIVE) -> R.color.live(lesson.state == Lesson.State.WAIT) -> R.color.waitelse -> R.color.playback
}

operator

  • 通过 operator 修饰「特定函数名」的函数,例如 plus get 可以达到重载运算符的效果

lambda

如果函数的最后一个参数是 lambda ,那么 lambda 表达式可以放在圆括号之外:

lessons.forEach() { lesson : Lesson ->// ...
}

如果你的函数传入参数只有一个 lambda 的话,那么小括号也可以省略的:

lessons.forEach { lesson : Lesson ->// ...
}

如果 lambda 表达式只有一个参数,那么可以省略,通过隐式的 it 来访问:

lessons.forEach { // it// ...
}

循环

通过标准函数 repeat()

repeat(100) {//..
}

通过区间:

for (i in 0..99) {}// until 不包括右边界
for (i in 0 until 100) {}

infix 函数

  • 必须是 成员函数 扩展函数
  • 必须 只能接受一个参数,并且不能有默认值
// until() 函数的源码
public infix fun Int.until(to: Int): IntRange {if (to <= Int.MIN_VALUE) return IntRange.EMPTYreturn this .. (to - 1).toInt()
}

潜逃函数

Kotlin 中可以在函数中继续声明函数

fun func(){fun innerFunc(){}
}
  • 内部函数可以访问外部函数的参数
  • 每次调用时,会产生一个函数对象

注解使用处目标

当某个元素可能会包含多种内容 ( 例如构造属性,成员属性 ) ,使用注解时可以通过 「注解使用处目标」,让注解对目标发生作用,例如 @file: @get: @set: 等。

函数简化

可以通过符号 = 简化原本直接 return 的函数

fun get(key :String) = SP.getString(key,null)

函数参数默认值

可以通过函数参数默认值来代替 Java 的函数重载

// 使用 @JvmOverloads 对 Java 暴露重载函数
@JvmOverloads
fun toast(text: CharSequence, duration: Int = Toast.LENGTH_SHORT) {Toast.makeText(this, text, duration).show()
}

扩展函数

  • 扩展函数可以为任何类添加上一个函数,从而代替工具类
  • 扩展函数和成员函数相同时,成员函数优先被调用
  • 扩展函数是静态解析的,在编译时就确定了调用函数 ( 没有多态 )

函数类型

  • 函数类型由「传入参数类型」和「返回值类型」组成,用「 -> 」连接,
  • 传入参数需要用「 () 」,如果返回值为 Unit 不能省略 
  • 函数类型实际是一个接口,如果需要将函数作为参数传递时可以通过 ::函数名 或者「匿名函数」或者使用 「 lambda

内联函数

  • 内联函数配合「函数类型」,可以减少「函数类型」生成的对象
  • 使用 inline 关键字声明的函数是「内联函数」,在「编译时」会将「内联函数」中的函数体直接插入到调用处。
  • 所以在写内联函数的时候需要注意,尽量将内联函数中的代码行数减少!

部分禁用内联

  • noinline 可以禁止部分参数参与内联编译
inline fun foo(inlined: () -> Unit, noinline notInlined:() -> Unit) {//......
}

具体化的类型参数

  • 因为内联函数的存在,我们可以通过配合 inline + reified 达到「真泛型」的效果
val RETROFIT = Retrofit.Builder().baseUrl("https://api.github.com/").build()inline fun <reified T> create(): T {return RETROFIT.create(T::class.java)
}val api = create<API>()

抽象属性

Kotlin 中,我们可以声明抽象属性,子类对抽象属性重写的时候需要重写对应的  setter/getter

属性委托

有些常见的属性操作,我们可以通过委托的方式,让它只实现一次,例如:
  • lazy 延迟属性:值只在第一次访问的时候计算
  • observable 可观察属性:属性发生改变时的通知
  • map 集合:将属性存在一个 map

对于一个只读属性( val 声明的),委托对象必须提供一个名为 getValue() 函数

对于一个可变属性( var 声明的),委托对象同时提供 setValue() getValue() 函数

类委托

可以通过类委托的模式来减少继承类委托的,编译器会优先使用自身重写的函数,而不是委托对象的函数
interface Base {fun print()
}
class BaseImpl(val x: Int) : Base {override fun print() {print(x)}
}// Derived 的 print 实现会通过构造参数中的 b 对象来完成。
class Derived(b: Base) : Base by b

Kotlin 标准函数apply、also、run、let

使用时可以通过简单的规则作出一些判断:

需要返回自身 -> apply also 中选
  • 作用域中使用 this 作为参数 ----> 选择 apply
  • 作用域中使用 it 作为参数 ----> 选择 also
不需要返回自身 -> run let 中选择
  • 作用域中使用 this 作为参数 ----> 选择 run
  • 作用域中使用 it 作为参数 ----> 选择 let

apply 适合对一个对象做附加操作的时候

let 适合配合判空的时候 (最好是成员变量,而不是局部变量,局部变量更适合 if )

with 适合对同一个对象进行多次操作的时候

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于ssm企业人事管理系统的设计与实现论文

摘 要 进入信息时代以来&#xff0c;很多数据都需要配套软件协助处理&#xff0c;这样可以解决传统方式带来的管理困扰。比如耗时长&#xff0c;成本高&#xff0c;维护数据困难&#xff0c;数据易丢失等缺点。本次使用数据库工具MySQL和编程技术SSM开发的企业人事管理系统&am…

Tekton 基于 gitlab 触发流水线

Tekton 基于 gitlab 触发流水线 Tekton EventListener 在8080端口监听事件&#xff0c;Gitlab 提交代码产生push 事件&#xff0c;gitlab webhook触发tekton流水线执行。 前置要求&#xff1a; kubernetes集群中已部署 tekton pipeline、tekton triggers以及tekton dashboa…

GO并发编程综合应用

一.GO并发编程综合应用 1.生产者消费者模式 1.1需求分析 ​ 生产者每秒生产一个商品&#xff0c;并通过物流公司取货 ​ 物流公司将商品运输到商铺 ​ 消费者阻塞等待商铺到货&#xff0c;需要消费10次商品 1.2实现原理 1.3代码实现&#xff1a; package mainimport (&q…

Unity Mono加密解决方案

Unity Mono 是 Unity 引擎默认的脚本运行时环境&#xff0c;在游戏开发中扮演着重要的角色。Mono 由跨平台的开源 .NET 框架实现&#xff0c;它允许开发者使用 C# 等编程语言编写游戏逻辑。凭借简单易用的开发环境和高效的脚本编译速度&#xff0c;得到了众多游戏的青睐。 在 …

基于亚马逊云科技新功能:Amazon SageMaker Canvas无代码机器学习—以构建货物的交付状态检测模型实战为例深度剖析以突显其特性

授权说明&#xff1a;本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在亚马逊云科技开发者社区、 知乎、自媒体平台、第三方开发者媒体等亚马逊云科技官方渠道。 目录 &#x1f680;一. Amazon SageMaker &#x1f50e;1.1 新功能发布&#xff1a;A…

【通俗易懂】基于fabric8io操作k8s集群实战(pod、deployment、service、volume)

目录 前言一、基于fabric8io操作pod1.1 yaml创建pod1.2 fabric8io创建pod案例 二、基于fabric8io创建Service&#xff08;含Deployment&#xff09;2.1 yaml创建Service和Deployment2.2 fabric8io创建service案例 三、基于fabric8io操作Volume3.1 yaml配置挂载存储卷3.2 基于fa…

国际语音群呼系统有哪些应用场景?

国际语音群呼可应用于广告营销、消息通知、客情维护、金融催收等场景&#xff0c;助力出海企业产品营销和品牌推广。 广告营销 出海企业可以通过国际语音群呼系统&#xff0c;向目标市场的潜在客户进行广告宣传。例如&#xff0c;企业可以在系统中录制有关产品的宣传语&#…

分布式块存储 ZBS 的自主研发之旅|元数据管理

重点内容 元数据管理十分重要&#xff0c;犹如整个存储系统的“大黄页”&#xff0c;如果元数据操作出现性能瓶颈&#xff0c;将严重影响存储系统的整体性能。如何提升元数据处理速度与高可用是元数据管理的挑战之一。SmartX 分布式存储 ZBS 采用 Log Replication 的机制&…

InsCode实践分享

官方文档 官方文档永远是除了源码之外的最准确的资料&#xff0c;可以先看一遍&#xff0c;10分钟可以看完入门部分 InsCode 简介 | InsCode 文档 是什么 InsCode是一个在线的编程工具&#xff0c;提供了创建、调试、共享、部署项目的功能。可以说&#xff1a; InsCodeVSC…

Gitlab基础篇: Gitlab docker 安装部署、Gitlab 设置账号密码

文章目录 1、环境准备2、配置1)、初始化2)、修改gitlab配置文件3)、修改docker配置的gitlab默认端口 gitlab进阶配置gitlab 设置账号密码 1、环境准备 安装docker gitlab前确保docker环境&#xff0c;如果没有搭建docker请查阅“Linux docker 安装文档” docker 下载 gitlab容…

LabVIEW在高铁温度与振动监测中的应用

​LabVIEW在高铁温度与振动监测中的应用 高速铁路的可靠性和安全性是现代铁路运输系统设计和运营的重中之重。LabVIEW软件作为一个多功能、可扩展的图形编程环境&#xff0c;提供了一个理想的平台&#xff0c;用于开发高铁监测系统&#xff0c;不仅监测实时数据&#xff0c;也…

vue 中国省市区级联数据 三级联动

vue 中国省市区级联数据 三级联动 安装插件 npm install element-china-area-data5.0.2 -S 当前版本以测试&#xff0c;可用。组件中使用了 element-ui, https://element.eleme.cn/#/zh-CN/component/installation 库 请注意安装。插件文档 https://www.npmjs.com/package/ele…

Hudi 在 vivo 湖仓一体的落地实践

作者&#xff1a;vivo 互联网大数据团队 - Xu Yu 在增效降本的大背景下&#xff0c;vivo大数据基础团队引入Hudi组件为公司业务部门湖仓加速的场景进行赋能。主要应用在流批同源、实时链路优化及宽表拼接等业务场景。 一、Hudi 基础能力及相关概念介绍 1.1 流批同源能力 与H…

Yum仓库架构解析与搭建实践

1.Yum仓库搭建 1.1本地Yum仓库图解 1.2Linux本地仓库搭建 配置本地光盘镜像仓库 1&#xff09;挂载 [roothadoop101 ~]# mount -t iso996 /dev/cdrom/mnt 2&#xff09;查看 [rooothadoop101 ~] # df -h | |grep -i mnt /dev/sr0 4.6G 4.4G 3&#xf…

python学习1

大家好&#xff0c;这里是七七&#xff0c;今天开始又新开一个专栏&#xff0c;Python学习。这次思考了些许&#xff0c;准备用例子来学习&#xff0c;而不是只通过一大堆道理和书本来学习了。啊对&#xff0c;这次是从0开始学习&#xff0c;因此大佬不用看本文了&#xff0c;小…

103基于matlab的极限学习机(ELM)和改进的YELM和集成极限学习机(EELM)是现在流行的超强学习机

基于matlab的极限学习机&#xff08;ELM&#xff09;和改进的YELM和集成极限学习机(EELM)是现在流行的超强学习机&#xff0c;该程序是三者的方法比对。 包括学习时间&#xff0c;训练精度和测试精度的对比。数据可更换自己 的&#xff0c;程序已调通&#xff0c;可直接运行…

Nginx+Tomcat实现负载均衡和动静分离

目录 前瞻 动静分离和负载均衡原理 实现方法 实验&#xff08;七层代理&#xff09; 部署Nginx负载均衡服务器(192.168.75.50:80) 部署第一台Tomcat应用服务器&#xff08;192.168.75.60:8080&#xff09; 多实例部署第二台Tomcat应用服务器&#xff08;192.168.75.70:80…

Django和ECharts异步请求示例

前提条件 创建django项目&#xff0c;安装配置过程这里就不讲述了。 后端url http://127.0.0.1:8000/echarts/demo/ view视图函数 from django.http import HttpResponse import jsondef EchartsDemo(request):data {}categories ["衬衫","羊毛衫",&…

初识数据结构

文章目录 一、什么是数据结构&#xff1f;二、什么是算法&#xff1f;三、数据结构和算法的重要性在校园招聘的笔试中在校园招聘的面试中某学长CVTE面试&#xff1a;某学长腾讯的面试&#xff1a;某学姐百度的面试&#xff1a; 在未来的工作中 四、如何学好数据结构和算法1.死磕…

亚马逊云科技 re:Invent 大会 - ElastiCache Serverless模式来袭

亚马逊云科技 re:Invent 大会 - ElastiCache Serverless模式来袭 本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在 亚马逊云科技开发者社区, 知乎&#xff0c;自媒体平台&#xff0c;第三方开发者媒体等亚马逊云科技官方渠道。 文章目录 亚马逊云…