Kotlin笔记小结(For Java Developer)

java

这篇文章为kotlin学习记录,主要针对的是自己的知识盲区,不适用于新手。

文中所有demo均来自于kotlin官网

类型

整形

TypeSize (bits)Min valueMax value
Byte8-128127
Short16-3276832767
Int32-2,147,483,648 (-231)2,147,483,647 (231 - 1)
Long64-9,223,372,036,854,775,808 (-263)9,223,372,036,854,775,807 (263 - 1)

浮点型

TypeSize (bits)Significant bitsExponent bitsDecimal digits
Float322486-7
Double64531115-16

变量

只读变量使用val,可以被重新赋值的变量使用关键字var

// example of val

val a: Int = 1 // immediate assignment

val b = 2 // `Int` type is inferred

val c: Int // Type required when no initializer is provided

c = 3 // deferred assignment

// example of var

var x = 5 // `Int` type is inferred

x += 1

函数

默认参数

fun foo(a: Int = 0, b: String = "") { ... }

函数扩展

fun String.spaceToCamelCase() { ... }

"Convert this to camelcase".spaceToCamelCase()

单行表达式函数

fun theAnswer() = 42

// 同样适用于when

fun transform(color: String): Int = when (color) {

"Red" -> 0

"Green" -> 1

"Blue" -> 2

else -> throw IllegalArgumentException("Invalid color param value")

}

Lambda表达式

匿名函数

带receiver的函数字面量

类似于函数扩展,使得你能够直接在函数体中直接返回到receiver object. 在函数体重,receiver object使用this访问到,你可以通过this来获取到reciver object中的属性和方法。

val sum: Int.(Int) -> Int = { other -> plus(other)

// 匿名函数

val sum = fun Int.(other: Int): Int = this + other

Lambda表达式

基本语法

val sum: (Int, Int) -> Int = { x: Int, y: Int -> x + y }

  • lambda 使用 {} 包围
  • 后面的为函数体
  • 如果lambda的返回值不为空(Unit),那么最后一个表达式即为返回值,上面的例子中,x + y 即为返回值

类型声明可以省略,简略写法为:

val sum = { x: Int, y: Int -> x + y }

lambda为函数的最后一个参数

如果lambda为函数的最后一个参数,那么可以直接简写在函数外面,例如

val product = items.fold(1) { acc, e -> acc * e }

// 如果lambda作为函数的最后一个参数,那么,函数()可以省略

run { println("...") }

隐式的it

如果lambda只有一个参数,那么这个参数可以不必要声明,参数会隐式被it代替

ints.filter { it > 0 } // this literal is of type '(it: Int) -> Boolean'

// 等价于

ints.filter { intVal -> intVal > 0 }

lambda返回值

默认如果lambda的返回值不为空(Unit),那么最后一个表达式即为返回值,但是也可以显示地使用return来进行值的返回,但是要遵循qualified return语法

ints.filter {

val shouldFilter = it > 0

shouldFilter

}

ints.filter {

val shouldFilter = it > 0

return@filter shouldFilter

}

跳过lambda的返回值

如果不需要使用到lambda的参数,那么可以使用_代替

map.forEach { _, value -> println("$value!") }

匿名函数

匿名函数和lambda表达式一样,都是函数字面量。

Function literals are functions that are not declared but are passed immediately as an expression.

fun(x: Int, y: Int): Int = x + y

和lambda相比,匿名函数主要有两点不同

  • 匿名函数可以指定返回类型,而lambda不同
  • 如果没有定义返回标签,lambda的返回会直接返回到最近定义了fun关键字的函数,而匿名函数会返回到函数本身

类的继承使用:,类默认是final类型的(即不可修改),如果要让类可继承,使用open关键字

open class Shape

class Rectangle(var height: Double, var length: Double): Shape() {

var perimeter = (height + length) * 2

}

DTOs(POJOs/POCOs)

data class主要用作承载数据的对象,可以用作两个系统之间数据的交换

data class Customer(val name: String, val email: String)

  • getters (and setters in case of var s) for all properties
  • equals()
  • hashCode()
  • toString()
  • copy()
  • component1(), component2() 用作数据解构

实例化一个抽象类

abstract class MyAbstractClass {

abstract fun doSomething()

abstract fun sleep()

}

fun main() {

val myObject = object : MyAbstractClass() {

override fun doSomething() {

// ...

}

override fun sleep() { // ...

}

}

myObject.doSomething()

}

匿名类

Object表达式 主要用来创建匿名类

val helloWorld = object {

val hello = "Hello"

val world = "World"

// object expressions extend Any, so `override` is required on `toString()`

override fun toString() = "$hello $world"

}

匿名内部类

匿名内部类也叫伴生类,使用关键字companion,通常的作用是为类提供静态属性和方法,类似于java的static关键字

// 一个类中只允许声明一个伴生类

// 下面的例子中,如果同时存在两个伴生类,会报类型错误

class MyClass {

// 也可以声明名字

companion object Factory {

fun create(): MyClass = MyClass()

}

// 匿名, Companion

companion object {

fun create(): MyClass = MyClass()

}

}

fun main() {

// 调用可以省略掉伴生类名

println(MyClass.create())

println(MyClass.Factory.create())

println(MyClass.Companion.create())

}

字符串模板

var a = 1

// simple name in template:

val s1 = "a is $a"

a = 2

// 如果需要计算,则使用${xxx}来表示

// arbitrary expression in template:

val s2 = "${s1.replace("is", "was")}, but now is $a"

条件判断

条件判断采用关键字if / else if / else,需要注意一点的是if也可以作为表达式使用

fun maxOf(a: Int, b: Int) = if (a > b) a else b

if-not-null-else 简写

val files = File("Test").listFiles()

println(files?.size ?: "empty") // if files is null, this prints "empty"

// To calculate the fallback value in a code block, use `run`

val filesSize = files?.size ?: run {

return someSize

}

println(filesSize)

if not null 执行 (let)

val value = ...

value?.let {

... // execute this block if not null

}

Break and continue 标签

loop@ for (i in 1..100) {

for (j in 1..100) {

if (...) break@loop

}

}

Return to 自定义标签

the return -expression returns from the nearest enclosing function

fun foo() {

listOf(1, 2, 3, 4, 5).forEach {

if (it == 3) return // non-local return directly to the caller of foo()

print(it)

}

println("this point is unreachable")

}

// To return from a lambda expression, label it and qualify the return:

fun foo() {

listOf(1, 2, 3, 4, 5).forEach lit@{

if (it == 3) return@lit // local return to the caller of the lambda - the forEach loop

print(it)

}

print(" done with explicit label")

}

// Often it is more convenient to use implicit labels

fun foo() {

listOf(1, 2, 3, 4, 5).forEach {

if (it == 3) return@forEach // local return to the caller of the lambda - the forEach loop

print(it)

}

print(" done with implicit label")

}

// Return to anonymous function

fun foo() {

listOf(1, 2, 3, 4, 5).forEach(fun(value: Int) {

if (value == 3) return // local return to the caller of the anonymous function - the forEach loop

print(value)

})

print(" done with anonymous function")

}

When(更强大的Switch)

fun describe(obj: Any): String =

when (obj) {

1 -> "One"

"Hello" -> "Greeting"

is Long -> "Long"

!is String -> "Not a string"

else -> "Unknown"

}

Ranges

使用in关键字来判断一个变量是否处在这个区间中

val x = 10

val y = 9

if (x in 1..y+1) {

println("fits in range")

}

类型检查和自动转换

fun getStringLength(obj: Any): Int? {

if (obj is String) {

// `obj` is automatically cast to `String` in this branch

return obj.length

}

// `obj` is still of type `Any` outside of the type-checked branch

return null

}

// 或者

fun getStringLength(obj: Any): Int? {

if (obj !is String) return null

// `obj` is automatically cast to `String` in this branch

return obj.length

}

不安全转换

val x: String = y as String

安全转换

val x: String? = y as? String

代理

代理使用关键字by,代表的是将原本应该自己职责代理给其他的类或者属性

类代理

interface Base {

fun printMessage()

fun printMessageLine()

}

class BaseImpl(val x: Int) : Base {

override fun printMessage() { print(x) }

override fun printMessageLine() { println(x) }

}

// 交给代理类Base去做

class Derived(b: Base) : Base by b {

// 也可以重新override

override fun printMessage() { print("abc") }

}

fun main() {

val b = BaseImpl(10)

Derived(b).printMessage()

Derived(b).printMessageLine()

}

属性代理

一个规划化的栗子

以上是 Kotlin笔记小结(For Java Developer) 的全部内容, 来源链接: utcz.com/z/394930.html

回到顶部