最近在学kotlin,看了一些入门资料,整理为以下笔记(极简的形式记录的),便于自己复习,也希望对其他人有帮助。
kotlin是什么:
首先可以看下维基百科总体了解:Kotlin
以下关于Kotlin介绍章节摘抄于:写给Android开发者的Kotlin入门
Kotlin也是基于JVM设计的编程语言,算是对Java的温和改良。Google在2017年的IO大会上宣布,将Android开发的官方语言更换为Kotlin。比起Java来说,从编程思想到代码细节都有不少变化。
相对Java来说,Kotlin在编写代码时有如下优势:代码简洁高效、函数式编程、空指针安全、支持lambda表达式、流式API等。
在执行效率上,Kotlin和Java具有同样的理论速度(都是编译成JVM字节码)。
Kotlin和Java是互相完美兼容的,两种代码文件可以并存,代码可以互相调用、文件可以互相转换,库文件也可以无障碍地互相调用,据说使用Kotlin基本不会带来额外的成本负担。
一:kotlin基础:
1.Hello World:
kotlin的源文件不需要和Java一样必须有一个同名Public class,入口函数也是main,所以Hello World代码如下:
package net.println.kotlin fun main(args: Array<String>) { println("Hello World") }
二.基本数据类型
kotlin变量的声明无须像Java一样显式指明类型,它可以自动推断出具体的类型。
以下是基本类型的声明赋值例子:
1.数字
kotlin并没有显示的包装类型的概念,比如Int可以看做Java中int和Integer的合体,kotlin会根据场景自动判断是该用基本类型还是装箱类型。
//int32位 val anInt: Int = 8 val anotherInt: Int = 0xFF val moreInt: Int = 0b00000011 val maxInt: Int = Int.MAX_VALUE val minInt: Int = Int.MIN_VALUE //long 64位 val aLong: Long = 12368172397127391 val another: Long = 123 val maxLong: Long = Long.MAX_VALUE val minLong: Long = Long.MIN_VALUE //float 32位 val aFloat: Float = 2.0F val anotherFloat: Float = 1E3f val maxFloat: Float = Float.MAX_VALUE val minFloat: Float = -Float.MAX_VALUE //Double 64位 val aDouble: Double = 3.0 val anotherDouble: Double = 3.1415926 val maxDouble: Double= Double.MAX_VALUE val minDouble: Double= -Double.MAX_VALUE //Short 16位 val aShort: Short = 127 val maxShort: Short = Short.MAX_VALUE val minShort: Short = Short.MIN_VALUE //Byte 8位 val maxByte: Byte = Byte.MAX_VALUE val minByte: Byte = Byte.MIN_VALUE
2.字符
占2个字节,表示一个16位的Unicode字符,使用单引号引用:
val aChar: Char = '0' val bChar: Char = '中' val cChar: Char = '\u000f'
3.布尔
val aBoolean: Boolean = true val anotherBoolean: Boolean = false
4.字符串
字符串用 String
类型表示。字符串是不可变的。
字符串声明:
val string: String = "HelloWorld"
特殊字符的转义:
//打印出“Hello "Trump"” val sayHello : String = "Hello \"Trump\"" println(sayHello) //salary val salary: Int = 1000 //打印出“$salary” println("\$salary")
字符串模板:
val arg1: Int = 0 val arg2: Int = 1 println("" + arg1 + " + " + arg2 + " = " + (arg1 + arg2)) //字符串模板,表示使用“{}”括起来 println("$arg1 + $arg2 = ${arg1 + arg2}")
5.数组:
//无装箱开销的专门的类来表示原生类型数组 val arrayOfInt: IntArray = intArrayOf(1,3,5,7) val arrayOfChar: CharArray = charArrayOf('H', 'e','l','l','o','W','o','r','l','d') val arrayOfString: Array<String> = arrayOf("我", "是", "码农")
6.常量
编译期常量需要加const:
const val FINAL_HELLO_WORLD: String = "HelloWorld"
编译期编译后的代码将该引用使用的地方都替换为它的值。
三.类与对象
1.类的定义初始化:
//定义Girl、Boy类继承Human class Girl(charater: String, appearance: String, voice: String): Human(charater, appearance, voice) class Boy(charater: String, appearance: String, voice: String): Human(charater, appearance, voice) //只有open修饰的类才可以被继承 open class Human(var charater: String, var appearance: String, var voice: String){ //初始化代码块 init { println("new 了一个${this.javaClass.simpleName}, ta性格:$charater, 长相:$appearance, 声音:$voice") } } fun main(args: Array<String>) { val myGirl: Girl = Girl("温柔", "甜美", "动人") val myBoy: Boy = Boy("彪悍", "帅气", "浑厚") println(myGirl is Human) }
次构造函数:
class Person(val name: String) { constructor(name: String, parent: Person) : this(name) { parent.children.add(this) } }
2.类型转换:
假如有两个类,Child继承Parent:
open class Parent class Child: Parent() { fun getName(){ } }
安全的类型转换
fun main(args: Array<String>) { val parent: Parent = Parent() //当parent不为Child类型或子类的时候不抛异常,而是返回null val child: Child? = parent as? Child println(child) }
智能的类型转换:
var parent:Parent = Child() if (parent is Child){ //编译器知道parent是Child的实例了,无须像Java一样再做一次转换 print(parent.getName()) }
3.空安全:
fun getName(): String?{ return null } fun main(args: Array<String>) { //如果getName返回空则return,非空则将返回值赋值给name val name: String = getName() ?: return println(name.length) val value: String? = "HelloWorld" //告诉编译器value绝对为非空 println(value!!.length) //value非空才可以调用length,否则value?.length返回null print(value?.length) }
四.函数
1.基本函数声明:
在 Kotlin 中函数可以在文件顶层声明,这意味着你不需要像一些语言如 Java、C# 或 Scala 那样创建一个类来保存一个函数。
Kotlin 中的函数使用 fun 关键字声明:
fun double(x: Int): Int { return 2 * x }
函数参数使用 Pascal 表示法定义,即 name: type。
函数参数可以有默认值,与其他语言相比,这可以减少重载数量:
fun read(b: Array<Byte>, off: Int = 0, len: Int = b.size) { …… }
如果一个函数不返回任何有用的值,它的返回类型是 Unit(可以不用显示写在函数声明中):
fun printHello(name: String?): Unit { if (name != null) println("Hello ${name}") else println("Hi there!") // `return Unit` 或者 `return` 是可选的 }
2.命名参数:
当一个函数有大量的参数或默认参数时使用命名参数会非常方便:
例如以下函数声明:
fun reformat(str: String, normalizeCase: Boolean = true, upperCaseFirstLetter: Boolean = true, divideByCamelHumps: Boolean = false, wordSeparator: Char = ' ') { …… }
使用命名参数调用:
reformat(str, normalizeCase = true, upperCaseFirstLetter = true, divideByCamelHumps = false, wordSeparator = '_' )
代码的可读性就比较高。
3.单表达式函数
当函数返回单个表达式时,可以省略花括号并且在 = 符号之后指定代码体即可:
fun double(x: Int): Int = x * 2
这里的返回值可以不显示写出来,因为编译器会自动推断。具有块代码体的函数必须始终显式指定返回类型,除非他们旨在返回 Unit
)
4.可变数量的参数
函数的参数(通常是最后一个)可以用 vararg
修饰符标记:
fun <T> asList(vararg ts: T): List<T> { val result = ArrayList<T>() for (t in ts) // ts is an Array result.add(t) return result } //允许将可变数量的参数传递给函数: val list = asList(1, 2, 3)
5.函数作用域
kotlin可以在函数内部定义函数:
val int2Long = fun(x: Int): Long { var z = 5; fun a(y:Int) = y.toLong()+z return a(x) }
内部函数可以访问外部函数的局部变量,即闭包。
闭包:
1.函数内的函数
2.外部作用域声明变量
3.使用函数可以保存状态
闭包在逻辑上是封闭的,它使用自己内部的数据,用自己内部的逻辑进行处理,外部只能得到闭包的输出,无法输入,也无法干扰。
在系统资源上,闭包是持久使用的,它会一直在系统里,不像函数那样会被系统注销掉。
闭包在函数式编程里可以简化参数量、减少变量,会更加方便我们的开发。
6.成员函数
成员函数是在类或对象内部定义的函数:
class Sample() {
fun foo() { print("Foo") }
}