最近在学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") }
}