常量
- val = value,值類型
- 類似Java的final
- 不可能重復(fù)賦值
- 運(yùn)行時(shí)常量:val x =getX()
- 編譯期常量:const val x = 2
變量
- val = variable
- var x = "HelloWorld"http://定義變量
- x = "Hello,China"http://再次賦值
類型推導(dǎo)
- 編譯器可以推導(dǎo)量的類型
- val string ="Hello" //推導(dǎo)出String類型
- val int = 5 //Int 類型
- var x = getString() + 5 //String類型
函數(shù)
- 以特定功能組織起來(lái)的代碼塊
- fun[函數(shù)名]([參數(shù)列表]):[返回值類型]{[函數(shù)體]}
- fun[函數(shù)名]([參數(shù)列表]) = [表達(dá)式]
舉例:
- fun sayHi(name:String) { println("Hi,$name") }
- fun sayHi(name:String) = println("Hi,$name")
匿名函數(shù)
- fun([參數(shù)列表])...
- val sayHi = fun(name:String) = println("Hi,$name")
編寫函數(shù)的注意事項(xiàng)
- 功能單一
- 函數(shù)名要做到顧名思議
- 參數(shù)個(gè)數(shù)不要太多
Lambda 表達(dá)式
- 匿名函數(shù)
- 寫法:{[參數(shù)列表]->[函數(shù)體,最后一行是返回值]}
- val sum = {a:Int,b:Int->a + b }
Lambda的類型舉例
- ()->Unit
無(wú)參,返回值為Unit
- (Int)->Int
傳入整型,返回一個(gè)整型
- (String,(String)->String)->Boolean
- 傳入字符串、Lambda表達(dá)式,返回Boolean
Lambda表達(dá)式的調(diào)用
- 用()進(jìn)行調(diào)用
- 等價(jià)于invoke()
- val sum = {a:Int,b:Int -> a + b}
- sum(2,3)
- sum.invoke(2,3)
Lambda表達(dá)式的簡(jiǎn)化
- 函數(shù)參數(shù)調(diào)用時(shí)最后一個(gè)Lambda可以移出去
- 函數(shù)參數(shù)只有一個(gè)Lambda,調(diào)用時(shí)小括號(hào)可以省略
- Lambda只有一個(gè)參數(shù)可默認(rèn)為it
- 入?yún)ⅲ祷刂蹬c形參一致的函數(shù)可以用函數(shù)引用的方式作為實(shí)參傳入
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
類成員
- 屬性:作者說(shuō)成員變量,類范圍內(nèi)的變量
- 方法:或者說(shuō)成員函數(shù),類范圍內(nèi)的函數(shù)
函數(shù)和方法的區(qū)別
- 函數(shù)強(qiáng)調(diào)功能本身,不考慮從屬
- 方法的稱呼通常是從類的角度出發(fā)
- 叫法不同而已,不要糾結(jié)
定義屬性
- 構(gòu)造方法參數(shù)中val/var修飾的都是屬性
- 類內(nèi)部也可以定義屬性
屬性訪問(wèn)控制
- 屬性可以定義getter/setter
- val a:Int = 0 //不能定義set()
- get() = field
- var b:Float = 0f //可以定義getter/setter
- set(value){field = value}
屬性初始化
- 屬性的初始化盡量在構(gòu)造方法中完成
- 無(wú)法在構(gòu)造方法中初始化,嘗試降級(jí)為局部變量
- var用lateinit延遲初始化,val用lazy
- 可空類型謹(jǐn)慎用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()
}
//可空類型謹(jǐn)慎用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
基本運(yùn)算符
- 任何類可以定義或者重載父類的基本運(yùn)算符
- 通過(guò)運(yùn)算符對(duì)應(yīng)的具體函數(shù)來(lái)定義
- 對(duì)參數(shù)個(gè)數(shù)作要求,對(duì)參數(shù)和返回值類型不作要求
- 不能像Scale一樣定義任意運(yùn)算符
中綴表達(dá)式
- 只有一個(gè)參數(shù),且用infix修飾的函數(shù)
- class Book{ infix fun on(place:String){...}}
- Book() on "My Desk"
分支表達(dá)式
- if...else
- if(a ==b ) ... else if(a == c) ... else ...
- 表達(dá)式與完備性
- val x = if(b < 0) 0 else b
- val x = if(b < 0) 0 //錯(cuò)誤,賦值時(shí),分支必須完備
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. 表達(dá)式給變量賦值
val mode = if (args.isNotEmpty() && args[0] == "1") {
DEBUG
} else {
USER
}
println("請(qǐng)輸入用戶名:")
val username = readLine()
println("請(qǐng)輸入密碼:")
val password = readLine()
if (mode == DEBUG && username == ADMIN_USER && password == ADMIN_PASSWORD) {
println("管理員登錄成功")
} else if (username == USERNAME && password == PASSWORD) {
println("登錄成功")
} else {
println("登錄失敗")
}
When 表達(dá)式
- 加強(qiáng)版switch,支持任意類型
- 支持純表達(dá)式條件分支(類似if)
- 表達(dá)式與完備性
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
循環(huán)語(yǔ)句
for循環(huán)
- 基本寫法
- for(element in elements)...
- 給任意類實(shí)現(xiàn)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循環(huán)
類似于C語(yǔ)言
跳過(guò)和終止循環(huán)
- 跳過(guò)當(dāng)前循環(huán)用continue
- 終止循環(huán)用break
- 多層循環(huán)嵌套的終止結(jié)合便簽使用
- Outter@for(...){
Inner@while(i < 0){ if(...) break } //結(jié)束while循環(huán)
Inner@while(i < 0){ if(...) break@Outter }//結(jié)束外層for循環(huán)
}
具名參數(shù)
- 給函數(shù)的時(shí)參附上形參
- 舉例:
- fun sum(arg1:Int,arg2:Int) = arg1 + arg2
- sum(arg1 = 2, arg2 = 3)
變長(zhǎng)參數(shù)
- 某個(gè)參數(shù)可以接收多個(gè)值
- 可以不為最后一個(gè)參數(shù)
- 如果傳參時(shí)有歧義,需要使用具名參數(shù)
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
本章知識(shí)點(diǎn)示例
fun main(args: Array<String>) {
while (true) {
try {
println("請(qǐng)輸入算式例如:3 + 4")
val input = readLine() ?: break
if (input != null) {
val splits = input.trim().split(" ")
if (splits.size < 3) {
throw IllegalArgumentException("參數(shù)個(gè)數(shù)不對(duì)")
}
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("您輸入的數(shù)字格式不對(duì)")
} catch (e: IllegalArgumentException) {
println("請(qǐng)輸入用空格分隔的三個(gè)參數(shù)")
} catch (e:Exception){
println("未知異常:${e.message}")
}
println("再來(lái)一發(fā)?[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)
}
}
請(qǐng)輸入算式例如:3 + 4
566.33.33 + 1
您輸入的數(shù)字格式不對(duì)
再來(lái)一發(fā)?[Y]
y
請(qǐng)輸入算式例如:3 + 4
23+1
請(qǐng)輸入用空格分隔的三個(gè)參數(shù)
再來(lái)一發(fā)?[Y]
y
請(qǐng)輸入算式例如:3 + 4
5 + 6
5.0 + 6.0 = 11.0
再來(lái)一發(fā)?[Y]