Android:Kotlin语法基础
主函数
fun main(args: Array<String>){println("Hello World")
}
复制代码
变量
1、常量
val修饰常量,编译器规定常量必须初始化,若不想初始化,可用**by lazy{}**对常量进行懒加载
val a: Int = 1 // 强类型常量
val b = 2 // 弱类型常量
const val c = "Hello" // 编译器常量
val a: String by lazy{"lazy init"} // 懒加载常量
复制代码
2、变量
var修饰变量,编译器规定变量必须初始化,若不想初始化,可用lateinit关键字限制报错
lateinit var a //未初始化变量var x = 5 //初始化变量
var x1 = "x is $x" //获取变量的值:$变量
var x2 = "${x1.replace("is","was")}" //内嵌表达式:${表达式}var str = """ //段落<html><a href="">go</a></html>
"""
复制代码
3、空值检测
println(value?.size) //if not null
println(value?.size ?: "empty") //if not null and else
println(value.firstOrNull() ?: "") //if not null and get first
println(values["key"] ?: a + b) //if not null and else + 表达式
value?.let{ } //if not null + 代码块
value!!.let{ } //告诉编译器不需要判空
复制代码
4、字符串比较
==:在kt中相当于java的equals() ===:在kt中相当于java的==
数组
1、定义
//每种基本类型都有对应的数组创建方法,类似于定制版
var array:IntArray = intArrayOf(1,3,5,7)
var array:CharArray = charArrayOf('H','E','L','L','O')
//基于泛性的创建方法,泛型也可省略,类似于通用版
var array:Array<Char> = arrayOf('H','E','L','L','O')
复制代码
2、数组和字符串转换
//第一种形式
var array:Array<Char> = arrayOf('H','E','L','L','O')
println(array.joinInString(""))
//第二种形式
var array:CharArray = charArrayOf('H','E','L','L','O')
println(String(array))
复制代码
3、数组遍历
var array:Array<Char> = arrayOf('H','E','L','L','O')
//第一种形式
array.forEach{println(it)}
//第二种形式
array.forEach{::println}
//第三种形式
for((index,value) in array.withIndex()){println("$index -> $value")
}
复制代码
函数
1、有返回值的函数
//第一种形式
fun sum(a: Int, b: Int): Int {return a + b}
//第二种形式
fun sum(a: Int, b: Int) = return a + b
//第三种形式
fun sum(a: Int, b: Int) = a + b
复制代码
2、无返回值的函数
Unit类型相当于Void类型,Unit返回类型可以省略不写
fun printSum(a: Int, b: Int): Unit { …… }
复制代码
3、默认参数的函数
fun foo(a: Int = 0, b: String = "") { …… }
复制代码
4、变长参数的函数
变长参数由vararg关键字决定,数组参数可通过*方式传参,第一个参数可以不使用名字指定,最后个参数必须使用具名参数
fun say(double: Double,vararg ints: Int,string: String) { …… }val array = intArrayOf(1,3,4,5)
say(2.0,*array,string = "Hi")
复制代码
5、扩展函数
你可以给父类添加一个方法,这个方法将可以在所有子类中使用
fun Activity.toast(message: CharSequence, duration: Int = Toast.LENGTH_SHORT) {Toast.makeText(this, message, duration).show()
}
复制代码
6、智能类型推测
判断一个对象是否为一个类的实例,可以使用is关键字与Java中的instanceof关键字类似,但在Kotlin中如果已经确定了一个对象的类型,可以在接下来的代码块中直接作为这个确定类型使用
fun getStringLength(obj: Any): Int? {if (obj is String) {return obj.length} //类型判断后,obj会被系统自动转换为String类型if (obj !is String){} //同时还可以使用!is,来取反return null //代码块外部的obj仍然是Any类型的引用
}
复制代码
7、复合函数
复合函数指的是函数中存在另一个函数,类似于数学的f(g(x))
infix fun <P1,P2,R> Function1<P1,P2>.andThen(function: Function1<P2,R>): Function1<P1,R>{return fun(p1:P1): R{return function.invoke(this.invoke(p1))}
}var add = {i: Int -> i + 5}
var plus = {i: Int -> i * 2}
var addAndPlus = add andThen plus
println(addAndPlus(8)) // (8+5)*2=26
复制代码
8、函数的科理化
函数的科理化指的是函数中传递的多个参数可转换为多个函数来进行链接
//科理化前的函数
fun log(tag: String,target: OutputStream,message: Any?){target.write("$tag $message\n".toByteArray())
}
log("Hensen",System.out,"HelloWorld")//科理化后的函数
fun log(tag: String)= fun(target: OutputStream)= fun(message: Any?)= target.write("$tag $message\n".toByteArray())
log("Hensen")(System.out)("HelloWorld")
复制代码
Lambda表达式
1、定义Lambda表达式
var sum = {arg1: Int,arg2: Int ->arg1 + arg2
}
//使用第一种方式
sum(1,2)
//使用第二种方式
sum.invoke(1,2)
复制代码
2、带有return的Lambda表达式
Lambda表达式并不是函数,如果直接return,会退出当前调用Lambda表达式的函数,而不是退出当前的Lambda表达式,可以使用**@别名**的方式退出
var array:Array<Char> = arrayOf('H','E','L','L','O')
array.forEach ForEach@{if(it == 'L')return@ForEachprintln(it)
}
复制代码
3、带有run的Lambda表达式
调用某对象的run函数,在函数块内可以通过this指代该对象。返回值为函数块的最后一行或指定return表达式
val a = "string".run {print(this) //string3
}
println(a) //3
复制代码
4、带有let的Lambda表达式
调用某对象的let函数,则该对象为函数的参数。在函数块内可以通过it指代该对象。返回值为函数块的最后一行或指定return表达式
val a = "string".let {println(it) //string3
}
println(a) //3
复制代码
5、带有with的Lambda表达式
它是将某对象作为函数的参数,在函数块内可以通过this指代该对象。返回值为函数块的最后一行或指定return表达式
val a = with("string") {println(this) //string3
}
println(a) //3
复制代码
6、带有apply的Lambda表达式
调用某对象的apply函数,在函数块内可以通过this指代该对象。返回值为该对象自己
val a = "string".apply {println(this) //string
}
println(a) //string
复制代码
7、带有also的Lambda表达式
调用某对象的also函数,则该对象为函数的参数。在函数块内可以通过it指代该对象。返回值为该对象自己
val a = "string".also {println(it) //string
}
println(a) //string
复制代码
8、小结
- run:使用this指定当前对象,最后一行为返回值
- let:使用it指定当前对象,最后一行为返回值
- with:使用this指定当前对象,最后一行为返回值,写法上有区别
- apply:使用this指定当前对象,返回值为该对象自己
- also:使用it指定当前对象,返回值为该对象自己
表达式
1、When表达式
fun transform(x: Int){return when (x) {is Int -> println("$x is Int")in 1..100 -> println("$x is in 1-100")!in 1..100 -> println("$x is not in 1-100")//else不写则不做默认操作else -> throw IllegalArgumentException("Invalid x param value")}
}
复制代码
或者
fun describe(obj: Any): String =when (obj) {1 -> "One""Hello" -> "Greeting"is Long -> "Long"!is String -> "Not a string"else -> "Unknown"
}
复制代码
2、try-catch表达式
fun test() {val result = try {count()} catch (e: ArithmeticException) {throw IllegalStateException(e)}
}
复制代码
3、if表达式
fun foo(param: Int) {val result = if (param == 1) {"one"} else if (param == 2) {"two"} else {"three"}
}
复制代码
4、with表达式
class Turtle {fun penDown()fun penUp()fun turn(degrees: Double)fun forward(pixels: Double)
}val myTurtle = Turtle()
with(myTurtle) { // 画一个 100 像素的正方形penDown()for(i in 1..4) {forward(100.0)turn(90.0)}penUp()
}
复制代码
5、for表达式
val items = listOf("apple", "banana", "kiwifruit")
for (item in items) {println(item)
}val items = listOf("apple", "banana", "kiwifruit")
for (index in items.indices) {println("item at $index is ${items[index]}")
}
复制代码
6、while表达式
val items = listOf("apple", "banana", "kiwifruit")
var index = 0
while (index < items.size) {println("item at $index is ${items[index]}")index++
}
复制代码
7、中缀表达式
使用infix关键字创建中缀表达式
Class Book{infix fun on(any: Any): Boolean{return false}
}Class Desk{}if(Book on Desk){println("book on the desk")
}
复制代码
闭包
1、函数内部可以定义函数,属于闭包
fun add(x: Int): (Int)-> Int{return fun(y: Int): Int{return x + y}
}
复制代码
2、闭包持有函数内部的运行状态
fun justCount():() -> Unit{var count = 0 //被函数内部持有return {println(count++)}
}fun main(args: Array<String>) {val count = justCount()count() // 输出结果:0count() // 输出结果:1count() // 输出结果:2
}
复制代码
3、自行闭包
自执行闭包就是在定义闭包的同时直接执行闭包,一般用于初始化上下文环境
{ x: Int, y: Int ->println("${x + y}")
}(1, 3)
复制代码
运算符
1、自定义运算符
class Complex(var arg1: Double,var arg2: Double){operator fun plus(other: Complex): Complex{return Complex(arg1 + other.arg1,arg2 + other.arg2)}operator fun plus(other: Int): Complex{return Complex(arg1 + other,arg2)}oprator fun invoke(): Double{return Math.hypot(arg1,arg2)}overide fun toString(): String{return "${arg1} and ${arg2}"}
}val c1 = Complex(3.0,4.0)
val c1 = Complex(2.0,5.0)
println(c1 + c2) //5.0 and 9.0
println(c1 + 5) //8.0 and 4.0
println(c1()) //5
复制代码
区间语句
1、定义区间
var range = 0..1024 //[0,1024]闭区间
var range = 0 until 1024 //[0,1024)半开区间
var range = 0..-1 //空区间
复制代码
2、检查x是否在指定区间里面
val x = 10
val y = 9
if (x in 1..y+1) {println("fits in range")
}
复制代码
3、检查list.size是否在list的索引上
val list = listOf("a", "b", "c")if (-1 !in 0..list.lastIndex) {println("-1 is out of range")
}
if (list.size !in list.indices) {println("list size is out of valid list indices range too")
}
复制代码
4、区间遍历
for (x in 1..10 step 2) {print(x) //13579
}
for (x in 9 downTo 0 step 3) {print(x) //9630
}
复制代码
集合
1、初始化
val mutableList = mutableListOf(0, 1) //可读写List对象
var list = listOf(0, 1, 2) //可读List对象
val set = setOf(1, 2, 4) //可读Set对象
复制代码
2、集合遍历
val items = listOf("a", "b", "c")
for (item in items) {println(item)
}
复制代码
3、集合判断
val items = listOf("apple", "balanace", "coffee")
when {"orange" in items -> println("juicy")"apple" in items -> println("apple is fine too")
}
复制代码
映射
1、初始化
val map = mutableMapOf("a" to 1, "b" to 2, "c" to 3) //可读写Map对象
val map = mapOf("a" to 1, "b" to 2, "c" to 3) //可读Map对象
复制代码
2、访问Map
map["key"] = value
复制代码
3、遍历Map
for ((k, v) in map) {println("$k -> $v")
}
复制代码
构造方法
1、主构造函数
Kotlin的构造函数可以写在类头中,跟在类名后面,如果有注解还需要加上关键字constructor
class Person(private val name: String) {fun sayHello() {println("hello $name")}
}
复制代码
在主构造函数中不能有任何代码实现,如果有额外的代码需要在构造方法中执行,你需要放到init代码块中执行
class Person(private var name: String) {init {name = "Zhang Tao"}fun sayHello() {println("hello $name")}
}
复制代码
2、次构造函数
存在两个或两个以上的构造方法时,可以增加次构造方法
class Person(private var name: String) {private var description: String? = nullinit {name = "Zhang Tao"}constructor(name: String, description: String) : this(name) {this.description = description}fun sayHello() {println("hello $name")}
}
复制代码
类与对象
1、输出类名
println(HelloWorld::class.java.simpleName) //输出类名
println(HelloWorld::class.java.name) //输出包名+类名
复制代码
2、创建对象
val rectangle = Rectangle(5.0, 2.0)
val triangle = Triangle(3.0, 4.0, 5.0)
复制代码
3、数据类
data修饰的类称之为数据类,当data修饰后,会自动将所有成员用operator声明,即为这些成员生成getter()和setter()
data class Customer(val name: String, val email: String)
复制代码
编译器自动从主构造函数中的属性导入下面这些成员函数
equals()
hashCode()
toString()
componentN():函数返回对应着声明的参数顺序
copy()
复制代码
4、内部类
Kt默认的内部类为静态内部类,可以使用inner关键字将内部类变为非静态内部类,且可使用注解去获取外部类的成员属性
class Outter{var a = 5inner class Inner{var a = 6fun getOutterA(){println(this@Outter.a)}}
}
复制代码
5、单例类
object关键字表示该类是单例
class Single private constructor() {companion object {fun get():Single{return Holder.instance}}private object Holder {val instance = Single()}
}
复制代码
或者
object Resource {val name = "Name"
}
//使用
Resource.INSTANCE.name
复制代码
6、枚举类
枚举默认没有数值,如果需要固定类型的数值,可在类名后声明参数类型
enum class Programer(val id: Int) {JAVA(0), KOTLIN(1), C(2), CPP(3), ANDROID(4);fun getTag(): String{return "$id + $name"}
}
//使用
println(Programer.JAVA.getTag())
复制代码
7、密封类
sealed修饰的类称为密封类,用来表示受限的类层次结构
sealed class BaseClass {class Test1 : BaseClass() {override fun test() {println("Test1实例")}}class Test2 : BaseClass() {override fun test() {println("Test2实例")}}object Test3 : BaseClass() {override fun test() {println("Test3实例")}}open fun test() {println("BaseClass实例")}
}
复制代码
密封类与枚举的区别:
密封类是枚举类的扩展 枚举类型的值集合是受限的,且每个枚举常量只存在一个实例 密封类的一个子类可以有可包含状态的多个实例 8、继承
在class中加open关键字即可被继承
open class Person(var name:String, var age:Int){}
复制代码
9、接口代理
接口代理表示代理人可直接调用接口代理的方法
//代理driver和writer,当执行manager.driver(),Manager类会去调用代理的driver.driver()
class Manager(val driver: Driver,val writer: Writer):Driver by driver,Writer by writerinterface Driver{fun driver()}
interface Wirter{fun wirter()}
复制代码
10、伴生对象
用companion关键字修饰对象内的方法,我们称companion修饰的对象为伴生对象,本质是静态方法。如果在Java文件中想通过类名的方式去调用静态方法,则需要加入注解才可以使用
class StringUtils {companion object {@JvmStaticfun isEmpty(str: String): Boolean {return "" == str}@JvmFieldvar TAG = "StringUtils"}
}
复制代码
11、方法重载
由于Kt中有默认参数的性质,所以方法的重载可以用默认参数来实现,如果在Java文件中想使用Kt重载的话,就需要加入注解才可以使用
class StringUtils {@JvmOverloadsfun a(int: Int = 0): Int{return int}
}
复制代码
12、匿名对象
使用object对象表示匿名对象
btn?.setOnClickListener(object : View.OnClickListener{override fun onClick(v: View?) {}
})
复制代码
常用操作符
Kotlin的操作符跟RxJava基本一致
1、下标操作类
- contains:判断是否有指定元素
- elementAt:返回对应的元素,越界会抛IndexOutOfBoundsException
- firstOrNull:返回符合条件的第一个元素,没有返回null
- lastOrNull:返回符合条件的最后一个元素,没有返回null
- indexOf:返回指定元素的下标,没有 返回-1
- singleOrNull:返回符合条件的单个元素,如有没有符合或超过一个,返回null
2、判断类
- any:判断集合中 是否有满足条件的元素
- all:判断集合中的元素是否都满足条件
- none:判断集合中是否都不满足条件,是则返回true
- count:查询集合中满足条件的元素个数
- reduce:从第一项到最后一项进行累计
3、过滤类
- filter:过滤 掉所有满足条件的元素
- filterNot:过滤所有不满足条件的元素
- filterNotNull:过滤NULL
- take:返回前n个元素
4、转换类
- map:转换成另一个集合
- mapIndexed:除了转换成另一个集合,还可以拿到Index
- mapNotNull:执行转换前过滤掉 为 NULL 的元素
- flatMap:自定义逻辑合并两个集合
- groupBy:按照某个条件分组,返回Map
5、排序类
- reversed:反序
- sorted:升序
- sortedBy:自定义排序
- sortedDescending:降序
6、实战操作符
val fruits = listOf("banana", "avocado", "apple", "kiwifruit")
fruits.filter { it.startsWith("a") }.sortedBy { it }.map { it.toUpperCase() }.forEach { println(it) }
复制代码
特性
1、懒加载
val p: String by lazy {// 计算该字符串
}
复制代码
2、安全类型转换
父类转成子类会抛出类型转换失败的错误,如果采用**as?**的方式,则返回null
var child: Child = parent as? Child
复制代码
3、输出可执行文件
在Gradle添加依赖指定main函数文件,后缀名为Kt
apply plugin:'application'
mainClassName = "com.hensen.android.MyCalcKt"
复制代码
刷新Gradle,在Gradle右边栏点击distribution/installDist,生成的程序在build/install目录下
4、internal关键字
在变量中使用internal关键字表示成员变量只允许在模块内能被访问到
internal var name
复制代码
5、尾递归
对于递归函数,如果递归函数并未对递归的结果进行操作,则可以使用tailrec关键字将递归声明为尾递归,尾递归会优化代码,将递归转换成迭代
data class ListNode(val value: Int,var next: ListNode?)
//对递归的结果并未操作,属于尾递归
tailrec fun findListNode(head: ListNode?,value: Int): ListNode?{head?: return nullif(head.value == value) return headreturn findListNode(head.next,value)
}
//对递归的结果进行乘法运算,不属于尾递归
fun factorial(n: Long): Long{return n * factorial(n - 1)
}
复制代码
Android相关
1、view.find
使用Ktolin的拓展函数,view.find替代findViewById
var textView = view.find(R.id.textView)
复制代码
2、observable
Delegates.observable可以监听当前的变量值的变化,改变变量的值,即可触发observable
private var mCurrentState: Int by Delegates.observable(-1) { _, old, new ->if (old != new) {RxBus.getDefault().post(ChannelPK_OnModelChange_Rank_EventArgs(new == 1))MLog.info(PKModelManager.TAG, "rank mode : $old -> $new")}
}fun onModelChange() {mCurrentState = 1 //改变变量的值,即可触发observable
}
复制代码
3、bundle
创建bundle已经不需要再去执行其各种put方法
val bundle = bundleOf("KET_INT" to 1,"KET_LONG" to 2L,"KET_BOOLEAN" to true,"KEY_NULL" to null,"KEY_ARRAY" to arrayOf(1, 2)
)
复制代码
4、Parcelize
Parcelize已经不需要再写什么代码了,只需要继承和注解
@Parcelize
data class User(val name: String,val age: Int): Parcelize
复制代码
@Parcelize的使用需要在gradle声明变量androidExtensions {experimental = true
}
复制代码
5、Serializable
指定Serializable的名字
class Book(@SerializedName(TXT) var txt: String)
复制代码
6、postDelay
postDelay支持闭包和lambda表达式
handler.postDelayed(50) {// lambda
}
复制代码
7、注解
如果说在Java文件中需要使用到KT的变量、静态方法、重载方法等,就需要注解声明
- @JvmField:将属性编译为Java变量
- @JvmStatic:将伴生对象编译为Java静态方法
- @JvmOverloads:默认参数生成重载方法
- @file:JvmName:指定Kotlin文件编译后的类名
转载于:https://juejin.im/post/5cd58088f265da039b088aef
Android:Kotlin语法基础相关推荐
- 【Android学习之路】Kotlin语言基础
Kotlin语法基础 文章目录 Kotlin语法基础 变量 NULL检查机制 对象数据类型 类型转换 字符和字符串 区间 函数 lambda(匿名函数) 程序逻辑控制 if条件判断 when条件语句 ...
- Kotlin从小白到大牛第1篇 【Kotlin】基础视频课程-关东升-专题视频课程
Kotlin从小白到大牛第1篇 [Kotlin]基础视频课程-7239人已学习 课程介绍 本视频是智捷课堂推出的一套"Kotlin语言学习立体教程"的视频第一部分, ...
- 温习Android基础知识——《第一行代码(第三版)》读书笔记 Chapter 2 Kotlin语法
第二章:探究新语言,快速入门Kotlin编程 Google在2017年的I/O大会上宣布Kotlin为Android的一级开发语言,之后又在2019年的I/O大会上宣布其成为Android第一开发语言 ...
- Android kotlin基础语法
1.继承类和实现接口 继承类是冒号连接,java是extends连接.实现接口是逗号连接,java是implements连接 class MainActivity : AppCompatActivit ...
- 《Android 安全(二)》Smali语法基础
Github原文 Smali smali/baksmali 是Android的Java VM实现dalvik使用的dex格式的汇编程序/反汇编程序. 语法松散地基于Jasmin/ dedexer的语法 ...
- java程序 下雨,利用SurfaceView实现下雨与下雪动画效果详解(Kotlin语法)
前言 最近打算做一波东西巩固一下自己近期所学所得.话不多说,先看一下最终完成的效果图: 下雨.gif 这里比较懒--第二个图片中还是降雨--不过这不是关键点-- 下雪.gif 录制的mp4,转成了gi ...
- Android App开发基础
Android App开发基础 App的开发特点 (1)App的运行环境 1.使用数据线把手机连到电脑上 2.在电脑上安装手机的驱动程序 3.打开手机的开发者选项并启用USB调试 4.将连接的手机设为 ...
- Kotlin零基础入门到精通(精选)
Kotlin零基础入门到精通(精选) 一. Kotlin课程概述 1.1 课程安排: 1.2 什么是Kotlin? 1.3 Kotlin的发展历程 1.4 学习目标 1.5 必备知识 1.6 参考资料 ...
- 2022 最新 Android 基础教程,从开发入门到项目实战【b站动脑学院】学习笔记——第二章:Android App 开发基础
第 2 章 Android App开发基础 本章介绍基于Android系统的App开发常识,包括以下几个方面:App开发与其他软件开发有什么不一 样,App工程是怎样的组织结构又是怎样配置的,App开 ...
最新文章
- java 异步请求重定向_JavaEE通过response实现请求重定向
- linux中ed编辑器手册,脚本编辑器 - Navicat 15 for Linux 产品手册
- shell+飞信实现网站监控
- 中国互联网的抑郁:抄与被抄都很痛
- Java黑皮书课后题第5章:*5.47(商业:检测ISBN-13)ISBN-13是标识书籍的新标准。它使用13位数字d1d2d3~d12d13,d13是校验和。如果校验和为10,则替换为0。求所有数字
- 0048-三角形的判断
- mysql下载安装及配置_mysql的下载,安装和配置
- 掌握shell编程中数组的常见用法及示例
- 上位机与1200组态步骤_图解组态王一组态王软件
- strcpy的用法、c语言实现、及注意点
- vmware 14 密钥
- c++入门 简单语句 空语句 作用域和块 复合语句
- Protel DXP使用教程 -建立工程与绘制原理图PCB图
- 人工智能(机器学习)学习路线
- 美团开店宝Android pad,美团开店宝(com.sankuai.meituan.merchant) - 9.2.1 - 应用 - 酷安
- 淘宝前后端分离实践(PPT)
- 使用v-cli创建项目,引入element-ui构建用户管理页面实现增删改查
- 【Hexo】NexT 主题的配置使用记录
- 什么是Merkle Tree(默克尔树)
- MySQL-LOCATE和FIND_IN_SET函数
热门文章
- 牛客网——数字求和(水题
- iPhone开发【一】从HelloWorld開始
- core文件与gdb调试
- 探索 ASP.NET Futures (Part 2 - Search Enabled)
- hashcat离线碰撞md5
- (十一)开发环境【不会这些,你就会被认定是菜鸟小白,没做过项目】
- matlab神经网络每次相差大,GA-BP网络为什么每次训练的结果相差很大呢?
- python ttf svg path_SVG的path的使用
- 为什么多对多关系需要建立中间表_中间表是什么?和报表有什么关系?会带来怎样的问题?又如何解决?...
- Convolutional Neural Networks for Sentence Classification-学习笔记