val、var
作用:定义变量、常量
var a = 5
var b : Int
val c = 5;
1.没有初始化,必须声明类型
2.可初始化推断类型
init
作用: 初始化,没啥特别意义
init {
}
?
作用: 代表可空
var c : String?
1.可空变量,必须定义其类型
lateinit
作用:延迟加载1(延迟初始化)
lateinit var lazy : String
1.不能用于基本数据类型
2.不能为可空变量
3.使用时必须完成初始化,否则会崩溃UninitializedPropertyAccessException
4.必须使用var可读可写定义
lazy{}
作用:延迟加载2(第一次使用时初始化)
private val lazyTo : String by lazy{
"延迟初始化"
}
1.只能用于val常量
2.在该函数在变量的数据类型后面,用by链接
const
作用:定义常量1
const val num : String = "常量"
1.只能用于val常量,定义于类之外
2.相当于Java的public static final String num = "常量";
object
作用:定义常量1(对象表达式)
object Test{
const val num2 : String = "常量"
}
1.较为复杂,后续补充
companion object
作用:伴生对象
companion object {
const val NUM_A = 6
}
1.相当于Java中的静态类定义静态变量
2.伴生对象可自定义名称
3.通过类名.参数名称调用 , 如Test.NUM_A
==
作用:判断数值是否一致
a == b
1.与Java无异
===
作用:判断内存地址是否相等
var a = 129
var b : Int? = null
b = a
Log.d("22" , (b === a).toString())
1.以int为例,int的缓存大小在-128 - 127之间,两个数在此范围,比较结果为true,超过此范围,比较结果为false
if else
作用:条件判断
var a = 0
var num = if (a > 0) 1 else 2
in
作用:1. 循环迭代
2.判断值是否存在数组或者集合中
for (s in array) {
}
var b1 : Boolean = index in array
until
作用:步长,循环到步长的索引前为止
for (i in 1 until 5){
print(i)
}
相当于Java
for (int i = 1; i < 5; i++) {
print(1);
}
downTo
作用:循环递减
for (i in 15 downTo 10){
print(i)
}
相当于Java
for (int i = 15; i >= 10 ; i--) {
print(i);
}
..
作用:循环递增
for (i in 10 .. 15){
print(i)
}
1.与until相似,但..的范围为 10 <= i <= 15 , 范围取值不同
step
作用:配合until使用设置步长长度间隔
for (i in 3 until 10 step 2){
print(i)
}
1.输出时间隔数为2
indices
作用:数组遍历1
for (s in array.indices) {
println("$s" + array[s])
}
相当于Java
for (int i = 0; i < array.size(); i++) {
print(i + array[i]);
}
withIndex
作用:数组遍历2
for ((key , value) in array.withIndex()) {
println("index >> $key$value")
}
iterator
作用:数组迭代
var iterator = array.iterator()
while (iterator.hasNext()){
if(iterator.next() > 0){
iterator.remove()
}
}
when
作用:相当于Java的switch
when (a) {
1 -> {
print(1)
}
2, 3, 4 -> {
print(2)
}
else -> {
print("else")
}
}
Java示例
switch (a){
case 1:
println("1");
break;
case 2:
case 3:
case 4:
println("2");
break;
default:
println("else");
break;
}
?.
作用:判断当参数为空时,整个表达式都为空
var toast :String ? = null
println("${toast?.length?.plus(1)?.minus(2)}")
1.添加此操作符可以避免空指针
2.方法中的代码使用?.
去返回一个值,那么方法的返回值的类型后面也要加上?
符号
let
作用:配合?.使用,为空时跳过
for ( index in array) {
index?.let { print(index) }
}
1.当index为空时,跳过这个参数
2.相当于Java
for (index in arrTest) {
if (index == null){
continue
}
println("index => $index")
}
?:
作用:添加默认值,当对象为空时,使用默认值
a = b ?: 10
1.当b为空时,等价于a = 10
2.相当于
a = if(b != null) b else 10
!!.
作用:使用该操作符,数据为空时抛出异常
val a1 : Int? = null
println(a1!!.toString())
// Caused by: kotlin.KotlinNullPointerException
1.应该还是要提醒开发者对象为空
as?
作用:强制转换,不能强转的对象强转之后为空,比如说String转int
var a2 : Int = "Kotlin Studio" as Int
print(a2)
Unit
作用:方法无返回值
fun add() : Unit{
print("无返回值")
}
1.相当于Java的void
2.可以忽略不写(默认无返回值,方法默认public)
默认参数
作用:当方法的参数添加了默认值之后,可以不用传值
fun add(arg1 : Int = 2 , arg2 : String = "1" , arg3 :Boolean = true) : Unit{
print("无返回值")
}
调用
add()
add(1)
add(2 , "2")
add(3 , "3" , false)
vararg
作用:动态参数,参数个数不固定
open fun varargFun(arg0 : Int , vararg str : Int){
for (s in str) {
}
}
相当于Java的
private void varargFun(int arg0 , String... arg2) {
for (String s : arg2) {
}
}
first() | firstOrNull()
作用:字符串截取,截取第一个元素
var arg0 = "str".first()
print("s")
1.当arg0 == null 时 , 会抛出NoSuchElementException异常
2.使用firstOrNull()更加安全
last() | lastOrNull()
作用:字符串截取,截取最后一个元素
var arg0 = "str".last()
print("r")
1.当arg0 == null 时 , 会抛出NoSuchElementException异常
2.使用lastOrNull()更加安全
first{} | firstOrNull{}
作用:查找等于某一字符第一次出现的元素,并返回该元素
var arg0 = "str"
var frist= arg0.frist{ it == 's' }
Log.d("frist>>>>" , "$frist")
1.为保证安全,尽量使用firstOrNull , 当无该字符时,firstOrNull将返回null
last{} | lastOrNull{}
作用:查找等于某一字符最后一次出现的元素,并返回该元素
var arg0 = "str"
var last= arg0.last{ it == 's' }
Log.d("last>>>>" , "$last")
1.为保证安全,尽量使用lastOrNull, 当无该字符时,lastOrNull将返回null
indexOf() | indexOfFirst{}
作用:查找某一个元素或字符串在原字符串中第一次出现的下标
var arg0 = "str"
var index = arg0.indexOf("r")
Log.d("index>>>>" , "$index")
indexLastOf() | indexLastOfFirst{}
作用:查找某一个元素或字符串在原字符串中第一次出现的下标
var arg0 = "strstr"
var index = arg0.indexLastOf("r")
Log.d("index>>>>" , "$index")
constructor
作用:定义一个类的构造函数
class Constructor constructor(name : String , age : Int){
...
}
1.在构造函数不具有注释符或者默认的可见性修饰符时,constructor关键字可以省略
2.默认的可见性修饰符时(public)可以省略
3.多构造函数的情况下
class Constructor(var name: String, var age: Int) {
init {
print("$name >> $age")
}
constructor(name: String, age: Int, studio: String) : this(name, age){
...
}
}
init{}
作用:构造函数中的初始化代码块
class Constructor(var name : String , var age : Int){
init {
name = "100"
age = 10
print("$name >> $age")
}
}
1.init函数中能使用构造函数中的参数
open
作用:使用了open的类、参数、方法,子类继承后也可以使用
open class Constance {
open var arg1 : String = "1"
open fun argFun(){
...
}
}
class Test : Constance(){
}
//使用
var constance = Test()
var a = constance.arg1
sumBy
作用:统计字符的16进制值之和
var text = "123"
var sumBy = text.sumBy {
it.toInt()
}
Log.d("sumBy", "111 $sumBy")
1.只能用于字符串
TODO
作用:抛出异常以及测试错误的一个普通函数
TODO("测试TODO,抛出异常")
run
作用:不太懂什么意思,网上解释的也很模糊
//1.可以定义与外部变量同名的变量
var numText = "text"
numText.run {
var numText = "123"
log("numText1>>$numText")
}
log("numText2>>$numText")
//2.当需要调用一个类中的多个方法,或者不同类的同一方法时
var webView = WebView(this@MainActivity)
webView.settings.javaScriptEnabled = true
webView.settings.databaseEnabled = true
//简化之后的代码
webView.settings.run {
javaScriptEnabled = true
databaseEnabled = true
}
//3.可以用来判断空值,如果为空则不执行
webView.settings?.javaScriptEnabled = true
webView.settings?.databaseEnabled = true
//简化之后的代码
webView.settings?.run {
javaScriptEnabled = true
databaseEnabled = true
}
1.run以闭包返回最后一行代码
let
作用:内联函数, 和run作用相似
1.同以上2,3案例一致
2.与案例1不同的是,它的作用域是全局的
with()
作用:与let相似,不同点在于with需要传递一个参数
with("text"){
log("with>>>>$this")
}
1.with的标签为$this代表当前对象
apply()
作用:与run函数相似
webView.settings.apply {
this.allowContentAccess = true
}.apply {
this.allowFileAccess = true
}.apply {
this.blockNetworkImage = true
}
1.apply:每次返回对象本身,相当于传入webView,返回webView , 每次返回的对象都是同一个;与also不同的是,apply的作用域在整个父级范围中
2.run: 每一次返回最后一行代码的返回值,如为空,则为Unit;不可以定义与外部变量同名的变量
3.let: 每一次返回最后一行代码的返回值,如为空,则为Unit;可以定义与外部变量同名的变量
4.with: 每一次返回最后一行代码的返回值,如为空,则为Unit;以参数的方式传递,不能嵌套使用
5.also: 每次返回对象本身,相当于传入webView,返回webView , 每次返回的对象都是同一个;与apply不同的是,also的作用域只在函数范围
函数名 | 定义inline的结构 | 函数体内使用的对象 | 返回值 | 是否是扩展函数 | 适用的场景 |
---|---|---|---|---|---|
let | fun <T, R> T.let(block: (T) -> R): R = block(this) | it指代当前对象 | 闭包形式返回 | 是 | 适用于处理不为null的操作场景 |
with | fun <T, R> with(receiver: T, block: T.() -> R): R = receiver.block() | this指代当前对象或者省略 | 闭包形式返回 | 否 | 适用于调用同一个类的多个方法时,可以省去类名重复,直接调用类的方法即可,经常用于Android中RecyclerView中onBinderViewHolder中,数据model的属性映射到UI上 |
run | fun <T, R> T.run(block: T.() -> R): R = block() | this指代当前对象或者省略 | 闭包形式返回 | 是 | 适用于let,with函数任何场景。 |
apply | fun T.apply(block: T.() -> Unit): T { block(); return this } | this指代当前对象或者省略 | 返回this | 是 | 1、适用于run函数的任何场景,一般用于初始化一个对象实例的时候,操作对象属性,并最终返回这个对象。 2、动态inflate出一个XML的View的时候需要给View绑定数据也会用到. 3、一般可用于多个扩展函数链式调用 4、数据model多层级包裹判空处理的问题 |
also | fun T.also(block: (T) -> Unit): T { block(this); return this } | it指代当前对象 | 返回this | 是 | 适用于let函数的任何场景,一般可用于多个扩展函数链式调用 |
takeIf
作用:传入一个条件判断,如果成立返回该值,如果不成立则返回null
var takeIf = "text".takeIf {
it.startsWith("te1")
}
log("takeIf>>>>>$takeIf") //null
takeUnless
作用:和takeIf相反,传入一个条件判断,如果成立返回null,如果不成立则返回该值
var takeUnless = "text".takeUnless {
it.startsWith("te1")
}
log("takeUnless >>>>>$takeUnless") //text
repeat
作用:相当于循环
repeat(3){
log("repeat >>>>>$it") //0 | 1 | 2
}
1.$it为索引
reversed
作用:反转数组
var list = arrayListOf(1, 2, 3 , 4, "list")
log("list index >>> " + list[0]) //1
log("list component1 >>>" + list.component1()) //1
log("list component2 >>>" + list.component2()) //2
log("list >>>" + list.reversed().toString()) //["list" , 4, 3 , 2 , 1]
filter
作用:集合专用操作符;过滤不符合条件的值,组成新的数组
var arrayTo = arrayOf(1 ,2 , 3, 4)
var arrayList2 = arrayTo.toList()
var filter = arrayList2.filter {
it > 2
}
log("filter>>$filter")
filterIndexed
作用:集合专用操作符;与filter相同,但是可以获取数组的下标索引
var filterIndex = arrayList2.filterIndexed{index , result ->
index > 1 && result > 1
}
log("filterIndex>>> $filterIndex" )
map
作用:集合专用操作符;根据条件变换集合中的数据
var map = arrayList2.map {
"map".plus(it)
}
log("map>>>> $map" )
//[map1, map2, map3, map4]
mapNotNull
作用:与map相同,该函数会过滤掉为null的参数值
flatMap
作用:集合专用操作符; 根据条件合并两个集合,组成一个新的集合
var flatMap = arrayList2.flatMap {
listOf(it, "test".plus(it))
}
log("flatMap>>>> $flatMap" )
//[1, test1, 2, test2, 3, test3, 4, test4]
groupBy
作用:集合专用操作符;根据条件进行分组,组成多个不同条件的集合
var groupBy = arrayList2.groupBy {
if(it == 1) "data1" else "data2"
}
log("groupBy>>>> $groupBy" )
//{data1=[1], data2=[2, 3, 4]}
plus()
作用:合并两个元素,相当于Java的+,连接
var plus = "123"
log("plus >>> ${plus.plus(12)}")
sorted()
作用:自然升序
sortedBy{}
作用:根据条件升序,即把不满足条件的放在前面,满足条件的放在后面
sortedDescinding()
作用: 自然降序
sortedByDescinding{}
作用:根据条件降序。和sortedBy{}
相反
inline
作用:内联函数,当你调用一个inline function的时候,编译器不会产生一次函数调用,而是会在每次调用时,将inline function中的代码直接嵌入到调用处,本质上是在调用的地方直接加入拟定的代码
/**
* 传入泛型 , 验证当前对象是否为空
* @param notNullAction -> 不为空执行的函数,并返回当前的值
* @param nullAction -> 为空执行的函数 , 不返回任何值
* @return T 返回传入值继续下一步
* */
inline fun<reified T> T?.notNull(notNullAction : (T) ->Unit , nullAction : () -> Unit){
if(this != null) notNullAction.invoke(this) else nullAction.invoke()
}
reified
作用:通过reified关键字来标记这个泛型在编译时替换成具体类型
1.reified关键字一般和inline关键字一起使用(如上例),通过inline关键字我们可以知道inline会在调用的时候直接copy代码到调用的地方,调用时已经拟定了参数,所以我们知道参数的类型,通过reified关键字可以标记当前的具体类型