Kotlin
类型
基本类型
// 基本类型 Byte Short Int Long Double Floatval a = 1// 同swift 不支持隐式转换// val b: Double = aprintln(a.toDouble())// 字面常量 同 Java 但不支持八进制表示println(100_000)println(0b10000000)// 加减乘除取余跟大部分语言是一样的// 位运算println(1 shl 2)// 无符号整数 UByte UShort UInt ULong// 布尔运算也是跟Java一样println(true && false)// 字符串for(c in "cxk,jntm") { println(c)}// 原始字符串val text = """ <div> <span>abc</span> </div>""".trimIndent()// 字符串模板println("$b --- ")// 数组Array(5) {}.forEach { println(it) }// 原生类型数组intArrayOf(1,2,3,4).forEach { println(it) }
类型检测与转换
println("cxk" is String)println("cxk" !is String) // 等同于 !("cxk" is String)var str: Any = "cxk"if (str is String) { // 当编译器能保证变量在检测和使用之间不可改变时,智能转换才有效 // 在该分支 str自动被转为String println(str.length)}// 不安全的转换操作//println(str as Int)// 安全的可用转换操作 转换失败返回nullprintln(str as? Int)val list: List<String> = listOf("")if (list is ArrayList) { // `list` 会智能转换为 `ArrayList<String>`}
控制流
条件与循环
// if是表达式 会返回一个值var a = if (1 >2) 11 else 999// when语句// 除非编译器能够检测出所有的可能情况都已经覆盖了 否则需要else语句var str = "cxk"val ans = when("cxk") { "cxk" -> "jntm" // 多种情况 "jg", "ngm" -> "cxk" is String -> println("str is String") else -> "unknow"}// for循环遍历迭代器for(item in listOf("1", "2", "3")){}// 通过索引遍历数组var arr = arrayOf("1", "3","3")for(i in arr.indices) { println(arr[i])}// 数字区间迭代for(item in 1..10 step 2){println(item)}for(item in 10 downTo 0 step 2){println(item)}// while 和 do-while 循环var i = 0while (i < 10) {i++}do { i--;} while( i >= 0)
返回与跳转
// return 默认从最直接包围它的函数或者匿名函数返回fun foo() { listOf(1, 2, 3, 4, 5).forEach { if (it == 3) return // 此时这里直接返回到foo的调用者 而非退出这个lambda表达式 print(it) } println("this point is unreachable")}foo()fun foo1() { listOf(1, 2, 3, 4, 5).forEach a@{ if (it == 3) return@a// 此时这里就是退出lambda表达式 print(it) } println("this point is reachable")}foo1()// 标签loop@ for(i in 1..10) { for(j in 1..10) { if (i == 1 && j == 2) break@loop }}
异常
// kotlin 只有非受检异常try { if (2 > 1) throw Exception("n")}catch (e: Exception) { println(e)} finally { println("clean")}// try是一个表达式 可以有一个返回值 出现异常返回catch代码块里的返回值println(try {"cxk".toInt()}catch (e: NumberFormatException){null})
类
/ 空类class Emptyclass Person(name: String) { var innerName: String = name.uppercase() init { println("init code block ${innerName}") }}// 如果构造器有修饰符或者注解 则需要constructor关键字class Animal protected constructor(){}class Pet(owner: String) { // 次构造函数 将工作委托给主构造函数 constructor(): this("cxk")}// 使用open代表该类开放继承open class Remote { open val url = "baidu.com" open fun execute(){}}// 抽象类abstract class BaseRemote: Remote() { // 覆盖属性 // 可以用一个 var 属性覆盖一个 val 属性,但反之则不行 override val url = "google.com" // 一个抽象成员覆盖一个非抽象的开放成员 abstract override fun execute() open fun wrapper(){ println("BaseRemote wrapper") }}interface HTTP { fun wrapper(){ println("HTTP wrapper") }}class WarnRemote: BaseRemote(), HTTP{ override fun execute() { TODO("Not yet implemented") } override fun wrapper(){ // 调用父类的方法 super<BaseRemote>.wrapper(); // 调用特定接口的方法 super<HTTP>.wrapper(); println("WarnRemote wrapper") }}
属性
// 编译期常量const val PAGE_SIZE = 100class Properties { var key: String = "" var value: String = "" // getter setter // 0是幕后属性 var counter : Int = 0 set(value) {field = value+1} get() {return ++field } // 延迟初始化属性 lateinit var item: Item fun get(): Item? { if (::item.isInitialized) { return item } return null }}
接口
interface Service{ // 接口属性 val name: String get() = "service" fun list() // 接口默认方法 fun defaultList(){ println(this.list()) }}// 接口继承interface BaseService: Service{}class UserService: Service { override val name: String = "user-service" override fun list() { TODO("Not yet implemented") }}// 函数式接口fun interface Consumer { fun accept(i: Int)}fun main(){ Consumer { println(it)}.accept(1)}
可见性修饰符
- private:包内可见 类成员内可见
- internal:模块内可见
- protected:类成员跟子类可见
- public:范围最大
扩展
// 一个类扩展新功能而无需继承该类或者使用像装饰者这样的设计模式// 扩展一个类的函数fun MutableList<Int>.print(){ for(i in this) { println(i) }}fun String?.topPinyin(): String { if (this == null) return "null" return toString()}// 扩展属性val String.Int: Int get() = this.toInt()fun main() { // 调用的具体方法是由函数调用所在的表达式的类型来决定的 mutableListOf(1,2,3,4).print() var s: String? = null println(s.topPinyin()) println("1".Int)}
数据类
// 会根据构造函数自动生成equals/hashCode/toString/copydata class User(val name: String, val age: Int)fun main() { val cxk = User("cxk", 18) val olderCxk = cxk.copy(age = 22) println(cxk == olderCxk) // 解构 val (name, age) = cxk println("${name},${age}")}
密封类
// 密封类的所有直接子类在编译时都是已知的sealed class NetworkError: Error()class ConnectRefusedError: NetworkError()class TimeoutError: NetworkError()
泛型
// 使用out T 来确保它仅从 成员中返回(生产),并从不被消费// in T 则相反class Wrapper<out T>(val data: T) { fun get(): T { return data } // 类型投影 fun copy(from: Wrapper<out Any>, to: Wrapper<Any>){} // 星投影 fun print(w: Wrapper<*>) {}}// 泛型函数fun <T> singleList(t: T): List<T> { return Arrays.asList(t)}// 泛型约束// 上界fun <T: Comparable<T>> sort(list: List<T>){}fun main() { // 泛型自动推导 var wrapper = Wrapper(1)}
枚举类
enum class Season(val desc: String) { SPRING("春"), SUMMER("夏"), AUTUMN("秋"), WINTER("冬"), // 匿名内部类 QUANZHOU_AUTUMN("夏秋-秋夏") {}}fun main() { for (season in Season.values()) { println("${season.name} ${season.ordinal} ${season.desc}") }}
内联类
// 内联类:引入了一种新的类型,并且都在运行时表示为基础类型// 构造器只允许一个参数 其在使用时会内被编译为其基础类型@JvmInlinevalue class Password(val raw: String)