funval_declarations(){ //val声明的变量不能更改 val a = 64 val b= 123 val c = 3.4f//后面跟'F'或者'f' val d = 3.4 val e = 12.3e5 //不赋值的val声明,变量类型不能省略 val f: Int f = 13
val g = StringBuffer("test") g.replace(0, 1, "T") //打印 println("$a$b$c$d$e$f") println("$g")
funcharacters_and_strings() { //字符 println("=====字符=====") val a:Char = '\u0041' if (a.toInt() == 65){ println("match") }
//字符串 println("=====字符=====") val b:String = "Hello" println(b) println("取字符串中的字符:${b[0]}") println("遍历字符串中的字符:") for(letter in b) print("$letter\t") println()
//原始字符串 println("=====原始字符串=====") val raw = """Hello "test" world""" println(raw) //字符串模板 println("=====字符串模板=====") val c = 123.0 val d = "c = $c, price = ${'$'}${c/10}" println(d) //range println("=====range=====") val e = "${(10 downTo 1).toList().map { it.toString().toList() }.joinToString()}" println(e) }
2. 控制流
2.1 Nullability
在kotlin中var x:String = null是不允许的,因为它要求x不能为空。
1
fun main(args: Array<String>){}
对于上面的args表示的是由不能为空的String组成的不能为空的Array。
如果为null该怎么办,在类型名后添加?。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
funmain(args: Array<String>) { nullability() }
funnullability(){ var y:String? = null //下面的是错误的 //println(y.length) var len: Int? = y?.length println(len) //或者这样返回-1,其中?:类似else,也就是说如果y是Null,就返回-1 var len2:Int = y?.length ?: -1 println(len2)
funflow_based_typing() { var s:String? = "hjkh" if(s!=null){ //不需要s?.length println(s.length) } var x: Cloneable = intArrayOf(1, 2, 3) if (x is IntArray){ //不需要(x as IntArray).size println(x.size) } }
2.4 for遍历(for Iteration)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
funfor_loop(){ //普通for循环 for (a in (10 downTo 1)) print("$a\t") println()
//数组for循环 val ints = intArrayOf(4, 3, 2, 1) for((index, value) in ints.withIndex()){ println("$index:\t$value") }
//字典for循环 val capitals = mapOf("Paris" to "France", "London" to "UK") for ((capital, country) in capitals){ println("${country}'s capital is $capital") } }
funmain(args: Array<String>) { infix_functions() } //定义中缀函数 infixfunDouble.averageWith(other: Double):Double{ //this是左边的运算符 return (this + other) / 2.0 } funinfix_functions(){ val x = 'z' downTo 'a' for(a in x) print("$a\t") println()
val capitals = mapOf("Paris" to "France", "London" to "UK") for((key, value) in capitals) println("$key\t$value") println()
//调用中缀函数 val a = 3.0 val b = 10.0 println("The average of $a and $b is ${a averageWith b}") }
4 Lambda函数
4.1 Lambda函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
package KotlinSamples.Lambda
funmain(args: Array<String>) { val product = {x:Int, y:Int -> x * y} println("${product(2, 3)}") //可以把签名放在前面 val product2:(Int, Int)->Int = {x, y -> x* y} println("${product2(4, 6)}")
//lambda作为参数 val numbers = listOf(1, 2, 3, 4) val n = numbers.count { it > 2 } //等价于number.count({x->x>2}) println(n)
//闭包,kotlin中允许在lambda中修改外界的值 var sum = 0 numbers.forEach { sum += it } println("sum of $numbers is $sum") }
4.2 高阶函数
高阶函数是含有函数作为参数的函数,或者是返回值是函数的函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
funmain(args: Array<String>) { val numbers = listOf(7, 1, 3, 4) val maxvalue = max(numbers) {x, y -> x < y} println(maxvalue) }
fun<T>max(collection: Collection<T>, less:(T, T)->Boolean): T?{ var max:T? = null for(x in collection){ if (max == null || less(max, x)) max = x } return max }
4.3 带接受者的函数类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
funmain(args: Array<String>) { //Function type with receiver //类似扩展函数,但是只能作用于局部,而且这个函数是个lambda表达式,被存储在变量中 fun_type_with_recevier() //由于increaseBy是局部变量,因此下面的代码无法执行 //var y = 2 //y.increaseBy(10) }
funfun_type_with_recevier(){ //声明形式类似扩展函数,但是返回到变量中 val increaseBy = funInt.(value:Int) = this + value var x = 1 println("$x + 3 = ${x.increaseBy(3)}") }
4.4 Functors
不知道为什么,一直报错:Error:(10, 15) Kotlin: operator modifier is required on ‘invoke’ in ‘Average’
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
classAverage{ publicfuninvoke(vararg values: Double):Double{ val sum = values.sum() return sum/values.size } } funmain(args: Array<String>) { val a = Average() //functor val avg = a(1.0, 2.0, 3.0) println(avg) // fun String.invoke():String{ // return "("+this+")" // } // val str = "hello" // println("${str()}") }
classPerson{ lateinitvar name:String //如果不初始化,需要加lateinit var age:Int = -1 val canVote:Boolean get() = age > 16 var ssn = "00000" get() = field set(value) { println("$name's ssn is changed to $value") field = value } }
funmain(args: Array<String>) { var me = Person() me.name = "lixiang" me.age = 28 println("${me.name} can ${if (!me.canVote) "not " else ""}vote") me.ssn = "123456" }
5.2 构造函数和初始化
1 2 3 4 5 6 7 8 9 10 11
//注意,class的构造中需要给参数带上var或者val才是添加属性 classHuman(var name:String, val age:Int){ //初始化 init{ println("$name is $age") } } funmain(args: Array<String>) { var me = Human("Lixiang", 28) println("My name is ${me.name}, and my age is ${me.age}") }
classDelegate{ operatorfungetValue(thisRef:Any?, property: KProperty<*>):String{ return"$thisRef, thank you for delegating '${property.name}' to me!" }
operatorfunsetValue(thisRef: Any?, property: KProperty<*>, value:String){ println("$value has been assigned to '${property.name}' in $thisRef") } }
classPerson{ //委托 var name: String by Delegate() //委托的一种用法,惰性 val lazyValue: String by lazy { println("lazyValue初始化") "test" }
//委托的用法,通知,其中"John"是初始值 var othername: String by Delegates.observable("John") { prop, old, new -> println("${prop.name}$old -> $new") } } funmain(args: Array<String>) { var p = Person() p.name = "Lixiang" val s = p.name println(s) //只求一次值 println(p.lazyValue) println(p.lazyValue) println(p.lazyValue) p.othername = "Jack" }
//data class用来保存数据,他有以下几种方法 //equals()/hashCode() //toString() //copy() 深拷贝 //destructuring 解包操作 dataclassUser(val name:String, val age: Int){ //你也可以重写 overridefuntoString(): String{ return"My name is $name, age is $age" } }
funmain(args: Array<String>) { val a = User("Lixiang", 20) println(a) val b = User("Lixiang", 20) println(a == b) println(a === b) val c = a.copy() println(c == a) println(c ===a) //解包 val (name, age) = c println("$name, $age") }