《Kotin 编制程序思想·实战》

《Kotin 编制程序思想·实战》


《Kotlin极简教程》正式上架:

点击那里 > 去京东商城购进阅读

点击那里 > 去天猫购买阅读


1 JVM语言家族大概浏览

1.1 编程语言简史

1.2 程序执行的三种方法

1.2.1 编写翻译执行

1.2.2 解释实施

1.2.3 虚拟机执行

1.3 JVM概述

1.3.1 Java源代码编写翻译执行进度

1.3.2 Java Class文件简介

1.3.3 JVM字节码执行进程

1.4 JVM语言家族

1.4.1 Scala

1.4.2 Groovy

1.4.3 Clojure

1.4.4 Kotlin

1.4.5 Xtend

Xtend是Eclipse推出的2个新的JVM语言,并无意替代Java,而是以己之长补Java之短,精简代码,无项目,创新可读和保证。Eclipse
Xtend能够编写翻译成可读的Java代码,类似CoffeeScript之于Javascript。

静态类型

特点

扩充方法 :抓实封闭类型的新功能。

Lambda表达式:匿名函数文字精练的语法。

将lambda表达式编写翻译成匿名内部类。

运算符重载:让库更说明。

强硬的交流机的发挥:类型与隐式类型转换开关。

八个调度:即多态方法调用。

模板表明式:智能空间处理。

报表:一切都是表明式。

属性:访问和概念getter和setter方法的速记法。

一部分类型推理:很少须要写下项目签名了。

面面俱圆资助Java的泛型:包涵拥有的一致性和转换规则。

类型系统:Xtend的静态类型是不利的,因为它同意更好的静态分析和依照类型音讯的更好的工具。可是,缺点是外加的复杂性

2 Kotlin简介

2.1 kotlin简史

2.2 急忙学习工具

2.2.1 云端IDE

2.2.2 本地命令行环境搭建

2.2.3 Kotlin REPL

2.2.4 使用IntelliJ IDEA

2.2.5 使用Gradle创设筑工程程

3 神速开端:HelloWorld

3.1 命令行的HelloWorld

3.2 应用程序版HelloWorld

3.3 Web RESTFul HelloWorld

3.4 Android版的HelloWorld

3.5 JavaScript(Canvas) 版HelloWorld

4 kotlinc编写翻译进程分析

4.1 kotlinc执行原理分析

4.2 kotlin代码执行进程

4.3 Kt.class与Java.class区别

5 语言功底

5.1 基础语法

5.1.1 包(package)

package打包与import导包

源文件能够不需求般配目录和包,源文件能够置身其余文件目录

假设没有别的包评释的话,则其中的代码都属于暗中认可包,导入时包名即为函数名!
比如:import shortToast

除此以外你还足以在导入类的时候为类设置叁个外号,比如:
import java.util.Date as d

直白在文件中写一堆fun方法!

kotlin中因为能够选取增加方法,所以能够连class和interface都不写,

5.1.2 变量

变量效用域

声称变量

val

var

val定义常量和var定义变量,暗许都以private的,比如
概念:val a =123, var b = 321,打开生成的.class文件能够看看:

private私有,且暗中认可写了国有的getter和setter方法。

5.1.3 表达式

range

return

throw

三元表明式

Lambda表达式

this表达式

super表达式

5.1.4 代码块

5.1.5 分支控制流

if表达式

判定结构(条件表明式)

Java int max = a>b?a:b

Kotlin: val max = if (a>b) a else b

在if语句块的尾声能够自行重返末了一行表明式的值,而不供给写return

fun ifExample(x: Int, y: Int) {
val result = if (x >= y) {
println(“Condition ok.”)
true
} else {
println(“Condition else.”)
false
}
println(“Result $result”)
}

when表达式

fun whenExample(userType: Int) {
when (userType) {
0 -> println(“Registered user”)
1 -> print(“Administrator”)
else -> {
println(“Unknown”)
}
}
}

fun whenExample2(userType: Int) {
when (userType) {
0, 1 -> println(“Welcome user.”)
else -> println(“Permission denied.”)
}
}

fun whenExample3(userType: Int) {
when (userType) {
filterUserType(userType) -> {
println(“Subtype ok”)
whenExample2(userType)
}
else -> print(“Subtype not ok”)
}
}

fun filterUserType(userType: Int): Int {
if (userType >= 0 && userType < 2) {
return userType;
}
return -1
}

fun whenExample4(x: Int) {
val from = 0
val to = 100
when (x) {
in from..to -> println(“PRECISE”)
in (from / 2)..(to / 2) -> print(“VERY PRECISE”)
50 -> print(“STRAIGHT IN TARGET”)
else -> print(“MISSED”)
}
}

fun whenExample5(fullName: String) {
val isJohn = when (fullName) {
is String -> fullName.startsWith(“John “)
else -> false
}
}

fun whenExample6(fullName: String) {
when {
fullName.length == 0 -> println(“Please enter your name.”)
fullName.substring(0, 2).equals(“X “) -> println(“Hello Mr. X”)
fullName.startsWith(“John “) && !fullName.endsWith(” Smith”) ->
println(“Hello John!”)
fullName.endsWith(” Smith”) -> println(“Hello agent Smith.”)
else -> println(“Only secret agents allowed!”)
}
}

5.1.6 循环

while循环

for循环

Kotlin中的while与do-while,break,continue与Java中的类似,不过Kotlin中多了个好玩的东西:
Ranages,包涵与限定关于的函数操作符

Ranages

在限制内与不在范围内

fun main(array: Array<String>) {
for ((index, value) in array.withIndex()) {
println(“[ $index ][ $value ]”)
}

val a1 = 1
val a2 = 2
val b1 = if(a1 in 0..9) true else false
val b2 = if(a2 !in 10..20 ) true else false
println(b1)
println(b2)

val str1 = "Hello"
val str2 = "Hello,Wolrd"
if(str1 in str2) println(str1 + " in " + str2) else println(str1 + " is not in " + str2)
if(str1 in "Hello".."Kotlin") println(str1 + " in " + "Hello".."Kotlin") else println(str1 + " is not in " + "Hello".."Kotlin")

}

逐二遍历

val arr = Array(10,{n->n})
arr.forEach(::print)
println()
arr.forEach{
    it->print(it.toString() + " ")
}
println()
for(e in arr) print(e)
println()
for(i in 0..arr.lastIndex) print(arr[i].toString() + " ")
println()

你也得以调lastIndex来得到最终的下标,写成if(i in 0..array.lastIndex)
如若你不想顺着遍历,想转头遍历,能够选用downTo
(递减)关键字,从最大值到最小值递减!
for(i in 9 downTo 5) print(arr[i])
println()
想必您还想隔着遍历,比如只遍历:10,7,4,1,能够用 step
(步长)关键字!前边随着的是小幅,
例如你能够写成小数0.1这么也行,示例:
for(i in 9 downTo 3 step 3) print(arr[i])

倒序遍历

5.1.7 代码注释

5.1.8 异常

Kotlin中拥有的Exception都一而再了Throwable,含有三个message且未经济检察查。
这意味着不会迫使大家在其余地点使用try/catch,而Java中若是某些方法抛出
了Exception,就必要用try-catch包围代码块。

Kotlin抛出非凡和try-catch-finally和Java中的类似!可是Kotlin中throw和try都以表达式,
意味着他们得以赋值给某些变量,这一点在拍卖边界难点的时候很有用!代码示例:

class ExceptionExamples {

fun exceptionExmple() {
    try {
        // do something ...
    } catch (e: KotlinNullPointerException) {
        // handle exception
    } finally {
        // do something ...
    }
}

// Try / Catch is expression!
fun exceptionExample2(): Int {
    return try {
        // do something
        0
    } catch (e: KotlinNullPointerException) {
        // handle exception
        -1
    }
}

}

5.2 标识符

5.2.1 修饰符

访问权限

public:暗许,总是可知

internal:同模块可知

private:证明范围与同模块的子成效域可知

protected:类似于private,但对子类也可知

5.2.2 关键保留字

var:定义变量

val:定义常量

fun:定义方法

Unit:暗中同意方法重回值,类似于Java中的void,能够通晓成归来没什么用的值

vararg:可变参数

假使是可变参数的话,能够选择 vararg 关键字修饰

fun sum(vararg args: Int) {
var sum = 0
for (x in args) {
sum += x
}
println(“Sum: $sum”)
}

fun trySum(){
sum(1, 3, 6, 10, 1, 2, 3, 4)
}

$:字符串模板(取值)

位运算符:or(按位或),and(按位与),shl(有标志左移),shr(有标志右移),

ushr(无符号右移),xor(按位异或),inv(按位取反)

in:在某些范围中

downTo:递减,循环时可用,每一回减1

step:步长,循环时可用,设置每便循环的充实或调减的量

when:Kotlin中增强版的switch,能够匹配值,范围,类型与参数

is:判断项目用,类似于Java中的instanceof()

5.2.3 运算符

5.2.4 赋值符

5.3 函数

5.3.1 main函数

5.3.2 定义函数

使用 fun 关键字来声称

假若没有访问控制符修饰的fun暗许是public final的!

返回值:Unit

壮大函数

一向定义在文书中,而不必要借助于任何的类的函数

成员函数

写在class或object中的函数

5.3.3 包级函数

5.3.4 Lambda表达式

// lambda写法1
val runnable3 = Runnable { ->
println(“I’m a Lambda”)
}

// lambda写法2
val runnable4 = { println(“I’m a Lambda”) }
Thread(runnable4).start()

函数式接口(functional interface)

只含有一个华而不实方法的接口

Java标准库中的java.lang.Runnable和java.util.Comparator

public void runThread() {
new Thread(new Runnable() {
public void run() {
System.out.println(“Run!”);
}
}).start();
}

public void runThreadUseLambda() {
new Thread(() -> {
System.out.println(“Run!”);
}).start();
}

Collections.sort(list, (x, y) -> y – x);

List input = Arrays.asList(new String[] {“apple”, “orange”,
“pear”});
input.forEach((v) -> System.out.println(v));
input.forEach(System.out::println);

5.3.5 闭包

5.3.6 匿名函数

// new 2个线程
// 匿名类写法
val runnable1 = object : Runnable{
override fun run() {
println(“I’m an anonymous class”)
}
}

// 函数写法, 略像js
val runnable2 = fun (){
println(“I’m a function”)
}

5.4 特色效益

5.4.1 函数拓展和脾性实行(Extensions)

fun main(args: Array<String>) {
val list = listOf(“1”, “2”, “3”, “4”)

// 函数拓展
list.myForEach { println(it) }

// 属性拓展
println("last: ${list.lastItem}")

}

/**

  • 展开 List 类, 加一个自定义的遍历方法
    */
    fun <T> List<T>.myForEach(doTask: (T) -> Unit){
    for(item in this)
    doTask(item)
    }

/**

  • 进展 List 类, 加八个自定义的尺寸属性
    */
    val <T> List<T>.lastItem: T
    get() = get(size – 1)

// 输出:
1
2
3
4
last: 4

class Employee {
fun name(): String {
return “Employee name”
}
}

class ExtendedFunctionalityExample(val e: Employee) {
// We extended Employee class with function that does not exist in
original class!
fun Employee.age(): Int {
return 25
}

fun tryExtendedEmployeeExample() {
    println("Name: ${e.name()}, Age: ${e.age()}")
}

}

5.4.2 属性代理

以懒加载为例,lazySum可能供给复杂的运算,我们把它代理给lazy。
能够看出,唯有首先次加载举办了计算,之后都以直接取值,进步了功能。

val lazySum: Int by lazy {
println(“begin compute lazySum …”)
var sum = 0
for (i in 0..100)
sum += i
println(“lazySum computed!\n”)
sum // 再次回到计算结果
}

fun main(args: Array<String>) {
println(lazySum)
println(lazySum)
}

// 输出:
begin compute lazySum …
lazySum computed!

5050
5050

5.4.3 委托(Delegate)

5.4.4 空指针安全

空对象检查Null Check

var mNullable: String? = null
var mNonNull: String = “mNonNull”

fun testNull(){
println(“testNull: “)
println(mNullable?.length)
println(mNonNull.length)
println()
}

// 输出:
testNull:
null
8

// java 风格,判空
if(mNullable != null)
mNullable.length

// kotlin 语法糖,判空(推荐)
mNullable?.length

null check达成原理简析

空类型强转为非空类型

var user: User? = getUser()
user!!.name = “Jack”

5.4.5 Lazy Evaluation

class UsesLazy {
val myLazyValue: String by lazy {
println(“I am initializing this lazy value!”)
“My lazy value!”
}
}

fun useLazy(){
val usesLazy: UsesLazy = UsesLazy()
val a: String = usesLazy.myLazyValue
val b: String = usesLazy.myLazyValue
val c: String = usesLazy.myLazyValue
}

6 类型系统

6.1 编译时类型与运作时类型

6.2 根类型Any

对象相等性

6.3 基本类型(Primitive Types)

6.3.1 Number: 包罗整型与浮点型等

kotlin.Byte

kotlin.Short

kotlin.Int

kotlin.Long

kotlin.Float

kotlin.Double

6.3.2 Char: 字符类型(Character)

6.3.3 Boolean: 布尔类型

6.3.4 String: 字符串类型

字符串常量

字符串函数

字符串模板

转义字符串

Kotlin居然没有自动转型

for(i in 0..arr.lastIndex) print(arr[i] + ” “)
不可能自动转型,那样写代码多麻烦

for(i in 0..arr.lastIndex) print(arr[i].toString() + ” “)

6.3.5 Array: 数组类型

原生数组类型

始建数组

定长数组:val fixedSizeArray = arrayOfNulls<Int>(10)
空数组: val empty = emptyArray<Int>()
装箱操作:val arr = arrayOf(1, 2, 3)
//还有别的诸如IntArrayOf,BooleanArrayOf等
闭包起始化:

val arr = Array(100, {num -> num})
for(i in 0..99) println(arr[i])

做客数组

使用[]

[]走访数组成分在此间实在是展开了操作符的
重载,调用的骨子里是Array类的getter和setter方法,但是编写翻译成字节码的时候会展开优化,
化为直接待上访问数组的内部存款和储蓄器地址,所以并不会造成质量损失!

遍历数组

foreach遍历

for(e in arr) println(e)

基于下标遍历

for(i in arr.indices) println(arr[i])

indices代表下标!范围:(0 <= indices < 数组size)

6.4 特殊种类

kotlin.Any

kotlin.Nothing

kotlin.Unit

kotlin.KClass<T>

6.5 可空类型(Nullable Types)

6.6 函数类型( Functional Types)

闭包类型

6.7 类型检查和测试

is运算符

as运算符

6.8 类型转换

6.9 类型别称typealias

6.10 泛型

fun <T> genericFunctionsExample(x: T){
println(“Value: $x”)
}

fun tryGenericFunctionsExampe(){
genericFunctionsExample(5)
genericFunctionsExample(“Some word!”)
genericFunctionsExample(‘c’)
genericFunctionsExample(5.55)
}

7 面向对象编制程序(OOP)

7.1 面向对象思想

7.2 类与后续

7.2.1 类

类的横向分类

抽象类

接口类

枚举类

注解类

静态类与伴生对象

sealed 密封类

sealed class SuperEnum {
class Human(val race: String) : SuperEnum()
class Animal(val specie: String, val legsCount: Int) : SuperEnum()
object Bacteria : SuperEnum()
}

fun trySuperEnum(superEnum: SuperEnum): String = when (superEnum) {
is SuperEnum.Human -> “Human ${superEnum.race}”
is SuperEnum.Animal -> “${superEnum.specie} with
${superEnum.legsCount} legs.”
is SuperEnum.Bacteria -> “Some micro organism …”
}

data 数据类

data class Person(val name: String, val age: Int){}

fun tryDataClassCopying(){
val p = Person(“John Smith”, 1985)
val p2 = p.copy()
val p3 = p.copy(age = 1990)
val p4 = p.copy(“John Doe”)

println(p)
println(p2)
println(p3)
println(p4)

}

data class Employee(val name: String, val age: Int) {}

data class Worker(val name: String = “Unknown”, val age: Int = 1970) {}

类的纵向整合

嵌套类Nested Class

内部类Inner Class

匿名内部类Inner Class

声明类

类修饰符

构造函数

主构造函数

CoffeeScript,次构造函数

类的脾气(数据结构)

类的一坐一起(算法函数)

7.2.2 接口与抽象类

接口的默许达成

interface A {
fun foo() { println(“A”) } // 暗中同意实现, 打字与印刷”A”
fun bar()
}

interface B {
fun foo() { println(“B”) }
fun bar() { println(“bar”) }
}

// 多一而再时,显式钦命 super<A>.foo() 以去抵触
class D : A, B {
override fun foo() {
super<A>.foo()
super<B>.foo()
}

override fun bar() {
    super.bar()
}

}

考虑下边包车型地铁二个简易的拓展货币转换的接口。该接口的兑现格局恐怕是调用第2方提供的劳动来成功实际的转换操作。

public interface CurrencyConverter {
BigDecimal convert(Currency from, Currency to, BigDecimal amount);
}
该接口在开发出来之后,在利用中获取了运用。在此起彼伏的版本更新中,第3方服务提供了新的批量处理的效益,允许在一次呼吁中同时转换八个数值。最直白的做法是在原有的接口中添加二个新的措施来支撑批量处理,不过如此会导致已部分代码不可能运行。而暗中认可方法则足以很好的消除那一个标题。使用私下认可方法的新接口如下所示。

public interface CurrencyConverter {
BigDecimal convert(Currency from, Currency to, BigDecimal amount);

default List convert(Currency from, Currency to, List amounts) {
    List result = new ArrayList();
        for (BigDecimal amount : amounts) {
            result.add(convert(from, to, amount));
        }
        return result;
}

}
新加上的法门运用default关键词来修饰,并能够有自个儿的方法体。

目的

接口的暗中认可方法的最首要对象之一是解决接口的嬗变难点。当往一个接口中添加新的办法时,能够提供该方法的默许达成。对于已有个别接口使用者来说,代码能够三番玖遍运转。新的代码则能够利用该措施,也得以覆写私下认可的落到实处。

贯彻行为的多继承

7.2.3 继承

open类

7.2.4 完结接口

7.2.5 函数重载

override重写覆盖父类函数

7.3 类的实例对象

新建对象

对象属性(数据结构)

对象行为(算法函数)

7.4 委托

类的委托

质量的信托

8 函数式编制程序(FP)

8.1 函数式编制程序概述

面向对象编程OOP特征

函数式编制程序FP特征

8.2 Kotlin函数式编程

8.2.1 函数是什么样

内联函数

8.2.2 函数指针

8.2.3 复合函数(高阶函数)

8.2.4 闭包(closure)

js闭包

function closureExample(objID, text, timedelay) {
setTimeout(function() {
document.getElementById(objID).innerHTML = text;
}, timedelay);
}
closureExample(‘myDiv’, ‘Closure is created’, 500);

groovy闭包

Kotlin闭包

val test = if (5 > 3) {
print(“yes”)
} else {
print(“no”)
}

fun tryClosures() {

val values = listOf<Int>(2, 4, 6, 8, 10)
var result = 0
values.forEach {
    result += it
}
println("Result: $result")

}

函数、Lambda、if语句、for、when,都得以叫做闭包

自实行闭包

自实施闭包就是在概念闭包的同时平素执行闭包,一般用来起始化上下文环境。
例如:

{ x: Int, y: Int ->
println(“${x + y}”)
}(1, 3)

总理的私自

行使闭包写代码格外灵活自由,省略了许多的一时半刻变量和参数证明。
可是,也正是因为闭包的油滑,造成一旦泛滥的话,恐怕会写出可读性相当差的代码。

8.2.5 Lambda表明式(匿名函数)

Lambda
表明式俗称匿名函数,熟知Java的大家应该也掌握那是个什么概念。Kotlin 的
Lambda表明式更“纯粹”一点, 因为它是真的把拉姆da抽象为了一种类型,而 Java
8 的 拉姆da 只是单方法匿名接口达成的语法糖罢了。

val printMsg = { msg: String ->
println(msg)
}

fun main(args: Array<String>) {
printMsg.invoke(“hello”)
}
如上是 拉姆da 表明式最简易的实例。

首先评释了四个名为 printMsg 的 Lambda,它承受3个 String
类型的值作为参数,然后在 main
函数中调用它。如果还想大约,你还足以在调用时间接省略invoke,像函数一样使用。

fun main(args: Array<String>) {
printMsg(“hello”)
}

拉姆da 表明式作为高阶函数的参数字传送递

fun main(args: Array<String>) {
log(“world”, printMsg)
}

val printMsg = { str: String ->
println(str)
}

val log = { str: String, printLog: (String) -> Unit ->
printLog(str)
}
以此事例中,log 是二个经受1个 String 和1个以 String 为参数并赶回 Unit
的 拉姆da 说明式为参数的 拉姆da 表明式。

8.2.6 内联函数(inline)

动用 高阶函数 在运维时会带来一些不利于: 每种函数都以3个对象,
而且它还要捕获3个闭包, 也正是, 在函 数体内部访问的那一个外层变量.
内部存款和储蓄器占用(函数对象和类都会占据内部存储器) 以及虚方法调用都会带来运转时的消耗.

不过也不是说富有的函数都要内联,因为即使添加了 inline
修饰,在编写翻译阶段,编写翻译器将会把函数拆分,插入到调用出。要是一个 inline
函数是十分的大的,那她会急剧增多调用它的那几个函数的体量。

infix fun Double.powerPI(x: Int): Double {
return Math.pow(this, x + Math.PI)
}

fun infixExample() {
val array = arrayOf(2.0, 4.0, 6.0, 8.0, 10.0)
for (value in array) {
val result = value powerPI 5
println(“Result: [ $value ][ $result ]”)
}
}

8.2.7 本地函数(Local Functions)

fun worker() {
fun doWork(work: String) {
println(“Working [ $work ]”)
}

doWork("Importing user data")
doWork("Processing user data")
doWork("Exporting user data")

}

8.2.8 命名参数(NamedParameters)

fun addEmployee(name: String, year: Int, address: String) {
}

// Let’s call method:
fun namedParametersExaple() {
addEmployee(
name = “John Smith”,
year = 1985,
address = “Avenue 666”
)
}

8.2.9 外部函数external

8.2.10 尾递归tailrec

tailrec fun tailRecursiveExample(word: String) {
if (word.length == 1) {
println(“— end”)
} else {
println(word)
tailRecursiveExample(word.substring(0..(word.length – 2)))
}
}

fun tryTailRecursiveExample() {
tailRecursiveExample(“My word”)
}

8.3 函数式Stream API

8.3.1 filter函数

8.3.2 map函数

fun main(args: Array<String>){
val list = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
list.filter { it%2==0 } // 取偶数
.map{ it*it } // 平方
.sortedDescending() // 降序排序
.take(3) // 取前 3 个
.forEach { println(it) } // 遍历, 打印
}

8.3.3 forEach

9 Kotlin与Java互操作(Interoperability)

9.1 使用工具相互转换

9.1.1 将 Java 转换为 Kotlin

9.1.2 将 Kotlin 转换为 Java

9.1.3 用 Kotlin 包容 Java
的做法,本来正是权宜之计,包容必然带来新旧三种价值观的争辨以及丑陋的发出

9.2 Kotlin与Java互操作

9.2.1 Kotlin无缝调用第壹方jar库

9.2.2 执行shell

9.2.3 文件操作

9.2.4 三十二线程代码

9.3 Kotlin与Java的区别

9.3.1 void 与 Unit

9.3.2 反射获取类的 Class

9.3.3 Java 与 Kotlin 关键字争持的处理

9.3.4 static 方法与伴生对象companion object

9.3.5 包级别函数

9.3.6 重载必须使用override

10 集合类与泛型

10.1 kotlin.collections

10.1.1 不可变集合类

List

// Gives us read only list
fun getList(): List<Int> {
return listOf(1, 3, 5, 7)
}

// Gives us read only map
fun getMap(): Map<String, Double> {
return mapOf(“EUR” to 123.20, “USD” to 110.34, “CHF” to 111.4)
}

fun printMap(key: String) {
val map = getMap()
if (key in map) println(map[key]) else println(“There is no such key
$key”)
}

Set

Map

fun traverseMapExample(map: Map<String, Int>) {
for ((key, value) in map) println(“$key : $value”)
}

10.1.2 可变集合类

kotlin.collections.MutableCollection<E>

MutableList<E>

MutableSet<E>

MutableMap<K, V>

10.2 泛型与类型安全

10.2.1 类型参数

10.2.2 类型估算

10.2.3 协变与逆变

10.3 类型上下界

11 轻量级线程:协程(Coroutines)

11.1 协程概念

val fibonacci = buildSequence {
yield(1) // first Fibonacci number
var cur = 1
var next = 1
while (true) {
yield(next) // next Fibonacci number
val tmp = cur + next
cur = next
next = tmp
}
}

for (i in fibonacci){
println(i)
if(i > 100) break //大于100就告一段落循环
}

用接近同步的代码做着异步的事情

11.2 协程的基本操作

11.2.1 创建

11.2.2 启动

11.2.3 暂停

11.2.4 继续

11.3 竞争规则

11.4 同步

11.5 完成异步

12 使用Kotlin开发Web应用

12.1 Kotlin集成Spring Boot开发Web应用

12.1.1 Spring Boot简介

12.1.2 Kotlin集成Spring Boot

12.2 Spring 5 对 Kotlin的支持

12.2.1 Functional bean registration with Kotlin

Spring Framework 5.0 introduces a new way to register beans using lambda
as an alternative to XML or JavaConfig with @Configuration and @Bean. In
a nutshell, it makes it possible to register beans with a Supplier
lambda that acts as a FactoryBean.

In Java you will for example write:

GenericApplicationContext context = new GenericApplicationContext();
context.registerBean(Foo.class);
context.registerBean(Bar.class, () -> new
Bar(context.getBean(Foo.class))
);
While in Kotlin, reified type parameters allow us to simply write:

val context = GenericApplicationContext {
registerBean<Foo>()
registerBean { Bar(it.getBean<Foo>()) }
}

12.2.2 使用Kotlin的函数式风格API开发 Web应用

Spring Framework 5.0 comes with a Kotlin routing DSL that allows you to
leverage the Spring Functional Web API recently announced with clean and
idiomatic Kotlin code:

{
(“/blog” and accept(TEXT_HTML)).route {
GET(“/”, this@BlogController::findAllView)
GET(“/{slug}”, this@BlogController::findOneView)
}
(“/api/blog” and accept(APPLICATION_JSON)).route {
GET(“/”, this@BlogController::findAll)
GET(“/{id}”, this@BlogController::findOne)
}
}

https://github.com/EasyKotlin/mixit

12.2.3 Kotlin Script based templates

ScriptTemplateView to render templates

This could allow you to write this kind of templates with full
autocompletion and refactoring support in your IDE:

import io.spring.demo.*

“””
${include(“header”)}
<h1>${i18n(“title”)}</h1>
<ul>
${users.joinToLine{ “<li>${i18n(“user”)} ${it.firstname}
${it.lastname}</li>” }}
</ul>
${include(“footer”)}
“””

https://github.com/EasyKotlin/kotlin-script-templating

12.3 使用Kotlin的Web框架Ktor开发Web应用

Ktor is a framework for quickly creating web applications in Kotlin with
minimal effort.

import org.jetbrains.ktor.netty.*
import org.jetbrains.ktor.routing.*
import org.jetbrains.ktor.application.*
import org.jetbrains.ktor.host.*
import org.jetbrains.ktor.http.*
import org.jetbrains.ktor.response.*

fun main(args: Array<String>) {
embeddedServer(Netty, 8080) {
routing {
get(“/”) {
call.respondText(“Hello, world!”, ContentType.Text.Html)
}
}
}.start(wait = true)
}

https://github.com/Kotlin/ktor/wiki

12.4 基于Kotlin Script的模板引擎

13 使用Kotlin实现DSL

13.1 DSL

13.2 Groovy的DSL语法

13.3 Kotlin使用闭包创设 DSL

14使用Kotlin开 发JavaScript代码

14.1 Kotlin代码编写翻译成js进度

14.2 使用Kotlin开发JavaScript代码

15 使用Kotlin开发Android程序

https://github.com/Kotlin/anko

class MyActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?, persistentState:
PersistableBundle?) {
super.onCreate(savedInstanceState, persistentState)
MyActivityUI().setContentView(this)
}
}

class MyActivityUI : AnkoComponent<MyActivity> {
override fun createView(ui: AnkoContext<MyActivity>) = ui.apply
{
verticalLayout {
editText()
button(“Say Hello”) {
onClick { ctx.toast(“Hello!”) }
}
}
}.view
}

16 使用Kotlin Native开发原生应用

17 KOTLIN语言生态

17.1 测试(Testing)

17.2 重视注入(Dependency Injection)

17.3 JSON序列化(JSON serialization)

17.4 Web 框架

17.5 数据库访问(Database access)

17.6 工具类(Utilities)

17.7 桌面编制程序(Desktop programming)

17.8 Http库

Fuel:
https://github.com/EasyKotlin/Fuel

//an extension over string (support GET, PUT, POST, DELETE with
httpGet(), httpPut(), httpPost(), httpDelete())
http://httpbin.org/get“.httpGet().responseString
{ request, response, result ->
//do something with response
when (result) {
is Result.Failure -> {
error = result.getAs()
}
is Result.Success -> {
data = result.getAs()
}
}
}

//if we set baseURL beforehand, simply use relativePath
FuelManager.instance.basePath =
http://httpbin.org
“/get”.httpGet().responseString { request, response, result ->
//make a GET to
http://httpbin.org/get
and do something with response
val (data, error) = result
if (error != null) {
//do something when success
} else {
//error handling
}
}

//if you prefer this a little longer way, you can always do
//get
Fuel.get(“http://httpbin.org/get“).responseString
{ request, response, result ->
//do something with response
result.fold({ d ->
//do something with data
}, { err ->
//do something with error
})
}

val (request, response, result) =
http://httpbin.org/get“.httpGet().responseString()
// result is Result<String, FuelError>

17.9 并发库kotlinx.coroutines

kotlinx.coroutines:https://github.com/EasyKotlin/kotlinx.coroutines

https://github.com/EasyKotlin/kotlinx.coroutines/blob/master/coroutines-guide.md

fun main(args: Array<String>) {
launch(CommonPool) { // create new coroutine in common thread pool
delay(1000L) // non-blocking delay for 1 second (default time unit is
ms)
println(“World!”) // print after delay
}
println(“Hello,”) // main function continues while coroutine is
delayed
Thread.sleep(2000L) // block main thread for 2 seconds to keep JVM
alive
}

Run this code:

Hello,
World!

18 附录 参考资料

https://github.com/EasyKotlin/kotlin-in-action

Awesome Kotlin:
https://kotlin.link/

Kotlin项目Github源码:https://github.com/JetBrains/kotlin

Kotlin语言规范:http://jetbrains.github.io/kotlin-spec/

在线体验学习Kotlin语言:https://try.kotlinlang.org

官网文书档案:http://kotlinlang.org/docs/

https://github.com/trending?l=kotlin

https://github.com/EasyKotlin/Kotlin-for-Android-Developers

https://github.com/EasyKotlin/Bandhook-Kotlin

https://spring.io/blog/2017/01/04/introducing-kotlin-support-in-spring-framework-5-0

xtend:
http://www.eclipse.org/xtend/documentation/index.html