Kotlin 程序结构
常量
val = value,值类型
类似Java的final
不可能重复赋值
-
运行时常量:val x =getX()
-
编译期常量:const val x = 2
变量
val = variable -
var x = “HelloWorld”//定义变量
-
x = “Hello,China”//再次赋值
类型推导
编译器可以推导量的类型 -
val string =“Hello” //推导出String类型
-
val int = 5 //Int 类型
-
var x = getString() + 5 //String类型
函数
以特定功能组织起来的代码块 -
fun函数名:[返回值类型]{[函数体]}
-
fun函数名 = [表达式]
举例: -
fun sayHi(name:String) { println(“Hi,$name”) }
-
fun sayHi(name:String) = println(“Hi,$name”)
匿名函数
fun([参数列表])… -
val sayHi = fun(name:String) = println(“Hi,$name”)
编写函数的注意事项
功能单一
函数名要做到顾名思议
参数个数不要太多
Lambda 表达式
匿名函数
写法:{[参数列表]->[函数体,最后一行是返回值]} -
val sum = {a:Int,b:Int->a + b }
Lambda的类型举例
()->Unit
无参,返回值为Unit
(Int)->Int
传入整型,返回一个整型
(String,(String)->String)->Boolean -
传入字符串、Lambda表达式,返回Boolean
Lambda表达式的调用
用()进行调用
等价于invoke() -
val sum = {a:Int,b:Int -> a + b}
-
sum(2,3)
-
sum.invoke(2,3)
Lambda表达式的简化
函数参数调用时最后一个Lambda可以移出去
函数参数只有一个Lambda,调用时小括号可以省略
Lambda只有一个参数可默认为it
入参,返回值与形参一致的函数可以用函数引用的方式作为实参传入
fun main(args: Array<String>) {
println(int2Long(3))
println(sum(2, 3))
println(sum2(5, 6))
println(sum.invoke(1, 3))
val args: Array<Int> = arrayOf(1, 2, 3, 4, 5, 6)
for (i in args) {
println(i)
}
args.forEach(::println)
println("--------------------------------")
args.forEach ForEach@{
if (it == 2) return@ForEach
println(it)
}
println("The End 1.....")
args.forEach {
if (it == 3) return
println(it)
}
println("The End 2.....")
}
val int2Long = fun(x: Int): Long {
return x.toLong()
}
val sum = { arg1: Int, arg2: Int -> arg1 + arg2 }
val sum2 = { arg1: Int, arg2: Int -> println("$arg1 + $arg2 = ${arg1 + arg2}") }
3
5
5 + 6 = 11
kotlin.Unit
4
1
2
3
4
5
6
1
2
3
4
5
6
--------------------------------
1
3
4
5
6
The End 1.....
1
2
类成员
属性:作者说成员变量,类范围内的变量
方法:或者说成员函数,类范围内的函数
函数和方法的区别
函数强调功能本身,不考虑从属
方法的称呼通常是从类的角度出发
叫法不同而已,不要纠结
定义属性
构造方法参数中val/var修饰的都是属性
类内部也可以定义属性
属性访问控制
属性可以定义getter/setter
- val a:Int = 0 //不能定义set()
- get() = field
- var b:Float = 0f //可以定义getter/setter
- set(value){field = value}
属性初始化
属性的初始化尽量在构造方法中完成
无法在构造方法中初始化,尝试降级为局部变量
var用lateinit延迟初始化,val用lazy
可空类型谨慎用null直接初始化
class X
//lateinit 延迟初始化
class A {
var b = 0
lateinit var c: String
lateinit var d: X
val e: X by lazy {
println("init X")
X()
}
//可空类型谨慎用null直接初始化
var cc: String? = null
}
fun main(args: Array<String>) {
println("start")
val a = A()
println("init a")
println(a.b)
println(a.e)
a.d = X()
println(a.d)
println(a.cc?.length)
}
start
init a
0
init X
chapter3.X@7106e68e
chapter3.X@7eda2dbb
null
基本运算符
任何类可以定义或者重载父类的基本运算符
通过运算符对应的具体函数来定义
对参数个数作要求,对参数和返回值类型不作要求
不能像Scale一样定义任意运算符
中缀表达式
只有一个参数,且用infix修饰的函数
- class Book{ infix fun on(place:String){...}}
- Book() on "My Desk"
分支表达式
if...else
- if(a ==b ) ... else if(a == c) ... else ...
表达式与完备性
- val x = if(b < 0) 0 else b
- val x = if(b < 0) 0 //错误,赋值时,分支必须完备
private const val USERNAME = "kotlin"
private const val PASSWORD = "jetbrains"
private const val ADMIN_USER = "admin"
private const val ADMIN_PASSWORD = "admin"
private const val DEBUG = 1
private const val USER = 0
fun main(args: Array<String>) {
//1.变量赋值
// var mode = USER
// if (args.isNotEmpty() && args[0] == "1") {
// mode = DEBUG
// }
//2. 表达式给变量赋值
val mode = if (args.isNotEmpty() && args[0] == "1") {
DEBUG
} else {
USER
}
println("请输入用户名:")
val username = readLine()
println("请输入密码:")
val password = readLine()
if (mode == DEBUG && username == ADMIN_USER && password == ADMIN_PASSWORD) {
println("管理员登录成功")
} else if (username == USERNAME && password == PASSWORD) {
println("登录成功")
} else {
println("登录失败")
}
When 表达式
加强版switch,支持任意类型
支持纯表达式条件分支(类似if)
表达式与完备性
fun main(args: Array<String>) {
val x = 5
when (x) {
is Int -> println("Hello $x")
in 1..100 -> println("$x is in 1..100")
!in 1..100 -> println("$x is not in 1..100")
args[0].toInt() -> println("$x == args[0]")
}
}
Hello 5
循环语句
for循环
基本写法
- for(element in elements)…
给任意类实现Iterator方法
fun main(args: Array<String>) {
val args: Array<Char> = arrayOf('a', 'b', 'c', 'd')
for (arg in args) {
println(arg)
}
println("-------------------------------")
for ((index, value) in args.withIndex()) {
println("$index -> $value")
}
println("-------------------------------")
for (indexedValue in args.withIndex()) {
println("${indexedValue.index} -> ${indexedValue.value}")
}
println("-------------------------------")
val list = MyIntList()
list.add(1)
list.add(2)
list.add(3)
for (i in list) {
println(i)
}
}
class MyIterator(val iterator: Iterator<Int>) {
operator fun next(): Int {
return iterator.next()
}
operator fun hasNext(): Boolean {
return iterator.hasNext()
}
}
class MyIntList {
private val list = ArrayList<Int>()
fun add(int: Int) {
list.add(int)
}
fun remove(int: Int) {
list.remove(int)
}
operator fun iterator(): MyIterator {
return MyIterator(list.iterator())
}
}
a
b
c
d
-------------------------------
0 -> a
1 -> b
2 -> c
3 -> d
-------------------------------
0 -> a
1 -> b
2 -> c
3 -> d
-------------------------------
1
2
3
While循环
类似于C语言
跳过和终止循环
跳过当前循环用continue
终止循环用break
多层循环嵌套的终止结合便签使用
- Outter@for(...){
Inner@while(i < 0){ if(...) break } //结束while循环
Inner@while(i < 0){ if(...) break@Outter }//结束外层for循环
}
具名参数
给函数的时参附上形参
举例:
- fun sum(arg1:Int,arg2:Int) = arg1 + arg2
- sum(arg1 = 2, arg2 = 3)
变长参数
某个参数可以接收多个值
可以不为最后一个参数
如果传参时有歧义,需要使用具名参数
fun main(vararg args: String) {
// for (arg in args) {
// println(arg)
// }
hello(18.0,1,2,3,4,string ="Hello")
val array = intArrayOf(5,4,3,2,1)
hello(18.0,*array,string ="Hello")
}
fun hello(double: Double,vararg ints: Int, string: String) {
ints.forEach(::println)
}
1
2
3
4
5
4
3
2
1
本章知识点示例
fun main(args: Array<String>) {
while (true) {
try {
println("请输入算式例如:3 + 4")
val input = readLine() ?: break
if (input != null) {
val splits = input.trim().split(" ")
if (splits.size < 3) {
throw IllegalArgumentException("参数个数不对")
}
val arg1 = splits[0].toDouble()
val op = splits[1]
val arg2 = splits[2].toDouble()
println("$arg1 $op $arg2 = ${Operator(op).apply(arg1, arg2)}")
}
} catch (e: NumberFormatException) {
println("您输入的数字格式不对")
} catch (e: IllegalArgumentException) {
println("请输入用空格分隔的三个参数")
} catch (e:Exception){
println("未知异常:${e.message}")
}
println("再来一发?[Y]")
val cmd = readLine()
if (cmd == null || cmd.toLowerCase() != "y") {
break
}
}
}
class Operator(op: String) {
val opFun: (left: Double, right: Double) -> Double
init {
opFun = when (op) {
"+" -> { l, r -> l + r }
"-" -> { l, r -> l - r }
"*" -> { l, r -> l * r }
"/" -> { l, r -> l / r }
"%" -> { l, r -> l % r }
else -> {
throw UnsupportedOperationException(op)
}
}
}
fun apply(left: Double, right: Double): Double {
return opFun(left, right)
}
}
请输入算式例如:3 + 4
566.33.33 + 1
您输入的数字格式不对
再来一发?[Y]
y
请输入算式例如:3 + 4
23+1
请输入用空格分隔的三个参数
再来一发?[Y]
y
请输入算式例如:3 + 4
5 + 6
5.0 + 6.0 = 11.0
再来一发?[Y]
相关文章
- kotlin中Activity跳转
- 基于kotlin开发的验证码发送注册的app
- 开心档-Kotlin 基础语法
- 【Kotlin】Kotlin 高阶函数 ( 高阶函数当做参数 | 高阶函数定义 | 高阶函数调用 )
- 【Kotlin】Kotlin 领域特定语言 DSL 原理 二 ( 中缀表达式 )
- 【Kotlin 协程】Channel 通道 ③ ( CoroutineScope#produce 构造生产者协程 | CoroutineScope#actor 构造消费者协程 )
- 【Kotlin】集合操作总结 ( List 集合 | MutableList 集合 | List 集合遍历 | Set 集合 | MutableSet 集合 | Map 集合 | 可变 Map集合 )
- 【Kotlin】接口和抽象类 ( 接口属性和方法定义 | 接口默认方法实现 | 抽象类 )
- Kotlin新增协程、类型别名特性,提升了对JavaScript的支持详解手机开发