From 5450ec58845c8f7c047af6a628bfd74b3512a9ed Mon Sep 17 00:00:00 2001 From: Bennyhuo Date: Tue, 13 Mar 2018 14:59:36 +0800 Subject: [PATCH 01/60] Update README.md --- README.md | 35 ++++------------------------------- 1 file changed, 4 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index d97c44e..a9a36b1 100644 --- a/README.md +++ b/README.md @@ -2,46 +2,19 @@ # [Kotlin 系统入门到进阶 视频教程](http://coding.imooc.com/class/108.html) -这是什么?这是我最新制作的系统讲解 Kotlin 的视频教程,相比较早录制的视频,这套视频在专业团队的协助下完成,内容更适合初学者入门学习;另外,由于 Kotlin 版本更新非常快,新视频也结合了 1.1 的新特性为大家展开讲解,希望能对大家有帮助~ +这是什么?这是我最新制作的系统讲解 Kotlin 的视频教程,相比较早录制的视频,这套视频在专业团队的协助下完成,内容更适合初学者入门学习;另外,由于 Kotlin 版本更新非常快,新视频也结合了 1.1/1.2 的新特性为大家展开讲解,希望能对大家有帮助~ **视频地址:** [http://coding.imooc.com/class/108.html](http://coding.imooc.com/class/108.html) -## 第1章 课程介绍 +> 已经更新了 **反射** **泛型** **跨平台** 的内容。 -本章主要介绍什么是Kotlin,课程安排,以及开发环境的配置。 - -## 第2章 数据类型 - -本章主要讲解 Kotlin 的基本词法,从类型系统入手为大家介绍 Kotlin 中都存在哪些类型,以及相关的特性。(知识点:基本类型、类与对象、空类型、智能类型转换、包、区间、数组) - -## 第3章 程序结构 -本章主要讲解 Kotlin 的句法,从程序结构入手为大家介绍 Kotlin 有哪些表达式,有哪些语句,如何定义常量、变量以及函数等等。(知识点:常量与变量 、函数、Lambda表达式、类成员、运算符、分支表达式、循环语句、异常捕获 、函数的具名参数、函数的变长参数、函数的默认参数、案例:一个命令行计算器、导出可执行程... - -## 第4章 面向对象 -本章深入探讨 Kotlin 的面向对象的知识,包括抽象、继承,扩展成员、属性代理以及常见类的概念及特性。(知识点:面向对象的基本概念、抽象类与接口、 子承父业的故事、类及其成员的可见性、object、伴生对象与静态成员、方法重载和默认参数、扩展成员、属性代理、数据类、内部类、枚举、密封类)... - -## 第5章 高阶函数 -本章深入探讨 Kotlin 的高阶函数的知识,学习常见的内置高阶函数的用法,并对常见高阶函数的相关概念如闭包、复合、科里化等做简要介绍。(知识点:基本概念、常见高阶函数、尾递归优化、闭包、函数复合、科里化 Currying、 偏函数、一个统计字符个数的小例子)... - -## 第6章 领域特定语言 DSL -本章介绍领域特定语言 DSL 的概念,以及如何使用 Kotlin 编写 DSL。(知识点:DSL 的基本概念、案例:HTML DSL、Gradle Kotlin 脚本) - -## 第7章 协程 Coroutine -本章介绍 Kotlin 的协程,主要包括基本 API 的使用,协程执行流程的分析,以及协程相关应用的案例和框架介绍。(知识点:基本概念、案例:异步下载图片、 协程的原理剖析、序列生成器、Kotlinx.coroutines框架简介) - -## 第8章 Kotlin与 Java 混合开发 -本章主要对 Kotlin 与 Java 混合开发常见的问题进行了梳理。(知识点:基本互操作、SAM转换、正则表达式、集合框架、IO操作、装箱和拆箱、注解处理器) - -## 第9章 Kotlin的应用与展望 -本章主要为大家演示如何编写 Kotlin 脚本,如何开发服务端程序, 如何开发 Android 应用,如何开发前端程序,以及如何使用 Kotlin-Native 将 Kotlin 直接编译为可执行程序并在操作系统上直接运行。(知识点:Kotlin的应用场景、 Kotlin-Script的例子、Kotlin-Android的例子、Kotlin-JavaScript的例子、 Kotlin-springboot的例子、Kotlin-Native 的例子) - -# [<已过时>Kotlin从入门到『放弃』系列 视频教程](https://github.com/enbandari/Kotlin-Tutorials) +# [Kotlin从入门到『放弃』系列 视频教程](https://github.com/enbandari/Kotlin-Tutorials) **发现有人在淘宝店上卖这套视频哈,大家不要去买。。。直接在这里下载多好** 随着Kotlin越来越成熟稳定,我已经开始在生产环境中使用它。考虑到目前国内资料较少,我录制了一套视频教程,希望以此抛砖引玉,让 Kotlin 在国内火起来。 -个人水平有限,不足之处欢迎大家发邮件到 [bennyhuo@println.net](mailto: bennyhuo@println.net),谢谢大家! +个人水平有限,不足之处欢迎大家发邮件到 [bennyhuo@println.net](mailto: bennyhuo@println.net) ,谢谢大家! # 介绍 From 87245766241beb66af1dbc15dda47e1a0aa09693 Mon Sep 17 00:00:00 2001 From: Bennyhuo Date: Tue, 13 Mar 2018 15:03:01 +0800 Subject: [PATCH 02/60] =?UTF-8?q?Update=20=E6=B7=B1=E5=85=A5=E7=90=86?= =?UTF-8?q?=E8=A7=A3=20Kotlin=20coroutine=20(=E4=BA=8C=EF=BC=89.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修改错别字 --- ...6\350\247\243 Kotlin coroutine (\344\272\214\357\274\211.md" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/articles/2017.2.6/\346\267\261\345\205\245\347\220\206\350\247\243 Kotlin coroutine (\344\272\214\357\274\211.md" "b/articles/2017.2.6/\346\267\261\345\205\245\347\220\206\350\247\243 Kotlin coroutine (\344\272\214\357\274\211.md" index 3f5dd5c..a66635b 100644 --- "a/articles/2017.2.6/\346\267\261\345\205\245\347\220\206\350\247\243 Kotlin coroutine (\344\272\214\357\274\211.md" +++ "b/articles/2017.2.6/\346\267\261\345\205\245\347\220\206\350\247\243 Kotlin coroutine (\344\272\214\357\274\211.md" @@ -290,7 +290,7 @@ isActive 会在 cancel 之后被置为 false。 ## 6. 携带值的 Job -我们前面说了,通过携程返回的 Job,我们可以控制携程的运行。可有时候我们更关注协程运行的结果,比如从网络加载一张图片: +我们前面说了,通过协程返回的 Job,我们可以控制协程的运行。可有时候我们更关注协程运行的结果,比如从网络加载一张图片: ```kotlin suspend fun loadImage(url: String): Bitmap { From d5a487298d55197329acaa2bbfcdd922555457c6 Mon Sep 17 00:00:00 2001 From: Bennyhuo Date: Wed, 13 Jun 2018 06:48:27 +0800 Subject: [PATCH 03/60] Update README.md --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index a9a36b1..cae649b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,10 @@ [![GitHub license](https://img.shields.io/badge/license-CC%20BY--NC--ND%204.0-blue.svg)](https://creativecommons.org/licenses/by-nc-nd/4.0/) +# [基于 GitHub App 业务深度讲解 Kotlin1.2高级特性与框架设计](https://coding.imooc.com/class/232.html) + +我们在 2018年6月基于 Android 的开发环境推出了一套深入讲解 Kotlin 特性的课程,这套课程以大家最为熟悉的 GitHub App 开发作为整套课程的线索,将 Kotlin 的高级特性一一融入其中予以讲解,这其中我们对泛型、反射、属性代理、协程、Dsl 做了详尽的讲解和框架设计与开发,力求让大家能够对这些技能灵活运用。 + + # [Kotlin 系统入门到进阶 视频教程](http://coding.imooc.com/class/108.html) 这是什么?这是我最新制作的系统讲解 Kotlin 的视频教程,相比较早录制的视频,这套视频在专业团队的协助下完成,内容更适合初学者入门学习;另外,由于 Kotlin 版本更新非常快,新视频也结合了 1.1/1.2 的新特性为大家展开讲解,希望能对大家有帮助~ From 782ca99e7112aad10bf53c442fa4b7ad03938b0d Mon Sep 17 00:00:00 2001 From: Bennyhuo Date: Mon, 8 Oct 2018 07:26:12 +0800 Subject: [PATCH 04/60] Update README.md --- README.md | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index cae649b..a7968a6 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,11 @@ [![GitHub license](https://img.shields.io/badge/license-CC%20BY--NC--ND%204.0-blue.svg)](https://creativecommons.org/licenses/by-nc-nd/4.0/) +# [注解处理器开发教程](https://github.com/enbandari/Apt-Tutorials) + +我在做 [基于 GitHub App 业务深度讲解 Kotlin1.2高级特性与框架设计](https://coding.imooc.com/class/232.html) 这门课的时候,顺便做了一个注解处理器的框架,叫 [Tieguanyin(铁观音)](https://github.com/enbandari/TieGuanYin),这个框架主要是用来解决 Activity 跳转时传参的问题,我们知道 Activity 如果需要参数,那么我们只能非常繁琐的使用 `Intent` 来传递,有了这个框架我们就可以省去这个麻烦的步骤。 + +在这里,框架的内容其实不是重点,重点是,它是一个注解处理器的项目。为了让它的作用尽可能的放大,我对原框架做了简化,做了这套课程。 + # [基于 GitHub App 业务深度讲解 Kotlin1.2高级特性与框架设计](https://coding.imooc.com/class/232.html) 我们在 2018年6月基于 Android 的开发环境推出了一套深入讲解 Kotlin 特性的课程,这套课程以大家最为熟悉的 GitHub App 开发作为整套课程的线索,将 Kotlin 的高级特性一一融入其中予以讲解,这其中我们对泛型、反射、属性代理、协程、Dsl 做了详尽的讲解和框架设计与开发,力求让大家能够对这些技能灵活运用。 @@ -29,14 +35,6 @@ [下载全部视频(百度云)](http://pan.baidu.com/s/1nvGYAfB) -关注微信公众号:Kotlin, 获取最新视频更新动态 - - - -加入 QQ 群 Kotlin ,162452394: - - - # 目录 #### [01 Kotlin 简介](http://v.qq.com/page/z/u/9/z0337i7a3u9.html) @@ -152,9 +150,13 @@   除了视频中提到的点之外还有一些细节,比如异常的捕获,集合类型的映射等等,大家自行参考官方文档即可。在了解了这些之后,你就可以放心大胆的在你的项目中慢慢渗透 Kotlin,让你的代码逐渐走向简洁与精致了。 -# 打赏 +# 获取最新动态 + +关注微信公众号:Kotlin, 获取最新视频更新动态 + + -录制这样一套视频确实是需要花费时间和心血的,如果您觉得它对您有帮助,可以通过微信和支付宝打赏,我将努力将视频做到最好!谢谢! +加入 QQ 群 Kotlin ,162452394: - + From a0cd1cf5fe9dc5f912beef24c0c53c6614c9157a Mon Sep 17 00:00:00 2001 From: Bennyhuo Date: Sat, 9 Mar 2019 08:08:01 +0800 Subject: [PATCH 05/60] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index a7968a6..10f7794 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,9 @@ [![GitHub license](https://img.shields.io/badge/license-CC%20BY--NC--ND%204.0-blue.svg)](https://creativecommons.org/licenses/by-nc-nd/4.0/) +# [破解Android高级面试](https://coding.imooc.com/class/317.html) + +我一直做 Kotlin 的推广和宣传,发现大多数学习 Kotlin 的同学都是被行业“胁迫”不得不学。大家的诉求更多是怎么样找到一份好的工作,考虑到学习 Kotlin 的同学大多都是 Android 开发者,我就花了半年的功夫仔细整理了这一套视频出来,题目看上去不多,但每一个题目背后能引出的知识点可一点儿都不少。不求面面俱到,只求精准打击,面试过程中只要你能给面试官留下深刻的印象,那么这事儿就成了。 + # [注解处理器开发教程](https://github.com/enbandari/Apt-Tutorials) 我在做 [基于 GitHub App 业务深度讲解 Kotlin1.2高级特性与框架设计](https://coding.imooc.com/class/232.html) 这门课的时候,顺便做了一个注解处理器的框架,叫 [Tieguanyin(铁观音)](https://github.com/enbandari/TieGuanYin),这个框架主要是用来解决 Activity 跳转时传参的问题,我们知道 Activity 如果需要参数,那么我们只能非常繁琐的使用 `Intent` 来传递,有了这个框架我们就可以省去这个麻烦的步骤。 From ef5abad35a7e8a992718f7dad3a0df75ea05d7ac Mon Sep 17 00:00:00 2001 From: Bennyhuo Date: Sat, 9 Mar 2019 09:02:01 +0800 Subject: [PATCH 06/60] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 10f7794..fec321b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ [![GitHub license](https://img.shields.io/badge/license-CC%20BY--NC--ND%204.0-blue.svg)](https://creativecommons.org/licenses/by-nc-nd/4.0/) -# [破解Android高级面试](https://coding.imooc.com/class/317.html) +# [破解Android高级面试](https://s.imooc.com/SBS30PR) 我一直做 Kotlin 的推广和宣传,发现大多数学习 Kotlin 的同学都是被行业“胁迫”不得不学。大家的诉求更多是怎么样找到一份好的工作,考虑到学习 Kotlin 的同学大多都是 Android 开发者,我就花了半年的功夫仔细整理了这一套视频出来,题目看上去不多,但每一个题目背后能引出的知识点可一点儿都不少。不求面面俱到,只求精准打击,面试过程中只要你能给面试官留下深刻的印象,那么这事儿就成了。 From bbc296f2c7fbf7b066711c7a021f9693bdb64238 Mon Sep 17 00:00:00 2001 From: Bennyhuo Date: Mon, 13 May 2019 19:39:54 +0800 Subject: [PATCH 07/60] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index fec321b..a2d2a8e 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,9 @@ [![GitHub license](https://img.shields.io/badge/license-CC%20BY--NC--ND%204.0-blue.svg)](https://creativecommons.org/licenses/by-nc-nd/4.0/) +# [破解 Retrofit](https://www.imooc.com/learn/1128?mc_marking=5487b137ad904bd13590a053ede6da2f&mc_channel=syb19) + +最近不少朋友反馈希望能看到一些深入分析框架的课程,正好前段时间对 Retrofit 又做了一次深入的分析,整理了一套免费视频分享给大家~ + # [破解Android高级面试](https://s.imooc.com/SBS30PR) 我一直做 Kotlin 的推广和宣传,发现大多数学习 Kotlin 的同学都是被行业“胁迫”不得不学。大家的诉求更多是怎么样找到一份好的工作,考虑到学习 Kotlin 的同学大多都是 Android 开发者,我就花了半年的功夫仔细整理了这一套视频出来,题目看上去不多,但每一个题目背后能引出的知识点可一点儿都不少。不求面面俱到,只求精准打击,面试过程中只要你能给面试官留下深刻的印象,那么这事儿就成了。 From c9d4e10e10a7d3c1acc28f076af8cc7d91d071e9 Mon Sep 17 00:00:00 2001 From: Bennyhuo Date: Fri, 14 Jun 2019 10:17:14 +0800 Subject: [PATCH 08/60] Update README.md --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index a2d2a8e..a3e2087 100644 --- a/README.md +++ b/README.md @@ -164,7 +164,5 @@ -加入 QQ 群 Kotlin ,162452394: - - +大群已满~ 加入新 QQ 群 Kotlin 中文社区① 603441485 From 172826ec535b911d17c4381a20862920dee5417b Mon Sep 17 00:00:00 2001 From: Bennyhuo Date: Mon, 25 Nov 2019 14:42:00 +0800 Subject: [PATCH 09/60] Update README.md --- README.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index a3e2087..e513969 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,12 @@ [![GitHub license](https://img.shields.io/badge/license-CC%20BY--NC--ND%204.0-blue.svg)](https://creativecommons.org/licenses/by-nc-nd/4.0/) +# [Kotlin 从入门到精通 视频教程](http://coding.imooc.com/class/398.html) + +Kotlin 1.3 是一个相对成熟和稳定的版本,这次基于 Kotlin 1.3.50 重新制作入门到精通的课程,相比之下新课知识点梳理更详细,内容干货更多,讲法也更成熟,希望能对大家有帮助。 + +**视频地址:** [http://coding.imooc.com/class/398.html](http://coding.imooc.com/class/398.html) + + # [破解 Retrofit](https://www.imooc.com/learn/1128?mc_marking=5487b137ad904bd13590a053ede6da2f&mc_channel=syb19) 最近不少朋友反馈希望能看到一些深入分析框架的课程,正好前段时间对 Retrofit 又做了一次深入的分析,整理了一套免费视频分享给大家~ @@ -19,14 +26,6 @@ 我们在 2018年6月基于 Android 的开发环境推出了一套深入讲解 Kotlin 特性的课程,这套课程以大家最为熟悉的 GitHub App 开发作为整套课程的线索,将 Kotlin 的高级特性一一融入其中予以讲解,这其中我们对泛型、反射、属性代理、协程、Dsl 做了详尽的讲解和框架设计与开发,力求让大家能够对这些技能灵活运用。 -# [Kotlin 系统入门到进阶 视频教程](http://coding.imooc.com/class/108.html) - -这是什么?这是我最新制作的系统讲解 Kotlin 的视频教程,相比较早录制的视频,这套视频在专业团队的协助下完成,内容更适合初学者入门学习;另外,由于 Kotlin 版本更新非常快,新视频也结合了 1.1/1.2 的新特性为大家展开讲解,希望能对大家有帮助~ - -**视频地址:** [http://coding.imooc.com/class/108.html](http://coding.imooc.com/class/108.html) - -> 已经更新了 **反射** **泛型** **跨平台** 的内容。 - # [Kotlin从入门到『放弃』系列 视频教程](https://github.com/enbandari/Kotlin-Tutorials) **发现有人在淘宝店上卖这套视频哈,大家不要去买。。。直接在这里下载多好** From 2f4d2c71dada5bced02823c6926706d5cd1bda79 Mon Sep 17 00:00:00 2001 From: Bennyhuo Date: Fri, 19 Jun 2020 17:32:31 +0800 Subject: [PATCH 10/60] Update README.md --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index e513969..1c20a8b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,18 @@ [![GitHub license](https://img.shields.io/badge/license-CC%20BY--NC--ND%204.0-blue.svg)](https://creativecommons.org/licenses/by-nc-nd/4.0/) +# [新书《深入理解 Kotlin 协程》](https://www.bennyhuo.com/project/kotlin-coroutines.html) + +Kotlin 协程可以说是截止目前为止 Kotlin 中最让人困惑的一部分内容了,官方文档也比较简略,对于初学者不够友好。今年我把过去在公众号和博客发布的协程相关的文章进行了整理和扩充,进一步完善了诸多细节编写了本书,有兴趣可以留意一下。 + +## 随书源码 + +本书**源码地址**:[《深入理解 Kotlin 协程》源码](https://github.com/enbandari/DiveIntoKotlinCoroutines-Sources) + +## 购买途径 + +* 京东自营:[深入理解Kotlin协程](https://item.jd.com/12898592.html) +* 当当自营:[深入理解Kotlin协程](http://product.dangdang.com/28973005.html) + # [Kotlin 从入门到精通 视频教程](http://coding.imooc.com/class/398.html) Kotlin 1.3 是一个相对成熟和稳定的版本,这次基于 Kotlin 1.3.50 重新制作入门到精通的课程,相比之下新课知识点梳理更详细,内容干货更多,讲法也更成熟,希望能对大家有帮助。 From 1f36dad97db0e078245aff7b4afba6a458809f1b Mon Sep 17 00:00:00 2001 From: Bennyhuo Date: Sat, 23 Jan 2021 08:57:17 +0800 Subject: [PATCH 11/60] Update README.md A new idea. --- README.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/README.md b/README.md index 1c20a8b..bba245a 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,29 @@ [![GitHub license](https://img.shields.io/badge/license-CC%20BY--NC--ND%204.0-blue.svg)](https://creativecommons.org/licenses/by-nc-nd/4.0/) +# 2021 新计划 + +准备做一个长期的 Kotlin 基础教程的编撰工作,作为官方文档的补充,大家有想法欢迎开 issue 跟我一起讨论。 + +### 内容目标(暂定): + +1. 主线内容涵盖 Kotlin common、Kotlin Jvm、Kotlin js、Kotlin Native,通用部分则不依赖 Kotlin Jvm(不像过去大家习惯的方式) +2. Kotlin 的常见库的使用方法 +3. 编译器配置、Gradle DSL 等等 + +### 输出形式: + +1. GitBook(主要目标,配合官网) +2. 纸质书(不排除可能性) + +### 时间安排 + +1. 大纲梳理,整体初步构思 - 2021.4 之前 +2. 基础部分 - 待细化 +3. Jvm 部分 +4. Js 部分 +5. Native 部分 +6. 框架部分(ktor、datetime、serialization...) + # [新书《深入理解 Kotlin 协程》](https://www.bennyhuo.com/project/kotlin-coroutines.html) Kotlin 协程可以说是截止目前为止 Kotlin 中最让人困惑的一部分内容了,官方文档也比较简略,对于初学者不够友好。今年我把过去在公众号和博客发布的协程相关的文章进行了整理和扩充,进一步完善了诸多细节编写了本书,有兴趣可以留意一下。 From b1bd9474261b3c42cddd7453ba3809e248e9a941 Mon Sep 17 00:00:00 2001 From: Bennyhuo Date: Sat, 17 Apr 2021 12:11:59 +0800 Subject: [PATCH 12/60] Update README.md --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index bba245a..98f6532 100644 --- a/README.md +++ b/README.md @@ -200,5 +200,10 @@ Kotlin 1.3 是一个相对成熟和稳定的版本,这次基于 Kotlin 1.3.50 -大群已满~ 加入新 QQ 群 Kotlin 中文社区① 603441485 +大群已满~ + +加入新 QQ 群 +Kotlin 中文社区群 大群:162452394 (已满) +Kotlin 中文社区群 ① 群:603441485 (已满) +Kotlin 中文社区群 ② 群:751395597 From f049ae279a8ea4e2f3d72551072591991fce6761 Mon Sep 17 00:00:00 2001 From: Bennyhuo Date: Sat, 17 Apr 2021 12:12:26 +0800 Subject: [PATCH 13/60] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 98f6532..47ffe2f 100644 --- a/README.md +++ b/README.md @@ -203,7 +203,10 @@ Kotlin 1.3 是一个相对成熟和稳定的版本,这次基于 Kotlin 1.3.50 大群已满~ 加入新 QQ 群 + Kotlin 中文社区群 大群:162452394 (已满) + Kotlin 中文社区群 ① 群:603441485 (已满) + Kotlin 中文社区群 ② 群:751395597 From 7cb632509b7f6c8b125c16b11ef8aa8aac46d5c2 Mon Sep 17 00:00:00 2001 From: Bennyhuo Date: Sat, 17 Apr 2021 12:12:57 +0800 Subject: [PATCH 14/60] Update README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 47ffe2f..837f25a 100644 --- a/README.md +++ b/README.md @@ -200,9 +200,8 @@ Kotlin 1.3 是一个相对成熟和稳定的版本,这次基于 Kotlin 1.3.50 -大群已满~ -加入新 QQ 群 +加入社区 QQ 群: Kotlin 中文社区群 大群:162452394 (已满) From d2174e5383b88e0867260b25878166131e51c7c6 Mon Sep 17 00:00:00 2001 From: bennyhuo Date: Sat, 5 Jun 2021 11:49:20 +0800 Subject: [PATCH 15/60] update file structure, add information about the new plan. --- README.md | 219 ++++-------------- docs/Dive-into-Kotlin-Coroutines.md | 0 docs/Tutorials-IMOOC.md | 0 legacy/README.md | 128 ++++++++++ ...32\347\273\247\346\211\277\343\200\217.md" | 0 {articles => legacy/articles}/2016.12.26.jpg | Bin .../articles}/2017.1.16/cover.jpg | Bin ...10\347\256\200\345\215\225\357\274\237.md" | 0 .../articles}/2017.1.2/17.1.2.jpg | Bin .../articles}/2017.1.2/17.1.2b.jpg | Bin .../articles}/2017.1.2/Kotlin 1.0.6.md | 0 .../articles}/2017.1.2/args.gif | Bin .../articles}/2017.1.2/try.gif | Bin ...240\267\344\275\277\347\224\250 Kotlin.md" | 0 .../2017.1.21/1.1-Beta-Banner-2-01.png | Bin .../articles}/2017.1.21/check.png | Bin .../articles}/2017.1.21/choose.png | Bin .../articles}/2017.1.21/houzi.png | Bin ...lin 1.1 Beta \351\231\215\344\270\264~.md" | 0 ...roid] 02 \350\257\264\350\257\264 Anko.md" | 0 .../articles}/2017.1.23/cover.jpg | Bin .../articles}/2017.1.23/linear.png | Bin .../articles}/2017.1.23/relative.png | Bin .../articles}/2017.1.30/coroutine_cover.jpg | Bin .../articles}/2017.1.30/coroutine_lua.png | Bin .../articles}/2017.1.30/cr0.png | Bin .../articles}/2017.1.30/cr1.png | Bin .../articles}/2017.1.30/cr2.png | Bin .../articles}/2017.1.30/mdhere.gif | Bin ...216 Java \345\205\261\345\255\230 (2) .md" | 0 ...6\350\276\221\344\273\243\347\240\201.jpg" | Bin ...26\350\276\221\344\273\243\347\240\201.md" | 0 ...7\220\206\350\247\243 Kotlin Coroutine.md" | 0 .../articles}/2017.1.9/action.gif | Bin .../articles}/2017.1.9/array.jpg | Bin .../articles}/2017.1.9/comment.gif | Bin .../articles}/2017.1.9/comment2.gif | Bin .../articles}/2017.1.9/comment3.gif | Bin .../articles}/2017.1.9/enter.gif | Bin .../articles}/2017.1.9/findaction.png | Bin .../articles}/2017.1.9/intellij.jpg | Bin .../articles}/2017.1.9/iter_smart.gif | Bin .../articles}/2017.1.9/iter_stupid.gif | Bin .../articles}/2017.1.9/livetemplate.png | Bin .../articles}/2017.1.9/lt10.png | Bin .../articles}/2017.1.9/lt11.png | Bin .../articles}/2017.1.9/lt12.png | Bin .../articles}/2017.1.9/lt13.png | Bin .../articles}/2017.1.9/lt14.png | Bin .../articles}/2017.1.9/lt15.png | Bin .../articles}/2017.1.9/lt2.png | Bin .../articles}/2017.1.9/lt3.png | Bin .../articles}/2017.1.9/lt4.png | Bin .../articles}/2017.1.9/lt5.png | Bin .../articles}/2017.1.9/lt6.png | Bin .../articles}/2017.1.9/lt8.png | Bin .../articles}/2017.1.9/lt9.png | Bin .../articles}/2017.1.9/main.gif | Bin .../articles}/2017.1.9/multiline.gif | Bin .../articles}/2017.1.9/multiline2.gif | Bin .../articles}/2017.1.9/multiline_action.png | Bin .../articles}/2017.1.9/newline.gif | Bin .../articles}/2017.1.9/newline2.gif | Bin .../articles}/2017.1.9/newline3.gif | Bin .../articles}/2017.1.9/newline_action.png | Bin .../articles}/2017.1.9/posix.png | Bin .../articles}/2017.1.9/search.png | Bin .../articles}/2017.1.9/search2.png | Bin .../articles}/2017.1.9/swap_action.png | Bin .../articles}/2017.1.9/swap_fun.gif | Bin .../articles}/2017.1.9/swap_smart.gif | Bin .../articles}/2017.1.9/swap_stupid.gif | Bin .../articles}/2017.1.9/tab.gif | Bin ...\214\346\230\257 IntArray \357\274\237.md" | 0 ...4\250\344\275\240\347\232\204 IntelliJ.md" | 0 .../articles}/2017.2.13/lambda.jpg | Bin ...a \350\241\250\350\276\276\345\274\217.md" | 0 .../articles}/2017.2.20/11RC-01.png | Bin ...54\351\203\275\350\267\257\344\270\212.md" | 0 .../articles}/2017.2.20/cover.jpg | Bin .../articles}/2017.2.20/embarassed.png | Bin .../articles}/2017.2.20/growup.png | Bin .../articles}/2017.2.20/high_order_fun.jpg | Bin .../articles}/2017.2.20/right.jpg | Bin .../articles}/2017.2.20/road.JPG | Bin .../articles}/2017.2.20/wangzhe.jpg | Bin .../articles}/2017.2.20/zhiyin.jpg | Bin ...60\357\274\210\344\270\200\357\274\211.md" | 0 ...60\357\274\210\344\272\214\357\274\211.md" | 0 ... 1.1 Beta 2 \345\217\221\345\270\203~.jpg" | Bin ...n 1.1 Beta 2 \345\217\221\345\270\203~.md" | 0 ...in coroutine (\344\272\214\357\274\211.md" | 0 ...otlin Script \344\273\213\347\273\215.jpg" | Bin ...Kotlin Script \344\273\213\347\273\215.md" | 0 ...212\346\211\213 Kotlin 11\346\213\233.jpg" | Bin ...\212\346\211\213 Kotlin 11\346\213\233.md" | 0 .../articles}/2017.3.20/cover.jpg | Bin .../articles}/2017.3.20/wechat_group.jpg | Bin ...s \347\232\204\351\224\231\357\274\237.md" | 0 .../articles}/2017.3.27/cover.jpg | Bin .../articles}/2017.3.4/Kotlin 1.1.md | 0 .../2017.3.4/Kotlin11blogbanner1.jpg | Bin ...0\345\244\247\347\232\204\345\235\221 .md" | 0 {arts => legacy/arts}/Kotlin-logo.png | Bin {arts => legacy/arts}/Kotlin.jpg | Bin {arts => legacy/arts}/contributes.jpg | Bin {arts => legacy/arts}/e_group.png | Bin ...3\347\240\201\345\205\263\346\263\250.png" | Bin .../code}/Kt01/src/net/println/kt01/Main.kt | 0 .../code}/Kt02/src/net/println/kt02/Main.kt | 0 {code => legacy/code}/Kt03/build.gradle | 0 .../Kt03/gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 0 {code => legacy/code}/Kt03/gradlew | 0 {code => legacy/code}/Kt03/gradlew.bat | 0 {code => legacy/code}/Kt03/settings.gradle | 0 .../src/main/java/net/println/kt03/Hello.java | 0 .../main/java/net/println/kt03/HelloJava.kt | 0 .../main/java/net/println/kt03/HelloKotlin.kt | 0 .../src/main/kotlin/net/println/kt03/User.kt | 0 {code => legacy/code}/Kt04/build.gradle | 0 .../Kt04/gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 0 {code => legacy/code}/Kt04/gradlew | 0 {code => legacy/code}/Kt04/gradlew.bat | 0 {code => legacy/code}/Kt04/settings.gradle | 0 .../java/net/println/kt04/ConsoleParam.kt | 0 .../net/println/kt04/ConsoleParamInJava.java | 0 {code => legacy/code}/Kt05/build.gradle | 0 .../Kt05/gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 0 {code => legacy/code}/Kt05/gradlew | 0 {code => legacy/code}/Kt05/gradlew.bat | 0 {code => legacy/code}/Kt05/settings.gradle | 0 .../java/net/println/kt05/ConsoleParam2.kt | 0 .../net/println/kt05/ConsoleParamInJava.java | 0 {code => legacy/code}/Kt06/build.gradle | 0 .../Kt06/gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 0 {code => legacy/code}/Kt06/gradlew | 0 {code => legacy/code}/Kt06/gradlew.bat | 0 {code => legacy/code}/Kt06/settings.gradle | 0 .../java/net/println/kt06/EnumInJava.java | 0 .../src/main/java/net/println/kt06/Main.java | 0 .../main/java/net/println/kt06/SayHello.kt | 0 {code => legacy/code}/Kt08/build.gradle | 0 .../Kt08/gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 0 {code => legacy/code}/Kt08/gradlew | 0 {code => legacy/code}/Kt08/gradlew.bat | 0 {code => legacy/code}/Kt08/settings.gradle | 0 .../src/main/java/net/println/kt08/Service.kt | 0 .../src/main/java/net/println/kt08/User.kt | 0 {code => legacy/code}/Kt09/build.gradle | 0 .../Kt09/gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 0 {code => legacy/code}/Kt09/gradlew | 0 {code => legacy/code}/Kt09/gradlew.bat | 0 .../src/main/java/net/println/kt09/Tailrec.kt | 0 {code => legacy/code}/Kt10/build.gradle | 0 .../Kt10/gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 0 {code => legacy/code}/Kt10/gradlew | 0 {code => legacy/code}/Kt10/gradlew.bat | 0 {code => legacy/code}/Kt10/settings.gradle | 0 .../println/kt10/java/LazyNotThreadSafe.java | 0 .../kt10/java/LazyThreadSafeDoubleCheck.java | 0 .../java/LazyThreadSafeStaticInnerClass.java | 0 .../kt10/java/LazyThreadSafeSynchronized.java | 0 .../println/kt10/java/PlainOldSingleton.java | 0 .../println/kt10/kotlin/LazyNotThreadSafe.kt | 0 .../kt10/kotlin/LazyThreadSafeDoubleCheck.kt | 0 .../kotlin/LazyThreadSafeStaticInnerObject.kt | 0 .../kt10/kotlin/LazyThreadSafeSynchronized.kt | 0 .../println/kt10/kotlin/PlainOldSingleton.kt | 0 {code => legacy/code}/Kt11/build.gradle | 0 .../Kt11/gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 0 {code => legacy/code}/Kt11/gradlew | 0 {code => legacy/code}/Kt11/gradlew.bat | 0 {code => legacy/code}/Kt11/settings.gradle | 0 .../src/main/kotlin/net/println/kt11/Main.kt | 0 .../main/kotlin/net/println/kt11/Player.kt | 0 .../main/kotlin/net/println/kt11/PlayerCmd.kt | 0 .../src/main/kotlin/net/println/kt11/State.kt | 0 {code => legacy/code}/Kt12/Program.cs | 0 {code => legacy/code}/Kt12/build.gradle | 0 .../Kt12/gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 0 {code => legacy/code}/Kt12/gradlew | 0 {code => legacy/code}/Kt12/gradlew.bat | 0 {code => legacy/code}/Kt12/result_singer.json | 0 .../code}/Kt12/result_singer_field_loss.json | 0 {code => legacy/code}/Kt12/result_songs.json | 0 {code => legacy/code}/Kt12/settings.gradle | 0 {code => legacy/code}/Kt12/singer.json | 0 .../src/main/java/net/println/kt12/Main.java | 0 .../src/main/kotlin/net/println/kt12/Api.kt | 0 .../src/main/kotlin/net/println/kt12/Data.kt | 0 .../main/kotlin/net/println/kt12/GsonExt.kt | 0 .../src/main/kotlin/net/println/kt12/Main.kt | 0 {code => legacy/code}/Kt13/build.gradle | 0 .../Kt13/gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 0 {code => legacy/code}/Kt13/gradlew | 0 {code => legacy/code}/Kt13/gradlew.bat | 0 {code => legacy/code}/Kt13/settings.gradle | 0 .../net/println/kt13/RESTFulComponent.kt | 0 .../main/kotlin/net/println/kt13/Service.kt | 0 .../src/main/kotlin/net/println/kt13/User.kt | 0 .../net/println/kt13/config/Settings.kt | 0 .../net/println/kt13/module/BaseUrlModule.kt | 0 .../net/println/kt13/module/CacheModule.kt | 0 .../kt13/module/GsonConverterModule.kt | 0 .../net/println/kt13/module/GsonModule.kt | 0 .../println/kt13/module/OkHttpClientModule.kt | 0 .../net/println/kt13/module/RetrofitModule.kt | 0 .../println/kt13/module/RxAdapterModule.kt | 0 {code => legacy/code}/Kt14/Kt14/build.gradle | 0 .../java/net/println/kt14/AccessToObject.java | 0 .../net/println/kt14/AccessToOverloads.java | 0 .../println/kt14/CallExtenstionMethod.java | 0 .../net/println/kt14/CallInternalClass.java | 0 .../net/println/kt14/CallPackageMethod.java | 0 .../java/net/println/kt14/PersonMain.java | 0 .../net/println/kt14/CallInternalClass.kt | 0 .../net/println/kt14/ExtensionMethod.kt | 0 .../kotlin/net/println/kt14/InternalClass.kt | 0 .../main/kotlin/net/println/kt14/Overloads.kt | 0 .../main/kotlin/net/println/kt14/Package.kt | 0 .../main/kotlin/net/println/kt14/Person.kt | 0 .../main/kotlin/net/println/kt14/Singleton.kt | 0 {code => legacy/code}/Kt14/build.gradle | 0 .../Kt14/gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 0 {code => legacy/code}/Kt14/gradlew | 0 {code => legacy/code}/Kt14/gradlew.bat | 0 .../code}/Kt14/kt14internal/build.gradle | 0 .../kt14internal/CallInternalClass.java | 0 .../kt14internal/CallInternalClassKt.kt | 0 {code => legacy/code}/Kt14/settings.gradle | 0 {code => legacy/code}/Kt15/build.gradle | 0 .../Kt15/gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 0 {code => legacy/code}/Kt15/gradlew | 0 {code => legacy/code}/Kt15/gradlew.bat | 0 {code => legacy/code}/Kt15/settings.gradle | 0 .../main/java/net/println/kt15/DataClass.java | 0 .../main/java/net/println/kt15/Generics.java | 0 .../net/println/kt15/NullSafetyAbsClass.java | 0 .../java/net/println/kt15/NullSafetyJava.java | 0 .../main/java/net/println/kt15/SAMInJava.java | 0 .../net/println/kt15/AccessDataClass.kt | 0 .../net/println/kt15/ConcurrentRelated.kt | 0 .../kotlin/net/println/kt15/GenericsInKt.kt | 0 .../kotlin/net/println/kt15/NullSafety.kt | 0 .../net/println/kt15/NullSafetySubClass.kt | 0 .../kotlin/net/println/kt15/SAMConversion.kt | 0 .../code}/MyBatisIssue/build.gradle | 0 .../gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 0 {code => legacy/code}/MyBatisIssue/gradlew | 0 .../code}/MyBatisIssue/gradlew.bat | 0 .../libs/mysql-connector-java-5.1.40-bin.jar | Bin .../code}/MyBatisIssue/settings.gradle | 0 .../net/println/kotlin/mybatis/Main.java | 0 .../kotlin/net/println/kotlin/mybatis/Main.kt | 0 .../net/println/kotlin/mybatis/TestUnsafe.kt | 0 .../kotlin/net/println/kotlin/mybatis/User.kt | 0 .../println/kotlin/mybatis/UserMapper.java | 0 .../kotlin/mybatis/annotations/PoKo.kt | 0 .../net/println/kotlin/mybatis/UserMapper.xml | 0 .../net/println/kotlin/mybatis/config.xml | 0 .../net/println/kotlin/mybatis/db.properties | 0 .../net/println/kotlin/mybatis/userinfo.sql | 0 {code => legacy/code}/RealmIssue/.gitignore | 0 .../code}/RealmIssue/app/.gitignore | 0 .../code}/RealmIssue/app/build.gradle | 0 .../code}/RealmIssue/app/proguard-rules.pro | 0 .../app/src/main/AndroidManifest.xml | 0 .../main/java/net/println/kotlin/realm/App.kt | 0 .../net/println/kotlin/realm/MainActivity.kt | 0 .../java/net/println/kotlin/realm/PoKo.kt | 0 .../java/net/println/kotlin/realm/User.kt | 0 .../app/src/main/res/layout/activity_main.xml | 0 .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin .../res/mipmap-hdpi/ic_launcher_round.png | Bin .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin .../res/mipmap-mdpi/ic_launcher_round.png | Bin .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin .../res/mipmap-xhdpi/ic_launcher_round.png | Bin .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin .../app/src/main/res/values/colors.xml | 0 .../app/src/main/res/values/strings.xml | 0 .../app/src/main/res/values/styles.xml | 0 {code => legacy/code}/RealmIssue/build.gradle | 0 .../code}/RealmIssue/gradle.properties | 0 .../gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 0 {code => legacy/code}/RealmIssue/gradlew | 0 {code => legacy/code}/RealmIssue/gradlew.bat | 0 .../code}/RealmIssue/settings.gradle | 0 {code => legacy/code}/kt07/build.gradle | 0 .../kt07/gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 0 {code => legacy/code}/kt07/gradlew | 0 {code => legacy/code}/kt07/gradlew.bat | 0 {code => legacy/code}/kt07/settings.gradle | 0 .../code}/kt07/src/main/Resources/input | 0 .../src/main/java/net/println/kt07/Lambda.kt | 0 ...1\345\255\230\357\274\2101\357\274\211.md" | 0 ...\216 Java \345\205\261\345\255\230 (2).md" | 0 .../Kt01 \347\256\200\344\273\213.pptx" | Bin ...6\236\220Json\346\225\260\346\215\256.key" | Bin ...0\344\270\252\346\246\202\345\277\265.key" | Bin ...45\205\261\345\255\230(\344\270\200).potx" | Bin 319 files changed, 170 insertions(+), 177 deletions(-) create mode 100644 docs/Dive-into-Kotlin-Coroutines.md create mode 100644 docs/Tutorials-IMOOC.md create mode 100644 legacy/README.md rename "articles/2016.12.26 Kotlin \345\246\202\344\275\225\344\274\230\351\233\205\347\232\204\345\256\236\347\216\260\343\200\216\345\244\232\347\273\247\346\211\277\343\200\217.md" => "legacy/articles/2016.12.26 Kotlin \345\246\202\344\275\225\344\274\230\351\233\205\347\232\204\345\256\236\347\216\260\343\200\216\345\244\232\347\273\247\346\211\277\343\200\217.md" (100%) rename {articles => legacy/articles}/2016.12.26.jpg (100%) rename {articles => legacy/articles}/2017.1.16/cover.jpg (100%) rename "articles/2017.1.16/\347\224\250 Kotlin \345\206\231 Android 01 \351\232\276\351\201\223\345\217\252\346\234\211\347\216\257\345\242\203\346\220\255\345\273\272\350\277\231\344\271\210\347\256\200\345\215\225\357\274\237.md" => "legacy/articles/2017.1.16/\347\224\250 Kotlin \345\206\231 Android 01 \351\232\276\351\201\223\345\217\252\346\234\211\347\216\257\345\242\203\346\220\255\345\273\272\350\277\231\344\271\210\347\256\200\345\215\225\357\274\237.md" (100%) rename {articles => legacy/articles}/2017.1.2/17.1.2.jpg (100%) rename {articles => legacy/articles}/2017.1.2/17.1.2b.jpg (100%) rename {articles => legacy/articles}/2017.1.2/Kotlin 1.0.6.md (100%) rename {articles => legacy/articles}/2017.1.2/args.gif (100%) rename {articles => legacy/articles}/2017.1.2/try.gif (100%) rename "articles/2017.1.2/\345\203\217\345\206\231\346\226\207\347\253\240\344\270\200\346\240\267\344\275\277\347\224\250 Kotlin.md" => "legacy/articles/2017.1.2/\345\203\217\345\206\231\346\226\207\347\253\240\344\270\200\346\240\267\344\275\277\347\224\250 Kotlin.md" (100%) rename {articles => legacy/articles}/2017.1.21/1.1-Beta-Banner-2-01.png (100%) rename {articles => legacy/articles}/2017.1.21/check.png (100%) rename {articles => legacy/articles}/2017.1.21/choose.png (100%) rename {articles => legacy/articles}/2017.1.21/houzi.png (100%) rename "articles/2017.1.21/\345\226\234\345\244\247\346\231\256\345\245\224\357\274\201Kotlin 1.1 Beta \351\231\215\344\270\264~.md" => "legacy/articles/2017.1.21/\345\226\234\345\244\247\346\231\256\345\245\224\357\274\201Kotlin 1.1 Beta \351\231\215\344\270\264~.md" (100%) rename "articles/2017.1.23/[\347\224\250 Kotlin \345\206\231 Android] 02 \350\257\264\350\257\264 Anko.md" => "legacy/articles/2017.1.23/[\347\224\250 Kotlin \345\206\231 Android] 02 \350\257\264\350\257\264 Anko.md" (100%) rename {articles => legacy/articles}/2017.1.23/cover.jpg (100%) rename {articles => legacy/articles}/2017.1.23/linear.png (100%) rename {articles => legacy/articles}/2017.1.23/relative.png (100%) rename {articles => legacy/articles}/2017.1.30/coroutine_cover.jpg (100%) rename {articles => legacy/articles}/2017.1.30/coroutine_lua.png (100%) rename {articles => legacy/articles}/2017.1.30/cr0.png (100%) rename {articles => legacy/articles}/2017.1.30/cr1.png (100%) rename {articles => legacy/articles}/2017.1.30/cr2.png (100%) rename {articles => legacy/articles}/2017.1.30/mdhere.gif (100%) rename "articles/2017.1.30/\345\213\230\350\257\257\357\274\23215 Kotlin \344\270\216 Java \345\205\261\345\255\230 (2) .md" => "legacy/articles/2017.1.30/\345\213\230\350\257\257\357\274\23215 Kotlin \344\270\216 Java \345\205\261\345\255\230 (2) .md" (100%) rename "articles/2017.1.30/\345\246\202\344\275\225\344\274\230\351\233\205\347\232\204\345\234\250\345\276\256\344\277\241\345\205\254\344\274\227\345\217\267\344\270\255\347\274\226\350\276\221\344\273\243\347\240\201.jpg" => "legacy/articles/2017.1.30/\345\246\202\344\275\225\344\274\230\351\233\205\347\232\204\345\234\250\345\276\256\344\277\241\345\205\254\344\274\227\345\217\267\344\270\255\347\274\226\350\276\221\344\273\243\347\240\201.jpg" (100%) rename "articles/2017.1.30/\345\246\202\344\275\225\344\274\230\351\233\205\347\232\204\345\234\250\345\276\256\344\277\241\345\205\254\344\274\227\345\217\267\344\270\255\347\274\226\350\276\221\344\273\243\347\240\201.md" => "legacy/articles/2017.1.30/\345\246\202\344\275\225\344\274\230\351\233\205\347\232\204\345\234\250\345\276\256\344\277\241\345\205\254\344\274\227\345\217\267\344\270\255\347\274\226\350\276\221\344\273\243\347\240\201.md" (100%) rename "articles/2017.1.30/\346\267\261\345\205\245\347\220\206\350\247\243 Kotlin Coroutine.md" => "legacy/articles/2017.1.30/\346\267\261\345\205\245\347\220\206\350\247\243 Kotlin Coroutine.md" (100%) rename {articles => legacy/articles}/2017.1.9/action.gif (100%) rename {articles => legacy/articles}/2017.1.9/array.jpg (100%) rename {articles => legacy/articles}/2017.1.9/comment.gif (100%) rename {articles => legacy/articles}/2017.1.9/comment2.gif (100%) rename {articles => legacy/articles}/2017.1.9/comment3.gif (100%) rename {articles => legacy/articles}/2017.1.9/enter.gif (100%) rename {articles => legacy/articles}/2017.1.9/findaction.png (100%) rename {articles => legacy/articles}/2017.1.9/intellij.jpg (100%) rename {articles => legacy/articles}/2017.1.9/iter_smart.gif (100%) rename {articles => legacy/articles}/2017.1.9/iter_stupid.gif (100%) rename {articles => legacy/articles}/2017.1.9/livetemplate.png (100%) rename {articles => legacy/articles}/2017.1.9/lt10.png (100%) rename {articles => legacy/articles}/2017.1.9/lt11.png (100%) rename {articles => legacy/articles}/2017.1.9/lt12.png (100%) rename {articles => legacy/articles}/2017.1.9/lt13.png (100%) rename {articles => legacy/articles}/2017.1.9/lt14.png (100%) rename {articles => legacy/articles}/2017.1.9/lt15.png (100%) rename {articles => legacy/articles}/2017.1.9/lt2.png (100%) rename {articles => legacy/articles}/2017.1.9/lt3.png (100%) rename {articles => legacy/articles}/2017.1.9/lt4.png (100%) rename {articles => legacy/articles}/2017.1.9/lt5.png (100%) rename {articles => legacy/articles}/2017.1.9/lt6.png (100%) rename {articles => legacy/articles}/2017.1.9/lt8.png (100%) rename {articles => legacy/articles}/2017.1.9/lt9.png (100%) rename {articles => legacy/articles}/2017.1.9/main.gif (100%) rename {articles => legacy/articles}/2017.1.9/multiline.gif (100%) rename {articles => legacy/articles}/2017.1.9/multiline2.gif (100%) rename {articles => legacy/articles}/2017.1.9/multiline_action.png (100%) rename {articles => legacy/articles}/2017.1.9/newline.gif (100%) rename {articles => legacy/articles}/2017.1.9/newline2.gif (100%) rename {articles => legacy/articles}/2017.1.9/newline3.gif (100%) rename {articles => legacy/articles}/2017.1.9/newline_action.png (100%) rename {articles => legacy/articles}/2017.1.9/posix.png (100%) rename {articles => legacy/articles}/2017.1.9/search.png (100%) rename {articles => legacy/articles}/2017.1.9/search2.png (100%) rename {articles => legacy/articles}/2017.1.9/swap_action.png (100%) rename {articles => legacy/articles}/2017.1.9/swap_fun.gif (100%) rename {articles => legacy/articles}/2017.1.9/swap_smart.gif (100%) rename {articles => legacy/articles}/2017.1.9/swap_stupid.gif (100%) rename {articles => legacy/articles}/2017.1.9/tab.gif (100%) rename "articles/2017.1.9/\344\270\272\344\273\200\344\271\210\344\270\215\347\233\264\346\216\245\344\275\277\347\224\250 Array \350\200\214\346\230\257 IntArray \357\274\237.md" => "legacy/articles/2017.1.9/\344\270\272\344\273\200\344\271\210\344\270\215\347\233\264\346\216\245\344\275\277\347\224\250 Array \350\200\214\346\230\257 IntArray \357\274\237.md" (100%) rename "articles/2017.1.9/\351\253\230\346\225\210\345\234\260\344\275\277\347\224\250\344\275\240\347\232\204 IntelliJ.md" => "legacy/articles/2017.1.9/\351\253\230\346\225\210\345\234\260\344\275\277\347\224\250\344\275\240\347\232\204 IntelliJ.md" (100%) rename {articles => legacy/articles}/2017.2.13/lambda.jpg (100%) rename "articles/2017.2.13/\347\273\206\350\257\264 Lambda \350\241\250\350\276\276\345\274\217.md" => "legacy/articles/2017.2.13/\347\273\206\350\257\264 Lambda \350\241\250\350\276\276\345\274\217.md" (100%) rename {articles => legacy/articles}/2017.2.20/11RC-01.png (100%) rename "articles/2017.2.20/Kotlin 1.1\357\274\232\346\210\221\344\273\254\351\203\275\350\267\257\344\270\212.md" => "legacy/articles/2017.2.20/Kotlin 1.1\357\274\232\346\210\221\344\273\254\351\203\275\350\267\257\344\270\212.md" (100%) rename {articles => legacy/articles}/2017.2.20/cover.jpg (100%) rename {articles => legacy/articles}/2017.2.20/embarassed.png (100%) rename {articles => legacy/articles}/2017.2.20/growup.png (100%) rename {articles => legacy/articles}/2017.2.20/high_order_fun.jpg (100%) rename {articles => legacy/articles}/2017.2.20/right.jpg (100%) rename {articles => legacy/articles}/2017.2.20/road.JPG (100%) rename {articles => legacy/articles}/2017.2.20/wangzhe.jpg (100%) rename {articles => legacy/articles}/2017.2.20/zhiyin.jpg (100%) rename "articles/2017.2.20/\351\253\230\351\230\266\345\207\275\346\225\260\357\274\210\344\270\200\357\274\211.md" => "legacy/articles/2017.2.20/\351\253\230\351\230\266\345\207\275\346\225\260\357\274\210\344\270\200\357\274\211.md" (100%) rename "articles/2017.2.27/\351\253\230\351\230\266\345\207\275\346\225\260\357\274\210\344\272\214\357\274\211.md" => "legacy/articles/2017.2.27/\351\253\230\351\230\266\345\207\275\346\225\260\357\274\210\344\272\214\357\274\211.md" (100%) rename "articles/2017.2.6/Kotlin 1.1 Beta 2 \345\217\221\345\270\203~.jpg" => "legacy/articles/2017.2.6/Kotlin 1.1 Beta 2 \345\217\221\345\270\203~.jpg" (100%) rename "articles/2017.2.6/Kotlin 1.1 Beta 2 \345\217\221\345\270\203~.md" => "legacy/articles/2017.2.6/Kotlin 1.1 Beta 2 \345\217\221\345\270\203~.md" (100%) rename "articles/2017.2.6/\346\267\261\345\205\245\347\220\206\350\247\243 Kotlin coroutine (\344\272\214\357\274\211.md" => "legacy/articles/2017.2.6/\346\267\261\345\205\245\347\220\206\350\247\243 Kotlin coroutine (\344\272\214\357\274\211.md" (100%) rename "articles/2017.3.13/Kotlin Script \344\273\213\347\273\215.jpg" => "legacy/articles/2017.3.13/Kotlin Script \344\273\213\347\273\215.jpg" (100%) rename "articles/2017.3.13/Kotlin Script \344\273\213\347\273\215.md" => "legacy/articles/2017.3.13/Kotlin Script \344\273\213\347\273\215.md" (100%) rename "articles/2017.3.13/\345\277\253\351\200\237\344\270\212\346\211\213 Kotlin 11\346\213\233.jpg" => "legacy/articles/2017.3.13/\345\277\253\351\200\237\344\270\212\346\211\213 Kotlin 11\346\213\233.jpg" (100%) rename "articles/2017.3.13/\345\277\253\351\200\237\344\270\212\346\211\213 Kotlin 11\346\213\233.md" => "legacy/articles/2017.3.13/\345\277\253\351\200\237\344\270\212\346\211\213 Kotlin 11\346\213\233.md" (100%) rename {articles => legacy/articles}/2017.3.20/cover.jpg (100%) rename {articles => legacy/articles}/2017.3.20/wechat_group.jpg (100%) rename "articles/2017.3.27/Kotlin \351\201\207\345\210\260 MyBatis\357\274\232\345\210\260\345\272\225\346\230\257 Int \347\232\204\351\224\231\357\274\214\350\277\230\346\230\257 data class \347\232\204\351\224\231\357\274\237.md" => "legacy/articles/2017.3.27/Kotlin \351\201\207\345\210\260 MyBatis\357\274\232\345\210\260\345\272\225\346\230\257 Int \347\232\204\351\224\231\357\274\214\350\277\230\346\230\257 data class \347\232\204\351\224\231\357\274\237.md" (100%) rename {articles => legacy/articles}/2017.3.27/cover.jpg (100%) rename {articles => legacy/articles}/2017.3.4/Kotlin 1.1.md (100%) rename {articles => legacy/articles}/2017.3.4/Kotlin11blogbanner1.jpg (100%) rename "articles/2017.4.3/Kotlin \345\205\274\345\256\271 Java \351\201\207\345\210\260\347\232\204\346\234\200\345\244\247\347\232\204\345\235\221 .md" => "legacy/articles/2017.4.3/Kotlin \345\205\274\345\256\271 Java \351\201\207\345\210\260\347\232\204\346\234\200\345\244\247\347\232\204\345\235\221 .md" (100%) rename {arts => legacy/arts}/Kotlin-logo.png (100%) rename {arts => legacy/arts}/Kotlin.jpg (100%) rename {arts => legacy/arts}/contributes.jpg (100%) rename {arts => legacy/arts}/e_group.png (100%) rename "arts/kotlin\346\211\253\347\240\201\345\205\263\346\263\250.png" => "legacy/arts/kotlin\346\211\253\347\240\201\345\205\263\346\263\250.png" (100%) rename {code => legacy/code}/Kt01/src/net/println/kt01/Main.kt (100%) rename {code => legacy/code}/Kt02/src/net/println/kt02/Main.kt (100%) rename {code => legacy/code}/Kt03/build.gradle (100%) rename {code => legacy/code}/Kt03/gradle/wrapper/gradle-wrapper.jar (100%) rename {code => legacy/code}/Kt03/gradle/wrapper/gradle-wrapper.properties (100%) rename {code => legacy/code}/Kt03/gradlew (100%) rename {code => legacy/code}/Kt03/gradlew.bat (100%) rename {code => legacy/code}/Kt03/settings.gradle (100%) rename {code => legacy/code}/Kt03/src/main/java/net/println/kt03/Hello.java (100%) rename {code => legacy/code}/Kt03/src/main/java/net/println/kt03/HelloJava.kt (100%) rename {code => legacy/code}/Kt03/src/main/java/net/println/kt03/HelloKotlin.kt (100%) rename {code => legacy/code}/Kt03/src/main/kotlin/net/println/kt03/User.kt (100%) rename {code => legacy/code}/Kt04/build.gradle (100%) rename {code => legacy/code}/Kt04/gradle/wrapper/gradle-wrapper.jar (100%) rename {code => legacy/code}/Kt04/gradle/wrapper/gradle-wrapper.properties (100%) rename {code => legacy/code}/Kt04/gradlew (100%) rename {code => legacy/code}/Kt04/gradlew.bat (100%) rename {code => legacy/code}/Kt04/settings.gradle (100%) rename {code => legacy/code}/Kt04/src/main/java/net/println/kt04/ConsoleParam.kt (100%) rename {code => legacy/code}/Kt04/src/main/java/net/println/kt04/ConsoleParamInJava.java (100%) rename {code => legacy/code}/Kt05/build.gradle (100%) rename {code => legacy/code}/Kt05/gradle/wrapper/gradle-wrapper.jar (100%) rename {code => legacy/code}/Kt05/gradle/wrapper/gradle-wrapper.properties (100%) rename {code => legacy/code}/Kt05/gradlew (100%) rename {code => legacy/code}/Kt05/gradlew.bat (100%) rename {code => legacy/code}/Kt05/settings.gradle (100%) rename {code => legacy/code}/Kt05/src/main/java/net/println/kt05/ConsoleParam2.kt (100%) rename {code => legacy/code}/Kt05/src/main/java/net/println/kt05/ConsoleParamInJava.java (100%) rename {code => legacy/code}/Kt06/build.gradle (100%) rename {code => legacy/code}/Kt06/gradle/wrapper/gradle-wrapper.jar (100%) rename {code => legacy/code}/Kt06/gradle/wrapper/gradle-wrapper.properties (100%) rename {code => legacy/code}/Kt06/gradlew (100%) rename {code => legacy/code}/Kt06/gradlew.bat (100%) rename {code => legacy/code}/Kt06/settings.gradle (100%) rename {code => legacy/code}/Kt06/src/main/java/net/println/kt06/EnumInJava.java (100%) rename {code => legacy/code}/Kt06/src/main/java/net/println/kt06/Main.java (100%) rename {code => legacy/code}/Kt06/src/main/java/net/println/kt06/SayHello.kt (100%) rename {code => legacy/code}/Kt08/build.gradle (100%) rename {code => legacy/code}/Kt08/gradle/wrapper/gradle-wrapper.jar (100%) rename {code => legacy/code}/Kt08/gradle/wrapper/gradle-wrapper.properties (100%) rename {code => legacy/code}/Kt08/gradlew (100%) rename {code => legacy/code}/Kt08/gradlew.bat (100%) rename {code => legacy/code}/Kt08/settings.gradle (100%) rename {code => legacy/code}/Kt08/src/main/java/net/println/kt08/Service.kt (100%) rename {code => legacy/code}/Kt08/src/main/java/net/println/kt08/User.kt (100%) rename {code => legacy/code}/Kt09/build.gradle (100%) rename {code => legacy/code}/Kt09/gradle/wrapper/gradle-wrapper.jar (100%) rename {code => legacy/code}/Kt09/gradle/wrapper/gradle-wrapper.properties (100%) rename {code => legacy/code}/Kt09/gradlew (100%) rename {code => legacy/code}/Kt09/gradlew.bat (100%) rename {code => legacy/code}/Kt09/src/main/java/net/println/kt09/Tailrec.kt (100%) rename {code => legacy/code}/Kt10/build.gradle (100%) rename {code => legacy/code}/Kt10/gradle/wrapper/gradle-wrapper.jar (100%) rename {code => legacy/code}/Kt10/gradle/wrapper/gradle-wrapper.properties (100%) rename {code => legacy/code}/Kt10/gradlew (100%) rename {code => legacy/code}/Kt10/gradlew.bat (100%) rename {code => legacy/code}/Kt10/settings.gradle (100%) rename {code => legacy/code}/Kt10/src/main/java/net/println/kt10/java/LazyNotThreadSafe.java (100%) rename {code => legacy/code}/Kt10/src/main/java/net/println/kt10/java/LazyThreadSafeDoubleCheck.java (100%) rename {code => legacy/code}/Kt10/src/main/java/net/println/kt10/java/LazyThreadSafeStaticInnerClass.java (100%) rename {code => legacy/code}/Kt10/src/main/java/net/println/kt10/java/LazyThreadSafeSynchronized.java (100%) rename {code => legacy/code}/Kt10/src/main/java/net/println/kt10/java/PlainOldSingleton.java (100%) rename {code => legacy/code}/Kt10/src/main/kotlin/net/println/kt10/kotlin/LazyNotThreadSafe.kt (100%) rename {code => legacy/code}/Kt10/src/main/kotlin/net/println/kt10/kotlin/LazyThreadSafeDoubleCheck.kt (100%) rename {code => legacy/code}/Kt10/src/main/kotlin/net/println/kt10/kotlin/LazyThreadSafeStaticInnerObject.kt (100%) rename {code => legacy/code}/Kt10/src/main/kotlin/net/println/kt10/kotlin/LazyThreadSafeSynchronized.kt (100%) rename {code => legacy/code}/Kt10/src/main/kotlin/net/println/kt10/kotlin/PlainOldSingleton.kt (100%) rename {code => legacy/code}/Kt11/build.gradle (100%) rename {code => legacy/code}/Kt11/gradle/wrapper/gradle-wrapper.jar (100%) rename {code => legacy/code}/Kt11/gradle/wrapper/gradle-wrapper.properties (100%) rename {code => legacy/code}/Kt11/gradlew (100%) rename {code => legacy/code}/Kt11/gradlew.bat (100%) rename {code => legacy/code}/Kt11/settings.gradle (100%) rename {code => legacy/code}/Kt11/src/main/kotlin/net/println/kt11/Main.kt (100%) rename {code => legacy/code}/Kt11/src/main/kotlin/net/println/kt11/Player.kt (100%) rename {code => legacy/code}/Kt11/src/main/kotlin/net/println/kt11/PlayerCmd.kt (100%) rename {code => legacy/code}/Kt11/src/main/kotlin/net/println/kt11/State.kt (100%) rename {code => legacy/code}/Kt12/Program.cs (100%) rename {code => legacy/code}/Kt12/build.gradle (100%) rename {code => legacy/code}/Kt12/gradle/wrapper/gradle-wrapper.jar (100%) rename {code => legacy/code}/Kt12/gradle/wrapper/gradle-wrapper.properties (100%) rename {code => legacy/code}/Kt12/gradlew (100%) rename {code => legacy/code}/Kt12/gradlew.bat (100%) rename {code => legacy/code}/Kt12/result_singer.json (100%) rename {code => legacy/code}/Kt12/result_singer_field_loss.json (100%) rename {code => legacy/code}/Kt12/result_songs.json (100%) rename {code => legacy/code}/Kt12/settings.gradle (100%) rename {code => legacy/code}/Kt12/singer.json (100%) rename {code => legacy/code}/Kt12/src/main/java/net/println/kt12/Main.java (100%) rename {code => legacy/code}/Kt12/src/main/kotlin/net/println/kt12/Api.kt (100%) rename {code => legacy/code}/Kt12/src/main/kotlin/net/println/kt12/Data.kt (100%) rename {code => legacy/code}/Kt12/src/main/kotlin/net/println/kt12/GsonExt.kt (100%) rename {code => legacy/code}/Kt12/src/main/kotlin/net/println/kt12/Main.kt (100%) rename {code => legacy/code}/Kt13/build.gradle (100%) rename {code => legacy/code}/Kt13/gradle/wrapper/gradle-wrapper.jar (100%) rename {code => legacy/code}/Kt13/gradle/wrapper/gradle-wrapper.properties (100%) rename {code => legacy/code}/Kt13/gradlew (100%) rename {code => legacy/code}/Kt13/gradlew.bat (100%) rename {code => legacy/code}/Kt13/settings.gradle (100%) rename {code => legacy/code}/Kt13/src/main/kotlin/net/println/kt13/RESTFulComponent.kt (100%) rename {code => legacy/code}/Kt13/src/main/kotlin/net/println/kt13/Service.kt (100%) rename {code => legacy/code}/Kt13/src/main/kotlin/net/println/kt13/User.kt (100%) rename {code => legacy/code}/Kt13/src/main/kotlin/net/println/kt13/config/Settings.kt (100%) rename {code => legacy/code}/Kt13/src/main/kotlin/net/println/kt13/module/BaseUrlModule.kt (100%) rename {code => legacy/code}/Kt13/src/main/kotlin/net/println/kt13/module/CacheModule.kt (100%) rename {code => legacy/code}/Kt13/src/main/kotlin/net/println/kt13/module/GsonConverterModule.kt (100%) rename {code => legacy/code}/Kt13/src/main/kotlin/net/println/kt13/module/GsonModule.kt (100%) rename {code => legacy/code}/Kt13/src/main/kotlin/net/println/kt13/module/OkHttpClientModule.kt (100%) rename {code => legacy/code}/Kt13/src/main/kotlin/net/println/kt13/module/RetrofitModule.kt (100%) rename {code => legacy/code}/Kt13/src/main/kotlin/net/println/kt13/module/RxAdapterModule.kt (100%) rename {code => legacy/code}/Kt14/Kt14/build.gradle (100%) rename {code => legacy/code}/Kt14/Kt14/src/main/java/net/println/kt14/AccessToObject.java (100%) rename {code => legacy/code}/Kt14/Kt14/src/main/java/net/println/kt14/AccessToOverloads.java (100%) rename {code => legacy/code}/Kt14/Kt14/src/main/java/net/println/kt14/CallExtenstionMethod.java (100%) rename {code => legacy/code}/Kt14/Kt14/src/main/java/net/println/kt14/CallInternalClass.java (100%) rename {code => legacy/code}/Kt14/Kt14/src/main/java/net/println/kt14/CallPackageMethod.java (100%) rename {code => legacy/code}/Kt14/Kt14/src/main/java/net/println/kt14/PersonMain.java (100%) rename {code => legacy/code}/Kt14/Kt14/src/main/kotlin/net/println/kt14/CallInternalClass.kt (100%) rename {code => legacy/code}/Kt14/Kt14/src/main/kotlin/net/println/kt14/ExtensionMethod.kt (100%) rename {code => legacy/code}/Kt14/Kt14/src/main/kotlin/net/println/kt14/InternalClass.kt (100%) rename {code => legacy/code}/Kt14/Kt14/src/main/kotlin/net/println/kt14/Overloads.kt (100%) rename {code => legacy/code}/Kt14/Kt14/src/main/kotlin/net/println/kt14/Package.kt (100%) rename {code => legacy/code}/Kt14/Kt14/src/main/kotlin/net/println/kt14/Person.kt (100%) rename {code => legacy/code}/Kt14/Kt14/src/main/kotlin/net/println/kt14/Singleton.kt (100%) rename {code => legacy/code}/Kt14/build.gradle (100%) rename {code => legacy/code}/Kt14/gradle/wrapper/gradle-wrapper.jar (100%) rename {code => legacy/code}/Kt14/gradle/wrapper/gradle-wrapper.properties (100%) rename {code => legacy/code}/Kt14/gradlew (100%) rename {code => legacy/code}/Kt14/gradlew.bat (100%) rename {code => legacy/code}/Kt14/kt14internal/build.gradle (100%) rename {code => legacy/code}/Kt14/kt14internal/src/main/java/net/println/kt14internal/CallInternalClass.java (100%) rename {code => legacy/code}/Kt14/kt14internal/src/main/kotlin/net/println/kt14internal/CallInternalClassKt.kt (100%) rename {code => legacy/code}/Kt14/settings.gradle (100%) rename {code => legacy/code}/Kt15/build.gradle (100%) rename {code => legacy/code}/Kt15/gradle/wrapper/gradle-wrapper.jar (100%) rename {code => legacy/code}/Kt15/gradle/wrapper/gradle-wrapper.properties (100%) rename {code => legacy/code}/Kt15/gradlew (100%) rename {code => legacy/code}/Kt15/gradlew.bat (100%) rename {code => legacy/code}/Kt15/settings.gradle (100%) rename {code => legacy/code}/Kt15/src/main/java/net/println/kt15/DataClass.java (100%) rename {code => legacy/code}/Kt15/src/main/java/net/println/kt15/Generics.java (100%) rename {code => legacy/code}/Kt15/src/main/java/net/println/kt15/NullSafetyAbsClass.java (100%) rename {code => legacy/code}/Kt15/src/main/java/net/println/kt15/NullSafetyJava.java (100%) rename {code => legacy/code}/Kt15/src/main/java/net/println/kt15/SAMInJava.java (100%) rename {code => legacy/code}/Kt15/src/main/kotlin/net/println/kt15/AccessDataClass.kt (100%) rename {code => legacy/code}/Kt15/src/main/kotlin/net/println/kt15/ConcurrentRelated.kt (100%) rename {code => legacy/code}/Kt15/src/main/kotlin/net/println/kt15/GenericsInKt.kt (100%) rename {code => legacy/code}/Kt15/src/main/kotlin/net/println/kt15/NullSafety.kt (100%) rename {code => legacy/code}/Kt15/src/main/kotlin/net/println/kt15/NullSafetySubClass.kt (100%) rename {code => legacy/code}/Kt15/src/main/kotlin/net/println/kt15/SAMConversion.kt (100%) rename {code => legacy/code}/MyBatisIssue/build.gradle (100%) rename {code => legacy/code}/MyBatisIssue/gradle/wrapper/gradle-wrapper.jar (100%) rename {code => legacy/code}/MyBatisIssue/gradle/wrapper/gradle-wrapper.properties (100%) rename {code => legacy/code}/MyBatisIssue/gradlew (100%) rename {code => legacy/code}/MyBatisIssue/gradlew.bat (100%) rename {code => legacy/code}/MyBatisIssue/libs/mysql-connector-java-5.1.40-bin.jar (100%) rename {code => legacy/code}/MyBatisIssue/settings.gradle (100%) rename {code => legacy/code}/MyBatisIssue/src/main/kotlin/net/println/kotlin/mybatis/Main.java (100%) rename {code => legacy/code}/MyBatisIssue/src/main/kotlin/net/println/kotlin/mybatis/Main.kt (100%) rename {code => legacy/code}/MyBatisIssue/src/main/kotlin/net/println/kotlin/mybatis/TestUnsafe.kt (100%) rename {code => legacy/code}/MyBatisIssue/src/main/kotlin/net/println/kotlin/mybatis/User.kt (100%) rename {code => legacy/code}/MyBatisIssue/src/main/kotlin/net/println/kotlin/mybatis/UserMapper.java (100%) rename {code => legacy/code}/MyBatisIssue/src/main/kotlin/net/println/kotlin/mybatis/annotations/PoKo.kt (100%) rename {code => legacy/code}/MyBatisIssue/src/main/resources/net/println/kotlin/mybatis/UserMapper.xml (100%) rename {code => legacy/code}/MyBatisIssue/src/main/resources/net/println/kotlin/mybatis/config.xml (100%) rename {code => legacy/code}/MyBatisIssue/src/main/resources/net/println/kotlin/mybatis/db.properties (100%) rename {code => legacy/code}/MyBatisIssue/src/main/resources/net/println/kotlin/mybatis/userinfo.sql (100%) rename {code => legacy/code}/RealmIssue/.gitignore (100%) rename {code => legacy/code}/RealmIssue/app/.gitignore (100%) rename {code => legacy/code}/RealmIssue/app/build.gradle (100%) rename {code => legacy/code}/RealmIssue/app/proguard-rules.pro (100%) rename {code => legacy/code}/RealmIssue/app/src/main/AndroidManifest.xml (100%) rename {code => legacy/code}/RealmIssue/app/src/main/java/net/println/kotlin/realm/App.kt (100%) rename {code => legacy/code}/RealmIssue/app/src/main/java/net/println/kotlin/realm/MainActivity.kt (100%) rename {code => legacy/code}/RealmIssue/app/src/main/java/net/println/kotlin/realm/PoKo.kt (100%) rename {code => legacy/code}/RealmIssue/app/src/main/java/net/println/kotlin/realm/User.kt (100%) rename {code => legacy/code}/RealmIssue/app/src/main/res/layout/activity_main.xml (100%) rename {code => legacy/code}/RealmIssue/app/src/main/res/mipmap-hdpi/ic_launcher.png (100%) rename {code => legacy/code}/RealmIssue/app/src/main/res/mipmap-hdpi/ic_launcher_round.png (100%) rename {code => legacy/code}/RealmIssue/app/src/main/res/mipmap-mdpi/ic_launcher.png (100%) rename {code => legacy/code}/RealmIssue/app/src/main/res/mipmap-mdpi/ic_launcher_round.png (100%) rename {code => legacy/code}/RealmIssue/app/src/main/res/mipmap-xhdpi/ic_launcher.png (100%) rename {code => legacy/code}/RealmIssue/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png (100%) rename {code => legacy/code}/RealmIssue/app/src/main/res/mipmap-xxhdpi/ic_launcher.png (100%) rename {code => legacy/code}/RealmIssue/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png (100%) rename {code => legacy/code}/RealmIssue/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png (100%) rename {code => legacy/code}/RealmIssue/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png (100%) rename {code => legacy/code}/RealmIssue/app/src/main/res/values/colors.xml (100%) rename {code => legacy/code}/RealmIssue/app/src/main/res/values/strings.xml (100%) rename {code => legacy/code}/RealmIssue/app/src/main/res/values/styles.xml (100%) rename {code => legacy/code}/RealmIssue/build.gradle (100%) rename {code => legacy/code}/RealmIssue/gradle.properties (100%) rename {code => legacy/code}/RealmIssue/gradle/wrapper/gradle-wrapper.jar (100%) rename {code => legacy/code}/RealmIssue/gradle/wrapper/gradle-wrapper.properties (100%) rename {code => legacy/code}/RealmIssue/gradlew (100%) rename {code => legacy/code}/RealmIssue/gradlew.bat (100%) rename {code => legacy/code}/RealmIssue/settings.gradle (100%) rename {code => legacy/code}/kt07/build.gradle (100%) rename {code => legacy/code}/kt07/gradle/wrapper/gradle-wrapper.jar (100%) rename {code => legacy/code}/kt07/gradle/wrapper/gradle-wrapper.properties (100%) rename {code => legacy/code}/kt07/gradlew (100%) rename {code => legacy/code}/kt07/gradlew.bat (100%) rename {code => legacy/code}/kt07/settings.gradle (100%) rename {code => legacy/code}/kt07/src/main/Resources/input (100%) rename {code => legacy/code}/kt07/src/main/java/net/println/kt07/Lambda.kt (100%) rename "script/14 Kotlin \344\270\216 Java \345\205\261\345\255\230\357\274\2101\357\274\211.md" => "legacy/script/14 Kotlin \344\270\216 Java \345\205\261\345\255\230\357\274\2101\357\274\211.md" (100%) rename "script/15 Kotlin \344\270\216 Java \345\205\261\345\255\230 (2).md" => "legacy/script/15 Kotlin \344\270\216 Java \345\205\261\345\255\230 (2).md" (100%) rename "script/Kt01 \347\256\200\344\273\213.pptx" => "legacy/script/Kt01 \347\256\200\344\273\213.pptx" (100%) rename "script/Kt12 \350\247\243\346\236\220Json\346\225\260\346\215\256.key" => "legacy/script/Kt12 \350\247\243\346\236\220Json\346\225\260\346\215\256.key" (100%) rename "script/Kt12 \351\235\242\345\220\221\345\257\271\350\261\241\347\232\204\345\207\240\344\270\252\346\246\202\345\277\265.key" => "legacy/script/Kt12 \351\235\242\345\220\221\345\257\271\350\261\241\347\232\204\345\207\240\344\270\252\346\246\202\345\277\265.key" (100%) rename "script/Kt14 Kotlin \344\270\216 Java \345\205\261\345\255\230(\344\270\200).potx" => "legacy/script/Kt14 Kotlin \344\270\216 Java \345\205\261\345\255\230(\344\270\200).potx" (100%) diff --git a/README.md b/README.md index 837f25a..fd517bd 100644 --- a/README.md +++ b/README.md @@ -1,211 +1,76 @@ [![GitHub license](https://img.shields.io/badge/license-CC%20BY--NC--ND%204.0-blue.svg)](https://creativecommons.org/licenses/by-nc-nd/4.0/) -# 2021 新计划 +[TOC] -准备做一个长期的 Kotlin 基础教程的编撰工作,作为官方文档的补充,大家有想法欢迎开 issue 跟我一起讨论。 +# Kotlin-Tutorials -### 内容目标(暂定): +**2021.6 更新** -1. 主线内容涵盖 Kotlin common、Kotlin Jvm、Kotlin js、Kotlin Native,通用部分则不依赖 Kotlin Jvm(不像过去大家习惯的方式) -2. Kotlin 的常见库的使用方法 -3. 编译器配置、Gradle DSL 等等 +这个仓库最初(2016年底)是用来分享一些 Kotlin 教程的,感兴趣的话可以查看[这里](legacy/README.md)。后来随着 Google 的大力支持,Kotlin 已经逐步在 Android 开发领域占据了一席之地。我就以个人经历来说说自己的感受吧: -### 输出形式: +过去几年我所在的[腾讯公司](https://www.tencent.com)当中,Kotlin 的落地项目实际上已经相当可观,例如: +* 外部开源的 Android 插件化框架 [Shadow](https://github.com/Tencent/Shadow),核心逻辑基本上使用 Kotlin 编写。 +* [蓝鲸 CI 平台](https://github.com/Tencent/bk-ci),这是一个后端项目,在腾讯内部已经成为公司主推的 CI 平台,之前我在上面做持续集成时需要二次开发,惊喜地发现打印出来的调用堆栈居然有 Kotlin 身影。 +* 内部还有团队使用 KMM 做跨平台的 UI 控件渲染,这可以说时非常有挑战的工作了,不仅要在移动端支持 Android、iOS,还要同时支持桌面版。基于这个框架所属产品的体量,我们大概率已经是这套技术方案的用户了。 -1. GitBook(主要目标,配合官网) -2. 纸质书(不排除可能性) +今年初我因个人原因离开了鹅厂,去了[北京猿力科技有限公司(猿辅导)](https://www.yuanfudao.com/),不出所料,在这家号称**小而美**且**有技术追求**的公司当中,Kotlin 在项目上的应用已经相当广泛了,新代码很少能见到 Java 的身影(有需要内推的小伙伴可以找我)。 + +所以,作为“布道者”,过去我们总是想着怎么让更多的开发者知道 Kotlin,现在我们则需要提供更多的 Kotlin 的学习材料,来帮助大家更好的使用 Kotlin。 -### 时间安排 +我目前主要的想法就是做一些视频放到 B 站上(账号:[**bennyhuo 不是算命的**](https://space.bilibili.com/28615855)),当然视频的内容也不限于 Kotlin 本身。这个计划已经开始尝试实施了,内容的规划在这个仓库的 [issue](https://github.com/bennyhuo/Kotlin-Tutorials/issues) 当中跟进,例如前不久刚刚录制的几个 [Gradle 迁移 KTS 的视频](https://github.com/bennyhuo/Kotlin-Tutorials/issues/25)。 -1. 大纲梳理,整体初步构思 - 2021.4 之前 -2. 基础部分 - 待细化 -3. Jvm 部分 -4. Js 部分 -5. Native 部分 -6. 框架部分(ktor、datetime、serialization...) +还有一个相对长期的规划是做一套电子书,后面会在这个 [issue](https://github.com/bennyhuo/Kotlin-Tutorials/issues/36) 当中跟进,电子书的主体内容与我之前的课程 [Kotlin 从入门到精通 视频教程](http://coding.imooc.com/class/398.html) 会有一定程度上的重叠,但电子书的好处就是更新维护方便,相比之下视频教程制作成本太高且不易维护。 -# [新书《深入理解 Kotlin 协程》](https://www.bennyhuo.com/project/kotlin-coroutines.html) +有想法的小伙伴欢迎与我交流。 -Kotlin 协程可以说是截止目前为止 Kotlin 中最让人困惑的一部分内容了,官方文档也比较简略,对于初学者不够友好。今年我把过去在公众号和博客发布的协程相关的文章进行了整理和扩充,进一步完善了诸多细节编写了本书,有兴趣可以留意一下。 - -## 随书源码 +## 联系我 -本书**源码地址**:[《深入理解 Kotlin 协程》源码](https://github.com/enbandari/DiveIntoKotlinCoroutines-Sources) +* 邮箱: [bennyhuo@kotliner.cn](mailto:bennyhuo@kotliner.cn) +* B 站账号:[**bennyhuo 不是算命的**](https://space.bilibili.com/28615855),我个人的视频会优先在 B 站发布 +* 微信公众号 **Kotlin**,公众号主要用来发布 Kotlin 以及移动端开发相关的内容。 + +* 加入社区 QQ 群 + * Kotlin 中文社区群 大群:162452394 (已满) + * Kotlin 中文社区群 ① 群:603441485 (已满) + * Kotlin 中文社区群 ② 群:751395597 -## 购买途径 - -* 京东自营:[深入理解Kotlin协程](https://item.jd.com/12898592.html) -* 当当自营:[深入理解Kotlin协程](http://product.dangdang.com/28973005.html) +* 当然,**北京猿辅导**的小伙伴也可以找我面聊 :) -# [Kotlin 从入门到精通 视频教程](http://coding.imooc.com/class/398.html) +--- -Kotlin 1.3 是一个相对成熟和稳定的版本,这次基于 Kotlin 1.3.50 重新制作入门到精通的课程,相比之下新课知识点梳理更详细,内容干货更多,讲法也更成熟,希望能对大家有帮助。 +以下是这几年我的一些积累和产出,有兴趣可以关注。 -**视频地址:** [http://coding.imooc.com/class/398.html](http://coding.imooc.com/class/398.html) +## [《深入理解 Kotlin 协程》](https://www.bennyhuo.com/project/kotlin-coroutines.html) 2020.6 出版 +Kotlin 协程可以说是截止目前为止 Kotlin 中最让人困惑的一部分内容了,官方文档也比较简略,对于初学者不够友好。今年我把过去在公众号和博客发布的协程相关的文章进行了整理和扩充,进一步完善了诸多细节编写了本书,有兴趣可以留意一下。 -# [破解 Retrofit](https://www.imooc.com/learn/1128?mc_marking=5487b137ad904bd13590a053ede6da2f&mc_channel=syb19) +### 随书源码 -最近不少朋友反馈希望能看到一些深入分析框架的课程,正好前段时间对 Retrofit 又做了一次深入的分析,整理了一套免费视频分享给大家~ +本书**源码地址**:[《深入理解 Kotlin 协程》源码](https://github.com/enbandari/DiveIntoKotlinCoroutines-Sources) -# [破解Android高级面试](https://s.imooc.com/SBS30PR) +### 购买途径 -我一直做 Kotlin 的推广和宣传,发现大多数学习 Kotlin 的同学都是被行业“胁迫”不得不学。大家的诉求更多是怎么样找到一份好的工作,考虑到学习 Kotlin 的同学大多都是 Android 开发者,我就花了半年的功夫仔细整理了这一套视频出来,题目看上去不多,但每一个题目背后能引出的知识点可一点儿都不少。不求面面俱到,只求精准打击,面试过程中只要你能给面试官留下深刻的印象,那么这事儿就成了。 +* 京东自营:[深入理解Kotlin协程](https://item.jd.com/12898592.html) +* 当当自营:[深入理解Kotlin协程](http://product.dangdang.com/28973005.html) -# [注解处理器开发教程](https://github.com/enbandari/Apt-Tutorials) +## [注解处理器开发教程](https://github.com/enbandari/Apt-Tutorials) -我在做 [基于 GitHub App 业务深度讲解 Kotlin1.2高级特性与框架设计](https://coding.imooc.com/class/232.html) 这门课的时候,顺便做了一个注解处理器的框架,叫 [Tieguanyin(铁观音)](https://github.com/enbandari/TieGuanYin),这个框架主要是用来解决 Activity 跳转时传参的问题,我们知道 Activity 如果需要参数,那么我们只能非常繁琐的使用 `Intent` 来传递,有了这个框架我们就可以省去这个麻烦的步骤。 +我在做 [基于 GitHub App 业务深度讲解 Kotlin1.2高级特性与框架设计](https://coding.imooc.com/class/232.html)(目前已经下线) 这门课的时候,顺便做了一个注解处理器的框架,叫 [Tieguanyin(铁观音)](https://github.com/enbandari/TieGuanYin),这个框架主要是用来解决 Activity 跳转时传参的问题,我们知道 Activity 如果需要参数,那么我们只能非常繁琐的使用 `Intent` 来传递,有了这个框架我们就可以省去这个麻烦的步骤。 在这里,框架的内容其实不是重点,重点是,它是一个注解处理器的项目。为了让它的作用尽可能的放大,我对原框架做了简化,做了这套课程。 -# [基于 GitHub App 业务深度讲解 Kotlin1.2高级特性与框架设计](https://coding.imooc.com/class/232.html) - -我们在 2018年6月基于 Android 的开发环境推出了一套深入讲解 Kotlin 特性的课程,这套课程以大家最为熟悉的 GitHub App 开发作为整套课程的线索,将 Kotlin 的高级特性一一融入其中予以讲解,这其中我们对泛型、反射、属性代理、协程、Dsl 做了详尽的讲解和框架设计与开发,力求让大家能够对这些技能灵活运用。 - - -# [Kotlin从入门到『放弃』系列 视频教程](https://github.com/enbandari/Kotlin-Tutorials) - -**发现有人在淘宝店上卖这套视频哈,大家不要去买。。。直接在这里下载多好** - -随着Kotlin越来越成熟稳定,我已经开始在生产环境中使用它。考虑到目前国内资料较少,我录制了一套视频教程,希望以此抛砖引玉,让 Kotlin 在国内火起来。 - -个人水平有限,不足之处欢迎大家发邮件到 [bennyhuo@println.net](mailto: bennyhuo@println.net) ,谢谢大家! - -# 介绍 - -视频从2016年10月初开始发布,更新至12月中旬完结。精力有限,后续暂时每周一通过公众号推送 Kotlin 及 Java 生态的一些文章,大家有选题也可以直接联系我,目前已经有两篇是基于大家的反馈撰写的,反馈也比较不错,谢谢大家的关注与支持。 - -[在线收看全部视频(腾讯视频)](http://v.qq.com/boke/gplay/903446d6231d8612d198c58fb86eb4dc_t6d000101bd9lx1.html) - -[下载全部视频(百度云)](http://pan.baidu.com/s/1nvGYAfB) - -# 目录 - -#### [01 Kotlin 简介](http://v.qq.com/page/z/u/9/z0337i7a3u9.html) - -  简要介绍下什么是 Kotlin,新语言太多了,大家为什么要接触 Kotlin 呢?因为它除了长得与 Java 不太像以外,其他的都差不多~ -   - -#### [02 Hello World](http://v.qq.com/page/h/n/m/h0337jfa5nm.html) - -  千里之行,始于Hello World! -   - -#### [03 使用Gradle编写程序简介(可选)](http://v.qq.com/page/b/p/l/b03372ox4pl.html) - -  这年头,写 Java 系的代码,不知道 Gradle 怎么行呢? -   - -#### [04 集合遍历 map](http://v.qq.com/page/s/q/c/s033707mdqc.html) - -  放下 i++,你不知道 map 已经占领世界了么?以前我以为 map-reduce 很牛逼,后来才知道就是数据迭代处理嘛。 -   - -#### [05 集合扁平化 flatMap](http://v.qq.com/page/h/u/7/h0337scgau7.html) - -  这个可以说是 map 的一个加强版,返回的仍然是开一个可迭代的集合,用哪个您自己看需求~ -   - -#### [06 枚举类型与When表达式](http://v.qq.com/page/t/0/9/t0337iacg09.html) - -  Kotlin 丢掉了 switch,却引进了 when,这二者看上去极其相似,不过后者却要强大得多。至于枚举嘛,还是 Java 枚举的老样子。 - - -#### [07 在 RxJava 中使用 Lambda](http://v.qq.com/x/page/l0340boeng7.html) - -  这一期通过一个统计文章中字符数的小程序进一步给大家呈现 Lambda 的威力,也向大家展示一下如何在 Kotlin 当中优雅地使用 RxJava。我不做教科书,所以如果大家对概念感兴趣,可以直接阅读官方 [API](https://kotlinlang.org/docs/reference/lambdas.html) - -  [RxJava](https://github.com/ReactiveX/RxJava) 是一个非常流行的 Java Reactive 框架,函数式的数据操作使得 Lambda 表达式可以充分体现自己的优势,比起 Java 的冗长,你会看到一段非常漂亮简洁的代码。建议大家先阅读 [RxJava](https://github.com/ReactiveX/RxJava) 的官方文章以对其有一些基本的认识。 -   - -#### [08 使用 Retrofit 发送 GET 请求](http://v.qq.com/x/page/t0342thu1al.html) - -  [Retrofit](https://square.github.io/retrofit/) 是 Square 的 Jake 大神开源的RESTful 网络请求框架,用它发送请求的感觉会让你感觉爽爆的。我这里还有几篇文章,以及一个我 hack 过的分支 [HackRetrofit](https://github.com/enbandari/HackRetrofit),有兴趣的童鞋可以一起探讨下~ - - -* [Android 下午茶:Hack Retrofit 之 增强参数](http://www.println.net/post/Android-Hack-Retrofit). +## [Kotlin 从入门到精通 视频教程](http://coding.imooc.com/class/398.html) -* [Android 下午茶:Hack Retrofit (2) 之 Mock Server](http://www.println.net/post/Android-Hack-Retrofit-Mock-Server) - -* [深入浅出 Retrofit,这么牛逼的框架你们还不来看看?](http://www.println.net/post/deep-in-retrofit) - - -#### [09 尾递归优化](http://v.qq.com/x/page/f0345wmuw2m.html) - -  尾递归,顾名思义,就是递归中调用自身的部分在函数体的最后一句。我们知道,递归调用对于栈大小的考验是非常大的,也经常会因为这个导致 StackOverflow,所以尾递归优化也是大家比较关注的一个话题。Kotlin 支持语法层面的尾递归优化,这在其他语言里面是不多见的。 - - -#### [10 单例](https://v.qq.com/x/page/w03659ate6w.html) - -  单例大家一定都不陌生,只要你动手写一个程序,就免不了要设计出一些全局存在且唯一的对象,他们就适合采用单例模式编写。在 Java 里面,单例模式的写法常见的有好几种,虽然简单却也是涉及了一些有意思的话题,那么在 Kotlin 当中我们要怎么设计单例程序呢? - - -#### [11 Sealed Class](https://v.qq.com/x/page/f0350ioskzj.html) -  枚举类型可以很好的限制一个类型的实例个数,比如 State 枚举有两种类型 IDLE 和 BUSY 两种状态,用枚举来描述再合适不过。不过,如果你想要设计子类个数有限的数据结构,比如指令,指令的类型通常是确定的,不过对于某些有参数的指令每一次都使用同一个实例反而不合适,这时候就需要 Sealed Class。 -   -   -#### [12 Json数据引发的血案](https://v.qq.com/x/page/s035296s9nw.html) -  Json 数据可真是大红大紫一番,它实在是太容易理解了,随着 Js 的火爆它就更加『肆无忌惮』起来。我们在 Java/Kotlin 当中解析它的时候经常会用到 Gson 这个库,用它来解析数据究竟会遇到哪些问题?本期主要围绕 Json 解析的几个小例子,给大家展示一下 Java/Kotlin 的伪泛型设计的问题,以及不完整的数据的解析对语言本身特性的冲击。 - - -#### [13 kapt 以及它的小伙伴们](https://v.qq.com/x/page/q035439xksx.html) - -  首先感谢 @CodingPapi,这一期的内容主要来自于他的建议。 - -  Kotiln 对于注解的支持情况在今年(2016)取得了较大的成果,现在除了对 @Inherited 这个注解的支持还不够之外,试用了一下没有发现太大的问题。关于 kapt,官方的文章罗列下来,其中 - -* [kapt: Annotation Processing for Kotlin -](https://blog.jetbrains.com/kotlin/2015/05/kapt-annotation-processing-for-kotlin/) 已经过时了,大家可以阅读下了解其中提到的三个方案 - -* [Better Annotation Processing: Supporting Stubs in kapt -](https://blog.jetbrains.com/kotlin/2015/06/better-annotation-processing-supporting-stubs-in-kapt/) 提到的实现其实基本上就是现在的正式版 - -* [Kotlin 1.0.4 is here -](https://blog.jetbrains.com/kotlin/2016/09/kotlin-1-0-4-is-here/)提到了 kapt 的正式发布,需要注意的是,kapt 的使用方法有些变化,需要 ```apply plugin: 'kotlin-kapt'``` - -  本期主要通过一个简单的 [Dagger2](https://google.github.io/dagger/) 实例给大家展示了注解在 Kotlin 当中的使用,看上去其实与在 Java 中使用区别不大,生成的源码也暂时是 Java 代码,不过这都不重要了,反正是要编译成 class 文件的。 - -  后面我们又简单分析了一下 Dagger2 以及 [ButterKnife](https://github.com/JakeWharton/butterknife) 的源码(有兴趣的话也可以看下我直接对后者进行分析和 Hack 的一篇文章:[深入浅出 ButterKnife,听说你还在 findViewById?](http://www.println.net/post/Deep-in-ButterKnife-3)),其实自己实现一个注解处理器是非常容易的,类似的框架还有[androidannotations](https://github.com/androidannotations/androidannotations),它的源码大家可以自行阅读。 - -**** -通过这个例子,我们其实发现 kapt 还是有一些不完善的地方,主要是: - -1. 不支持 @Inherited -2. 生成的源码需要手动添加到 SourceSets 中 -3. 编译时有时候需要手动操作一下 gradle 的 build 才能生成源码(这一点大家注意下就行了,我在视频中并没有提到) - -不过总体来讲,kapt 的现状还是不错的,相信不久的将来这些问题都将不是问题。 -**** - -#### [14 Kotlin 与 Java 共存 (1)](https://v.qq.com/x/page/c03579nzo8x.html) - -  你想要追求代码简洁、美观、精致,你应该倾向于使用 Kotlin,而如果你想要追求代码的功能强大,甚至有些黑科技的感觉,那 Java 还是当仁不让的。 - -  说了这么多,还是那句话,让他们共存,各取所长。 - -  那么问题来了,怎么共存呢?虽然一说理论我们都知道,跑在 Jvm 上面的语言最终都是要编成 class 文件的,在这个层面大家都是 Java 虚拟机的字节码,可他们在编译之前毕竟还是有不少差异的,这可如何是好? - -  正所谓兵来将挡水来土掩,有多少差异,就要有多少对策,这一期我们先讲**在 Java 中调用 Kotlin**。 - - -#### [15 Kotlin 与 Java 共存 (2)](https://v.qq.com/x/page/z0357ls85fe.html) - -  上一期我们简单讨论了几个 Java 调用 Kotlin 的场景,这一期我们主要讨论相反的情况:如何在 Kotlin 当中调用 Java 代码。 - -  除了视频中提到的点之外还有一些细节,比如异常的捕获,集合类型的映射等等,大家自行参考官方文档即可。在了解了这些之后,你就可以放心大胆的在你的项目中慢慢渗透 Kotlin,让你的代码逐渐走向简洁与精致了。 - -# 获取最新动态 - -关注微信公众号:Kotlin, 获取最新视频更新动态 +Kotlin 1.3 是一个相对成熟和稳定的版本,这次基于 Kotlin 1.3.50 重新制作入门到精通的课程,相比之下新课知识点梳理更详细,内容干货更多,讲法也更成熟,希望能对大家有帮助。 - +**视频地址:** [http://coding.imooc.com/class/398.html](http://coding.imooc.com/class/398.html) -加入社区 QQ 群: +## [破解 Retrofit](https://www.imooc.com/learn/1128?mc_marking=5487b137ad904bd13590a053ede6da2f&mc_channel=syb19) -Kotlin 中文社区群 大群:162452394 (已满) +最近不少朋友反馈希望能看到一些深入分析框架的课程,正好前段时间对 Retrofit 又做了一次深入的分析,整理了一套免费视频分享给大家~ -Kotlin 中文社区群 ① 群:603441485 (已满) +## [破解Android高级面试](https://s.imooc.com/SBS30PR) -Kotlin 中文社区群 ② 群:751395597 +我一直做 Kotlin 的推广和宣传,发现大多数学习 Kotlin 的同学都是被行业“胁迫”不得不学。大家的诉求更多是怎么样找到一份好的工作,考虑到学习 Kotlin 的同学大多都是 Android 开发者,我就花了半年的功夫仔细整理了这一套视频出来,题目看上去不多,但每一个题目背后能引出的知识点可一点儿都不少。不求面面俱到,只求精准打击,面试过程中只要你能给面试官留下深刻的印象,那么这事儿就成了。 diff --git a/docs/Dive-into-Kotlin-Coroutines.md b/docs/Dive-into-Kotlin-Coroutines.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/Tutorials-IMOOC.md b/docs/Tutorials-IMOOC.md new file mode 100644 index 0000000..e69de29 diff --git a/legacy/README.md b/legacy/README.md new file mode 100644 index 0000000..79f67ac --- /dev/null +++ b/legacy/README.md @@ -0,0 +1,128 @@ +# [Kotlin从入门到『放弃』系列 视频教程](https://github.com/enbandari/Kotlin-Tutorials) + +随着Kotlin越来越成熟稳定,我已经开始在生产环境中使用它。考虑到目前国内资料较少,我录制了一套视频教程,希望以此抛砖引玉,让 Kotlin 在国内火起来。 + +个人水平有限,不足之处欢迎大家发邮件到 [bennyhuo@println.net](mailto: bennyhuo@println.net) ,谢谢大家! + +# 介绍 + +视频从2016年10月初开始发布,更新至12月中旬完结。精力有限,后续暂时每周一通过公众号推送 Kotlin 及 Java 生态的一些文章,大家有选题也可以直接联系我,目前已经有两篇是基于大家的反馈撰写的,反馈也比较不错,谢谢大家的关注与支持。 + +[在线收看全部视频(腾讯视频)](http://v.qq.com/boke/gplay/903446d6231d8612d198c58fb86eb4dc_t6d000101bd9lx1.html) + +[下载全部视频(百度云)](http://pan.baidu.com/s/1nvGYAfB) + +# 目录 + +#### [01 Kotlin 简介](http://v.qq.com/page/z/u/9/z0337i7a3u9.html) + +  简要介绍下什么是 Kotlin,新语言太多了,大家为什么要接触 Kotlin 呢?因为它除了长得与 Java 不太像以外,其他的都差不多~ +   + +#### [02 Hello World](http://v.qq.com/page/h/n/m/h0337jfa5nm.html) + +  千里之行,始于Hello World! +   + +#### [03 使用Gradle编写程序简介(可选)](http://v.qq.com/page/b/p/l/b03372ox4pl.html) + +  这年头,写 Java 系的代码,不知道 Gradle 怎么行呢? +   + +#### [04 集合遍历 map](http://v.qq.com/page/s/q/c/s033707mdqc.html) + +  放下 i++,你不知道 map 已经占领世界了么?以前我以为 map-reduce 很牛逼,后来才知道就是数据迭代处理嘛。 +   + +#### [05 集合扁平化 flatMap](http://v.qq.com/page/h/u/7/h0337scgau7.html) + +  这个可以说是 map 的一个加强版,返回的仍然是开一个可迭代的集合,用哪个您自己看需求~ +   + +#### [06 枚举类型与When表达式](http://v.qq.com/page/t/0/9/t0337iacg09.html) + +  Kotlin 丢掉了 switch,却引进了 when,这二者看上去极其相似,不过后者却要强大得多。至于枚举嘛,还是 Java 枚举的老样子。 + + +#### [07 在 RxJava 中使用 Lambda](http://v.qq.com/x/page/l0340boeng7.html) + +  这一期通过一个统计文章中字符数的小程序进一步给大家呈现 Lambda 的威力,也向大家展示一下如何在 Kotlin 当中优雅地使用 RxJava。我不做教科书,所以如果大家对概念感兴趣,可以直接阅读官方 [API](https://kotlinlang.org/docs/reference/lambdas.html) + +  [RxJava](https://github.com/ReactiveX/RxJava) 是一个非常流行的 Java Reactive 框架,函数式的数据操作使得 Lambda 表达式可以充分体现自己的优势,比起 Java 的冗长,你会看到一段非常漂亮简洁的代码。建议大家先阅读 [RxJava](https://github.com/ReactiveX/RxJava) 的官方文章以对其有一些基本的认识。 +   + +#### [08 使用 Retrofit 发送 GET 请求](http://v.qq.com/x/page/t0342thu1al.html) + +  [Retrofit](https://square.github.io/retrofit/) 是 Square 的 Jake 大神开源的RESTful 网络请求框架,用它发送请求的感觉会让你感觉爽爆的。我这里还有几篇文章,以及一个我 hack 过的分支 [HackRetrofit](https://github.com/enbandari/HackRetrofit),有兴趣的童鞋可以一起探讨下~ + + +* [Android 下午茶:Hack Retrofit 之 增强参数](https://zhuanlan.zhihu.com/p/20863588)). + +* [Android 下午茶:Hack Retrofit (2) 之 Mock Server](https://www.zhihu.com/column/p/21364346) + +* [深入浅出 Retrofit,这么牛逼的框架你们还不来看看?](https://zhuanlan.zhihu.com/p/21808012) + + +#### [09 尾递归优化](http://v.qq.com/x/page/f0345wmuw2m.html) + +  尾递归,顾名思义,就是递归中调用自身的部分在函数体的最后一句。我们知道,递归调用对于栈大小的考验是非常大的,也经常会因为这个导致 StackOverflow,所以尾递归优化也是大家比较关注的一个话题。Kotlin 支持语法层面的尾递归优化,这在其他语言里面是不多见的。 + + +#### [10 单例](https://v.qq.com/x/page/w03659ate6w.html) + +  单例大家一定都不陌生,只要你动手写一个程序,就免不了要设计出一些全局存在且唯一的对象,他们就适合采用单例模式编写。在 Java 里面,单例模式的写法常见的有好几种,虽然简单却也是涉及了一些有意思的话题,那么在 Kotlin 当中我们要怎么设计单例程序呢? + + +#### [11 Sealed Class](https://v.qq.com/x/page/f0350ioskzj.html) +  枚举类型可以很好的限制一个类型的实例个数,比如 State 枚举有两种类型 IDLE 和 BUSY 两种状态,用枚举来描述再合适不过。不过,如果你想要设计子类个数有限的数据结构,比如指令,指令的类型通常是确定的,不过对于某些有参数的指令每一次都使用同一个实例反而不合适,这时候就需要 Sealed Class。 +   +   +#### [12 Json数据引发的血案](https://v.qq.com/x/page/s035296s9nw.html) +  Json 数据可真是大红大紫一番,它实在是太容易理解了,随着 Js 的火爆它就更加『肆无忌惮』起来。我们在 Java/Kotlin 当中解析它的时候经常会用到 Gson 这个库,用它来解析数据究竟会遇到哪些问题?本期主要围绕 Json 解析的几个小例子,给大家展示一下 Java/Kotlin 的伪泛型设计的问题,以及不完整的数据的解析对语言本身特性的冲击。 + + +#### [13 kapt 以及它的小伙伴们](https://v.qq.com/x/page/q035439xksx.html) + +  首先感谢 @CodingPapi,这一期的内容主要来自于他的建议。 + +  Kotiln 对于注解的支持情况在今年(2016)取得了较大的成果,现在除了对 @Inherited 这个注解的支持还不够之外,试用了一下没有发现太大的问题。关于 kapt,官方的文章罗列下来,其中 + +* [kapt: Annotation Processing for Kotlin +](https://blog.jetbrains.com/kotlin/2015/05/kapt-annotation-processing-for-kotlin/) 已经过时了,大家可以阅读下了解其中提到的三个方案 + +* [Better Annotation Processing: Supporting Stubs in kapt +](https://blog.jetbrains.com/kotlin/2015/06/better-annotation-processing-supporting-stubs-in-kapt/) 提到的实现其实基本上就是现在的正式版 + +* [Kotlin 1.0.4 is here +](https://blog.jetbrains.com/kotlin/2016/09/kotlin-1-0-4-is-here/)提到了 kapt 的正式发布,需要注意的是,kapt 的使用方法有些变化,需要 ```apply plugin: 'kotlin-kapt'``` + +  本期主要通过一个简单的 [Dagger2](https://google.github.io/dagger/) 实例给大家展示了注解在 Kotlin 当中的使用,看上去其实与在 Java 中使用区别不大,生成的源码也暂时是 Java 代码,不过这都不重要了,反正是要编译成 class 文件的。 + +  后面我们又简单分析了一下 Dagger2 以及 [ButterKnife](https://github.com/JakeWharton/butterknife) 的源码(有兴趣的话也可以看下我直接对后者进行分析和 Hack 的一篇文章:[深入浅出 ButterKnife,听说你还在 findViewById?](http://www.println.net/post/Deep-in-ButterKnife-3)),其实自己实现一个注解处理器是非常容易的,类似的框架还有[androidannotations](https://github.com/androidannotations/androidannotations),它的源码大家可以自行阅读。 + +**** +通过这个例子,我们其实发现 kapt 还是有一些不完善的地方,主要是: + +1. 不支持 @Inherited +2. 生成的源码需要手动添加到 SourceSets 中 +3. 编译时有时候需要手动操作一下 gradle 的 build 才能生成源码(这一点大家注意下就行了,我在视频中并没有提到) + +不过总体来讲,kapt 的现状还是不错的,相信不久的将来这些问题都将不是问题。 +**** + +#### [14 Kotlin 与 Java 共存 (1)](https://v.qq.com/x/page/c03579nzo8x.html) + +  你想要追求代码简洁、美观、精致,你应该倾向于使用 Kotlin,而如果你想要追求代码的功能强大,甚至有些黑科技的感觉,那 Java 还是当仁不让的。 + +  说了这么多,还是那句话,让他们共存,各取所长。 + +  那么问题来了,怎么共存呢?虽然一说理论我们都知道,跑在 Jvm 上面的语言最终都是要编成 class 文件的,在这个层面大家都是 Java 虚拟机的字节码,可他们在编译之前毕竟还是有不少差异的,这可如何是好? + +  正所谓兵来将挡水来土掩,有多少差异,就要有多少对策,这一期我们先讲**在 Java 中调用 Kotlin**。 + + +#### [15 Kotlin 与 Java 共存 (2)](https://v.qq.com/x/page/z0357ls85fe.html) + +  上一期我们简单讨论了几个 Java 调用 Kotlin 的场景,这一期我们主要讨论相反的情况:如何在 Kotlin 当中调用 Java 代码。 + +  除了视频中提到的点之外还有一些细节,比如异常的捕获,集合类型的映射等等,大家自行参考官方文档即可。在了解了这些之后,你就可以放心大胆的在你的项目中慢慢渗透 Kotlin,让你的代码逐渐走向简洁与精致了。 \ No newline at end of file diff --git "a/articles/2016.12.26 Kotlin \345\246\202\344\275\225\344\274\230\351\233\205\347\232\204\345\256\236\347\216\260\343\200\216\345\244\232\347\273\247\346\211\277\343\200\217.md" "b/legacy/articles/2016.12.26 Kotlin \345\246\202\344\275\225\344\274\230\351\233\205\347\232\204\345\256\236\347\216\260\343\200\216\345\244\232\347\273\247\346\211\277\343\200\217.md" similarity index 100% rename from "articles/2016.12.26 Kotlin \345\246\202\344\275\225\344\274\230\351\233\205\347\232\204\345\256\236\347\216\260\343\200\216\345\244\232\347\273\247\346\211\277\343\200\217.md" rename to "legacy/articles/2016.12.26 Kotlin \345\246\202\344\275\225\344\274\230\351\233\205\347\232\204\345\256\236\347\216\260\343\200\216\345\244\232\347\273\247\346\211\277\343\200\217.md" diff --git a/articles/2016.12.26.jpg b/legacy/articles/2016.12.26.jpg similarity index 100% rename from articles/2016.12.26.jpg rename to legacy/articles/2016.12.26.jpg diff --git a/articles/2017.1.16/cover.jpg b/legacy/articles/2017.1.16/cover.jpg similarity index 100% rename from articles/2017.1.16/cover.jpg rename to legacy/articles/2017.1.16/cover.jpg diff --git "a/articles/2017.1.16/\347\224\250 Kotlin \345\206\231 Android 01 \351\232\276\351\201\223\345\217\252\346\234\211\347\216\257\345\242\203\346\220\255\345\273\272\350\277\231\344\271\210\347\256\200\345\215\225\357\274\237.md" "b/legacy/articles/2017.1.16/\347\224\250 Kotlin \345\206\231 Android 01 \351\232\276\351\201\223\345\217\252\346\234\211\347\216\257\345\242\203\346\220\255\345\273\272\350\277\231\344\271\210\347\256\200\345\215\225\357\274\237.md" similarity index 100% rename from "articles/2017.1.16/\347\224\250 Kotlin \345\206\231 Android 01 \351\232\276\351\201\223\345\217\252\346\234\211\347\216\257\345\242\203\346\220\255\345\273\272\350\277\231\344\271\210\347\256\200\345\215\225\357\274\237.md" rename to "legacy/articles/2017.1.16/\347\224\250 Kotlin \345\206\231 Android 01 \351\232\276\351\201\223\345\217\252\346\234\211\347\216\257\345\242\203\346\220\255\345\273\272\350\277\231\344\271\210\347\256\200\345\215\225\357\274\237.md" diff --git a/articles/2017.1.2/17.1.2.jpg b/legacy/articles/2017.1.2/17.1.2.jpg similarity index 100% rename from articles/2017.1.2/17.1.2.jpg rename to legacy/articles/2017.1.2/17.1.2.jpg diff --git a/articles/2017.1.2/17.1.2b.jpg b/legacy/articles/2017.1.2/17.1.2b.jpg similarity index 100% rename from articles/2017.1.2/17.1.2b.jpg rename to legacy/articles/2017.1.2/17.1.2b.jpg diff --git a/articles/2017.1.2/Kotlin 1.0.6.md b/legacy/articles/2017.1.2/Kotlin 1.0.6.md similarity index 100% rename from articles/2017.1.2/Kotlin 1.0.6.md rename to legacy/articles/2017.1.2/Kotlin 1.0.6.md diff --git a/articles/2017.1.2/args.gif b/legacy/articles/2017.1.2/args.gif similarity index 100% rename from articles/2017.1.2/args.gif rename to legacy/articles/2017.1.2/args.gif diff --git a/articles/2017.1.2/try.gif b/legacy/articles/2017.1.2/try.gif similarity index 100% rename from articles/2017.1.2/try.gif rename to legacy/articles/2017.1.2/try.gif diff --git "a/articles/2017.1.2/\345\203\217\345\206\231\346\226\207\347\253\240\344\270\200\346\240\267\344\275\277\347\224\250 Kotlin.md" "b/legacy/articles/2017.1.2/\345\203\217\345\206\231\346\226\207\347\253\240\344\270\200\346\240\267\344\275\277\347\224\250 Kotlin.md" similarity index 100% rename from "articles/2017.1.2/\345\203\217\345\206\231\346\226\207\347\253\240\344\270\200\346\240\267\344\275\277\347\224\250 Kotlin.md" rename to "legacy/articles/2017.1.2/\345\203\217\345\206\231\346\226\207\347\253\240\344\270\200\346\240\267\344\275\277\347\224\250 Kotlin.md" diff --git a/articles/2017.1.21/1.1-Beta-Banner-2-01.png b/legacy/articles/2017.1.21/1.1-Beta-Banner-2-01.png similarity index 100% rename from articles/2017.1.21/1.1-Beta-Banner-2-01.png rename to legacy/articles/2017.1.21/1.1-Beta-Banner-2-01.png diff --git a/articles/2017.1.21/check.png b/legacy/articles/2017.1.21/check.png similarity index 100% rename from articles/2017.1.21/check.png rename to legacy/articles/2017.1.21/check.png diff --git a/articles/2017.1.21/choose.png b/legacy/articles/2017.1.21/choose.png similarity index 100% rename from articles/2017.1.21/choose.png rename to legacy/articles/2017.1.21/choose.png diff --git a/articles/2017.1.21/houzi.png b/legacy/articles/2017.1.21/houzi.png similarity index 100% rename from articles/2017.1.21/houzi.png rename to legacy/articles/2017.1.21/houzi.png diff --git "a/articles/2017.1.21/\345\226\234\345\244\247\346\231\256\345\245\224\357\274\201Kotlin 1.1 Beta \351\231\215\344\270\264~.md" "b/legacy/articles/2017.1.21/\345\226\234\345\244\247\346\231\256\345\245\224\357\274\201Kotlin 1.1 Beta \351\231\215\344\270\264~.md" similarity index 100% rename from "articles/2017.1.21/\345\226\234\345\244\247\346\231\256\345\245\224\357\274\201Kotlin 1.1 Beta \351\231\215\344\270\264~.md" rename to "legacy/articles/2017.1.21/\345\226\234\345\244\247\346\231\256\345\245\224\357\274\201Kotlin 1.1 Beta \351\231\215\344\270\264~.md" diff --git "a/articles/2017.1.23/[\347\224\250 Kotlin \345\206\231 Android] 02 \350\257\264\350\257\264 Anko.md" "b/legacy/articles/2017.1.23/[\347\224\250 Kotlin \345\206\231 Android] 02 \350\257\264\350\257\264 Anko.md" similarity index 100% rename from "articles/2017.1.23/[\347\224\250 Kotlin \345\206\231 Android] 02 \350\257\264\350\257\264 Anko.md" rename to "legacy/articles/2017.1.23/[\347\224\250 Kotlin \345\206\231 Android] 02 \350\257\264\350\257\264 Anko.md" diff --git a/articles/2017.1.23/cover.jpg b/legacy/articles/2017.1.23/cover.jpg similarity index 100% rename from articles/2017.1.23/cover.jpg rename to legacy/articles/2017.1.23/cover.jpg diff --git a/articles/2017.1.23/linear.png b/legacy/articles/2017.1.23/linear.png similarity index 100% rename from articles/2017.1.23/linear.png rename to legacy/articles/2017.1.23/linear.png diff --git a/articles/2017.1.23/relative.png b/legacy/articles/2017.1.23/relative.png similarity index 100% rename from articles/2017.1.23/relative.png rename to legacy/articles/2017.1.23/relative.png diff --git a/articles/2017.1.30/coroutine_cover.jpg b/legacy/articles/2017.1.30/coroutine_cover.jpg similarity index 100% rename from articles/2017.1.30/coroutine_cover.jpg rename to legacy/articles/2017.1.30/coroutine_cover.jpg diff --git a/articles/2017.1.30/coroutine_lua.png b/legacy/articles/2017.1.30/coroutine_lua.png similarity index 100% rename from articles/2017.1.30/coroutine_lua.png rename to legacy/articles/2017.1.30/coroutine_lua.png diff --git a/articles/2017.1.30/cr0.png b/legacy/articles/2017.1.30/cr0.png similarity index 100% rename from articles/2017.1.30/cr0.png rename to legacy/articles/2017.1.30/cr0.png diff --git a/articles/2017.1.30/cr1.png b/legacy/articles/2017.1.30/cr1.png similarity index 100% rename from articles/2017.1.30/cr1.png rename to legacy/articles/2017.1.30/cr1.png diff --git a/articles/2017.1.30/cr2.png b/legacy/articles/2017.1.30/cr2.png similarity index 100% rename from articles/2017.1.30/cr2.png rename to legacy/articles/2017.1.30/cr2.png diff --git a/articles/2017.1.30/mdhere.gif b/legacy/articles/2017.1.30/mdhere.gif similarity index 100% rename from articles/2017.1.30/mdhere.gif rename to legacy/articles/2017.1.30/mdhere.gif diff --git "a/articles/2017.1.30/\345\213\230\350\257\257\357\274\23215 Kotlin \344\270\216 Java \345\205\261\345\255\230 (2) .md" "b/legacy/articles/2017.1.30/\345\213\230\350\257\257\357\274\23215 Kotlin \344\270\216 Java \345\205\261\345\255\230 (2) .md" similarity index 100% rename from "articles/2017.1.30/\345\213\230\350\257\257\357\274\23215 Kotlin \344\270\216 Java \345\205\261\345\255\230 (2) .md" rename to "legacy/articles/2017.1.30/\345\213\230\350\257\257\357\274\23215 Kotlin \344\270\216 Java \345\205\261\345\255\230 (2) .md" diff --git "a/articles/2017.1.30/\345\246\202\344\275\225\344\274\230\351\233\205\347\232\204\345\234\250\345\276\256\344\277\241\345\205\254\344\274\227\345\217\267\344\270\255\347\274\226\350\276\221\344\273\243\347\240\201.jpg" "b/legacy/articles/2017.1.30/\345\246\202\344\275\225\344\274\230\351\233\205\347\232\204\345\234\250\345\276\256\344\277\241\345\205\254\344\274\227\345\217\267\344\270\255\347\274\226\350\276\221\344\273\243\347\240\201.jpg" similarity index 100% rename from "articles/2017.1.30/\345\246\202\344\275\225\344\274\230\351\233\205\347\232\204\345\234\250\345\276\256\344\277\241\345\205\254\344\274\227\345\217\267\344\270\255\347\274\226\350\276\221\344\273\243\347\240\201.jpg" rename to "legacy/articles/2017.1.30/\345\246\202\344\275\225\344\274\230\351\233\205\347\232\204\345\234\250\345\276\256\344\277\241\345\205\254\344\274\227\345\217\267\344\270\255\347\274\226\350\276\221\344\273\243\347\240\201.jpg" diff --git "a/articles/2017.1.30/\345\246\202\344\275\225\344\274\230\351\233\205\347\232\204\345\234\250\345\276\256\344\277\241\345\205\254\344\274\227\345\217\267\344\270\255\347\274\226\350\276\221\344\273\243\347\240\201.md" "b/legacy/articles/2017.1.30/\345\246\202\344\275\225\344\274\230\351\233\205\347\232\204\345\234\250\345\276\256\344\277\241\345\205\254\344\274\227\345\217\267\344\270\255\347\274\226\350\276\221\344\273\243\347\240\201.md" similarity index 100% rename from "articles/2017.1.30/\345\246\202\344\275\225\344\274\230\351\233\205\347\232\204\345\234\250\345\276\256\344\277\241\345\205\254\344\274\227\345\217\267\344\270\255\347\274\226\350\276\221\344\273\243\347\240\201.md" rename to "legacy/articles/2017.1.30/\345\246\202\344\275\225\344\274\230\351\233\205\347\232\204\345\234\250\345\276\256\344\277\241\345\205\254\344\274\227\345\217\267\344\270\255\347\274\226\350\276\221\344\273\243\347\240\201.md" diff --git "a/articles/2017.1.30/\346\267\261\345\205\245\347\220\206\350\247\243 Kotlin Coroutine.md" "b/legacy/articles/2017.1.30/\346\267\261\345\205\245\347\220\206\350\247\243 Kotlin Coroutine.md" similarity index 100% rename from "articles/2017.1.30/\346\267\261\345\205\245\347\220\206\350\247\243 Kotlin Coroutine.md" rename to "legacy/articles/2017.1.30/\346\267\261\345\205\245\347\220\206\350\247\243 Kotlin Coroutine.md" diff --git a/articles/2017.1.9/action.gif b/legacy/articles/2017.1.9/action.gif similarity index 100% rename from articles/2017.1.9/action.gif rename to legacy/articles/2017.1.9/action.gif diff --git a/articles/2017.1.9/array.jpg b/legacy/articles/2017.1.9/array.jpg similarity index 100% rename from articles/2017.1.9/array.jpg rename to legacy/articles/2017.1.9/array.jpg diff --git a/articles/2017.1.9/comment.gif b/legacy/articles/2017.1.9/comment.gif similarity index 100% rename from articles/2017.1.9/comment.gif rename to legacy/articles/2017.1.9/comment.gif diff --git a/articles/2017.1.9/comment2.gif b/legacy/articles/2017.1.9/comment2.gif similarity index 100% rename from articles/2017.1.9/comment2.gif rename to legacy/articles/2017.1.9/comment2.gif diff --git a/articles/2017.1.9/comment3.gif b/legacy/articles/2017.1.9/comment3.gif similarity index 100% rename from articles/2017.1.9/comment3.gif rename to legacy/articles/2017.1.9/comment3.gif diff --git a/articles/2017.1.9/enter.gif b/legacy/articles/2017.1.9/enter.gif similarity index 100% rename from articles/2017.1.9/enter.gif rename to legacy/articles/2017.1.9/enter.gif diff --git a/articles/2017.1.9/findaction.png b/legacy/articles/2017.1.9/findaction.png similarity index 100% rename from articles/2017.1.9/findaction.png rename to legacy/articles/2017.1.9/findaction.png diff --git a/articles/2017.1.9/intellij.jpg b/legacy/articles/2017.1.9/intellij.jpg similarity index 100% rename from articles/2017.1.9/intellij.jpg rename to legacy/articles/2017.1.9/intellij.jpg diff --git a/articles/2017.1.9/iter_smart.gif b/legacy/articles/2017.1.9/iter_smart.gif similarity index 100% rename from articles/2017.1.9/iter_smart.gif rename to legacy/articles/2017.1.9/iter_smart.gif diff --git a/articles/2017.1.9/iter_stupid.gif b/legacy/articles/2017.1.9/iter_stupid.gif similarity index 100% rename from articles/2017.1.9/iter_stupid.gif rename to legacy/articles/2017.1.9/iter_stupid.gif diff --git a/articles/2017.1.9/livetemplate.png b/legacy/articles/2017.1.9/livetemplate.png similarity index 100% rename from articles/2017.1.9/livetemplate.png rename to legacy/articles/2017.1.9/livetemplate.png diff --git a/articles/2017.1.9/lt10.png b/legacy/articles/2017.1.9/lt10.png similarity index 100% rename from articles/2017.1.9/lt10.png rename to legacy/articles/2017.1.9/lt10.png diff --git a/articles/2017.1.9/lt11.png b/legacy/articles/2017.1.9/lt11.png similarity index 100% rename from articles/2017.1.9/lt11.png rename to legacy/articles/2017.1.9/lt11.png diff --git a/articles/2017.1.9/lt12.png b/legacy/articles/2017.1.9/lt12.png similarity index 100% rename from articles/2017.1.9/lt12.png rename to legacy/articles/2017.1.9/lt12.png diff --git a/articles/2017.1.9/lt13.png b/legacy/articles/2017.1.9/lt13.png similarity index 100% rename from articles/2017.1.9/lt13.png rename to legacy/articles/2017.1.9/lt13.png diff --git a/articles/2017.1.9/lt14.png b/legacy/articles/2017.1.9/lt14.png similarity index 100% rename from articles/2017.1.9/lt14.png rename to legacy/articles/2017.1.9/lt14.png diff --git a/articles/2017.1.9/lt15.png b/legacy/articles/2017.1.9/lt15.png similarity index 100% rename from articles/2017.1.9/lt15.png rename to legacy/articles/2017.1.9/lt15.png diff --git a/articles/2017.1.9/lt2.png b/legacy/articles/2017.1.9/lt2.png similarity index 100% rename from articles/2017.1.9/lt2.png rename to legacy/articles/2017.1.9/lt2.png diff --git a/articles/2017.1.9/lt3.png b/legacy/articles/2017.1.9/lt3.png similarity index 100% rename from articles/2017.1.9/lt3.png rename to legacy/articles/2017.1.9/lt3.png diff --git a/articles/2017.1.9/lt4.png b/legacy/articles/2017.1.9/lt4.png similarity index 100% rename from articles/2017.1.9/lt4.png rename to legacy/articles/2017.1.9/lt4.png diff --git a/articles/2017.1.9/lt5.png b/legacy/articles/2017.1.9/lt5.png similarity index 100% rename from articles/2017.1.9/lt5.png rename to legacy/articles/2017.1.9/lt5.png diff --git a/articles/2017.1.9/lt6.png b/legacy/articles/2017.1.9/lt6.png similarity index 100% rename from articles/2017.1.9/lt6.png rename to legacy/articles/2017.1.9/lt6.png diff --git a/articles/2017.1.9/lt8.png b/legacy/articles/2017.1.9/lt8.png similarity index 100% rename from articles/2017.1.9/lt8.png rename to legacy/articles/2017.1.9/lt8.png diff --git a/articles/2017.1.9/lt9.png b/legacy/articles/2017.1.9/lt9.png similarity index 100% rename from articles/2017.1.9/lt9.png rename to legacy/articles/2017.1.9/lt9.png diff --git a/articles/2017.1.9/main.gif b/legacy/articles/2017.1.9/main.gif similarity index 100% rename from articles/2017.1.9/main.gif rename to legacy/articles/2017.1.9/main.gif diff --git a/articles/2017.1.9/multiline.gif b/legacy/articles/2017.1.9/multiline.gif similarity index 100% rename from articles/2017.1.9/multiline.gif rename to legacy/articles/2017.1.9/multiline.gif diff --git a/articles/2017.1.9/multiline2.gif b/legacy/articles/2017.1.9/multiline2.gif similarity index 100% rename from articles/2017.1.9/multiline2.gif rename to legacy/articles/2017.1.9/multiline2.gif diff --git a/articles/2017.1.9/multiline_action.png b/legacy/articles/2017.1.9/multiline_action.png similarity index 100% rename from articles/2017.1.9/multiline_action.png rename to legacy/articles/2017.1.9/multiline_action.png diff --git a/articles/2017.1.9/newline.gif b/legacy/articles/2017.1.9/newline.gif similarity index 100% rename from articles/2017.1.9/newline.gif rename to legacy/articles/2017.1.9/newline.gif diff --git a/articles/2017.1.9/newline2.gif b/legacy/articles/2017.1.9/newline2.gif similarity index 100% rename from articles/2017.1.9/newline2.gif rename to legacy/articles/2017.1.9/newline2.gif diff --git a/articles/2017.1.9/newline3.gif b/legacy/articles/2017.1.9/newline3.gif similarity index 100% rename from articles/2017.1.9/newline3.gif rename to legacy/articles/2017.1.9/newline3.gif diff --git a/articles/2017.1.9/newline_action.png b/legacy/articles/2017.1.9/newline_action.png similarity index 100% rename from articles/2017.1.9/newline_action.png rename to legacy/articles/2017.1.9/newline_action.png diff --git a/articles/2017.1.9/posix.png b/legacy/articles/2017.1.9/posix.png similarity index 100% rename from articles/2017.1.9/posix.png rename to legacy/articles/2017.1.9/posix.png diff --git a/articles/2017.1.9/search.png b/legacy/articles/2017.1.9/search.png similarity index 100% rename from articles/2017.1.9/search.png rename to legacy/articles/2017.1.9/search.png diff --git a/articles/2017.1.9/search2.png b/legacy/articles/2017.1.9/search2.png similarity index 100% rename from articles/2017.1.9/search2.png rename to legacy/articles/2017.1.9/search2.png diff --git a/articles/2017.1.9/swap_action.png b/legacy/articles/2017.1.9/swap_action.png similarity index 100% rename from articles/2017.1.9/swap_action.png rename to legacy/articles/2017.1.9/swap_action.png diff --git a/articles/2017.1.9/swap_fun.gif b/legacy/articles/2017.1.9/swap_fun.gif similarity index 100% rename from articles/2017.1.9/swap_fun.gif rename to legacy/articles/2017.1.9/swap_fun.gif diff --git a/articles/2017.1.9/swap_smart.gif b/legacy/articles/2017.1.9/swap_smart.gif similarity index 100% rename from articles/2017.1.9/swap_smart.gif rename to legacy/articles/2017.1.9/swap_smart.gif diff --git a/articles/2017.1.9/swap_stupid.gif b/legacy/articles/2017.1.9/swap_stupid.gif similarity index 100% rename from articles/2017.1.9/swap_stupid.gif rename to legacy/articles/2017.1.9/swap_stupid.gif diff --git a/articles/2017.1.9/tab.gif b/legacy/articles/2017.1.9/tab.gif similarity index 100% rename from articles/2017.1.9/tab.gif rename to legacy/articles/2017.1.9/tab.gif diff --git "a/articles/2017.1.9/\344\270\272\344\273\200\344\271\210\344\270\215\347\233\264\346\216\245\344\275\277\347\224\250 Array \350\200\214\346\230\257 IntArray \357\274\237.md" "b/legacy/articles/2017.1.9/\344\270\272\344\273\200\344\271\210\344\270\215\347\233\264\346\216\245\344\275\277\347\224\250 Array \350\200\214\346\230\257 IntArray \357\274\237.md" similarity index 100% rename from "articles/2017.1.9/\344\270\272\344\273\200\344\271\210\344\270\215\347\233\264\346\216\245\344\275\277\347\224\250 Array \350\200\214\346\230\257 IntArray \357\274\237.md" rename to "legacy/articles/2017.1.9/\344\270\272\344\273\200\344\271\210\344\270\215\347\233\264\346\216\245\344\275\277\347\224\250 Array \350\200\214\346\230\257 IntArray \357\274\237.md" diff --git "a/articles/2017.1.9/\351\253\230\346\225\210\345\234\260\344\275\277\347\224\250\344\275\240\347\232\204 IntelliJ.md" "b/legacy/articles/2017.1.9/\351\253\230\346\225\210\345\234\260\344\275\277\347\224\250\344\275\240\347\232\204 IntelliJ.md" similarity index 100% rename from "articles/2017.1.9/\351\253\230\346\225\210\345\234\260\344\275\277\347\224\250\344\275\240\347\232\204 IntelliJ.md" rename to "legacy/articles/2017.1.9/\351\253\230\346\225\210\345\234\260\344\275\277\347\224\250\344\275\240\347\232\204 IntelliJ.md" diff --git a/articles/2017.2.13/lambda.jpg b/legacy/articles/2017.2.13/lambda.jpg similarity index 100% rename from articles/2017.2.13/lambda.jpg rename to legacy/articles/2017.2.13/lambda.jpg diff --git "a/articles/2017.2.13/\347\273\206\350\257\264 Lambda \350\241\250\350\276\276\345\274\217.md" "b/legacy/articles/2017.2.13/\347\273\206\350\257\264 Lambda \350\241\250\350\276\276\345\274\217.md" similarity index 100% rename from "articles/2017.2.13/\347\273\206\350\257\264 Lambda \350\241\250\350\276\276\345\274\217.md" rename to "legacy/articles/2017.2.13/\347\273\206\350\257\264 Lambda \350\241\250\350\276\276\345\274\217.md" diff --git a/articles/2017.2.20/11RC-01.png b/legacy/articles/2017.2.20/11RC-01.png similarity index 100% rename from articles/2017.2.20/11RC-01.png rename to legacy/articles/2017.2.20/11RC-01.png diff --git "a/articles/2017.2.20/Kotlin 1.1\357\274\232\346\210\221\344\273\254\351\203\275\350\267\257\344\270\212.md" "b/legacy/articles/2017.2.20/Kotlin 1.1\357\274\232\346\210\221\344\273\254\351\203\275\350\267\257\344\270\212.md" similarity index 100% rename from "articles/2017.2.20/Kotlin 1.1\357\274\232\346\210\221\344\273\254\351\203\275\350\267\257\344\270\212.md" rename to "legacy/articles/2017.2.20/Kotlin 1.1\357\274\232\346\210\221\344\273\254\351\203\275\350\267\257\344\270\212.md" diff --git a/articles/2017.2.20/cover.jpg b/legacy/articles/2017.2.20/cover.jpg similarity index 100% rename from articles/2017.2.20/cover.jpg rename to legacy/articles/2017.2.20/cover.jpg diff --git a/articles/2017.2.20/embarassed.png b/legacy/articles/2017.2.20/embarassed.png similarity index 100% rename from articles/2017.2.20/embarassed.png rename to legacy/articles/2017.2.20/embarassed.png diff --git a/articles/2017.2.20/growup.png b/legacy/articles/2017.2.20/growup.png similarity index 100% rename from articles/2017.2.20/growup.png rename to legacy/articles/2017.2.20/growup.png diff --git a/articles/2017.2.20/high_order_fun.jpg b/legacy/articles/2017.2.20/high_order_fun.jpg similarity index 100% rename from articles/2017.2.20/high_order_fun.jpg rename to legacy/articles/2017.2.20/high_order_fun.jpg diff --git a/articles/2017.2.20/right.jpg b/legacy/articles/2017.2.20/right.jpg similarity index 100% rename from articles/2017.2.20/right.jpg rename to legacy/articles/2017.2.20/right.jpg diff --git a/articles/2017.2.20/road.JPG b/legacy/articles/2017.2.20/road.JPG similarity index 100% rename from articles/2017.2.20/road.JPG rename to legacy/articles/2017.2.20/road.JPG diff --git a/articles/2017.2.20/wangzhe.jpg b/legacy/articles/2017.2.20/wangzhe.jpg similarity index 100% rename from articles/2017.2.20/wangzhe.jpg rename to legacy/articles/2017.2.20/wangzhe.jpg diff --git a/articles/2017.2.20/zhiyin.jpg b/legacy/articles/2017.2.20/zhiyin.jpg similarity index 100% rename from articles/2017.2.20/zhiyin.jpg rename to legacy/articles/2017.2.20/zhiyin.jpg diff --git "a/articles/2017.2.20/\351\253\230\351\230\266\345\207\275\346\225\260\357\274\210\344\270\200\357\274\211.md" "b/legacy/articles/2017.2.20/\351\253\230\351\230\266\345\207\275\346\225\260\357\274\210\344\270\200\357\274\211.md" similarity index 100% rename from "articles/2017.2.20/\351\253\230\351\230\266\345\207\275\346\225\260\357\274\210\344\270\200\357\274\211.md" rename to "legacy/articles/2017.2.20/\351\253\230\351\230\266\345\207\275\346\225\260\357\274\210\344\270\200\357\274\211.md" diff --git "a/articles/2017.2.27/\351\253\230\351\230\266\345\207\275\346\225\260\357\274\210\344\272\214\357\274\211.md" "b/legacy/articles/2017.2.27/\351\253\230\351\230\266\345\207\275\346\225\260\357\274\210\344\272\214\357\274\211.md" similarity index 100% rename from "articles/2017.2.27/\351\253\230\351\230\266\345\207\275\346\225\260\357\274\210\344\272\214\357\274\211.md" rename to "legacy/articles/2017.2.27/\351\253\230\351\230\266\345\207\275\346\225\260\357\274\210\344\272\214\357\274\211.md" diff --git "a/articles/2017.2.6/Kotlin 1.1 Beta 2 \345\217\221\345\270\203~.jpg" "b/legacy/articles/2017.2.6/Kotlin 1.1 Beta 2 \345\217\221\345\270\203~.jpg" similarity index 100% rename from "articles/2017.2.6/Kotlin 1.1 Beta 2 \345\217\221\345\270\203~.jpg" rename to "legacy/articles/2017.2.6/Kotlin 1.1 Beta 2 \345\217\221\345\270\203~.jpg" diff --git "a/articles/2017.2.6/Kotlin 1.1 Beta 2 \345\217\221\345\270\203~.md" "b/legacy/articles/2017.2.6/Kotlin 1.1 Beta 2 \345\217\221\345\270\203~.md" similarity index 100% rename from "articles/2017.2.6/Kotlin 1.1 Beta 2 \345\217\221\345\270\203~.md" rename to "legacy/articles/2017.2.6/Kotlin 1.1 Beta 2 \345\217\221\345\270\203~.md" diff --git "a/articles/2017.2.6/\346\267\261\345\205\245\347\220\206\350\247\243 Kotlin coroutine (\344\272\214\357\274\211.md" "b/legacy/articles/2017.2.6/\346\267\261\345\205\245\347\220\206\350\247\243 Kotlin coroutine (\344\272\214\357\274\211.md" similarity index 100% rename from "articles/2017.2.6/\346\267\261\345\205\245\347\220\206\350\247\243 Kotlin coroutine (\344\272\214\357\274\211.md" rename to "legacy/articles/2017.2.6/\346\267\261\345\205\245\347\220\206\350\247\243 Kotlin coroutine (\344\272\214\357\274\211.md" diff --git "a/articles/2017.3.13/Kotlin Script \344\273\213\347\273\215.jpg" "b/legacy/articles/2017.3.13/Kotlin Script \344\273\213\347\273\215.jpg" similarity index 100% rename from "articles/2017.3.13/Kotlin Script \344\273\213\347\273\215.jpg" rename to "legacy/articles/2017.3.13/Kotlin Script \344\273\213\347\273\215.jpg" diff --git "a/articles/2017.3.13/Kotlin Script \344\273\213\347\273\215.md" "b/legacy/articles/2017.3.13/Kotlin Script \344\273\213\347\273\215.md" similarity index 100% rename from "articles/2017.3.13/Kotlin Script \344\273\213\347\273\215.md" rename to "legacy/articles/2017.3.13/Kotlin Script \344\273\213\347\273\215.md" diff --git "a/articles/2017.3.13/\345\277\253\351\200\237\344\270\212\346\211\213 Kotlin 11\346\213\233.jpg" "b/legacy/articles/2017.3.13/\345\277\253\351\200\237\344\270\212\346\211\213 Kotlin 11\346\213\233.jpg" similarity index 100% rename from "articles/2017.3.13/\345\277\253\351\200\237\344\270\212\346\211\213 Kotlin 11\346\213\233.jpg" rename to "legacy/articles/2017.3.13/\345\277\253\351\200\237\344\270\212\346\211\213 Kotlin 11\346\213\233.jpg" diff --git "a/articles/2017.3.13/\345\277\253\351\200\237\344\270\212\346\211\213 Kotlin 11\346\213\233.md" "b/legacy/articles/2017.3.13/\345\277\253\351\200\237\344\270\212\346\211\213 Kotlin 11\346\213\233.md" similarity index 100% rename from "articles/2017.3.13/\345\277\253\351\200\237\344\270\212\346\211\213 Kotlin 11\346\213\233.md" rename to "legacy/articles/2017.3.13/\345\277\253\351\200\237\344\270\212\346\211\213 Kotlin 11\346\213\233.md" diff --git a/articles/2017.3.20/cover.jpg b/legacy/articles/2017.3.20/cover.jpg similarity index 100% rename from articles/2017.3.20/cover.jpg rename to legacy/articles/2017.3.20/cover.jpg diff --git a/articles/2017.3.20/wechat_group.jpg b/legacy/articles/2017.3.20/wechat_group.jpg similarity index 100% rename from articles/2017.3.20/wechat_group.jpg rename to legacy/articles/2017.3.20/wechat_group.jpg diff --git "a/articles/2017.3.27/Kotlin \351\201\207\345\210\260 MyBatis\357\274\232\345\210\260\345\272\225\346\230\257 Int \347\232\204\351\224\231\357\274\214\350\277\230\346\230\257 data class \347\232\204\351\224\231\357\274\237.md" "b/legacy/articles/2017.3.27/Kotlin \351\201\207\345\210\260 MyBatis\357\274\232\345\210\260\345\272\225\346\230\257 Int \347\232\204\351\224\231\357\274\214\350\277\230\346\230\257 data class \347\232\204\351\224\231\357\274\237.md" similarity index 100% rename from "articles/2017.3.27/Kotlin \351\201\207\345\210\260 MyBatis\357\274\232\345\210\260\345\272\225\346\230\257 Int \347\232\204\351\224\231\357\274\214\350\277\230\346\230\257 data class \347\232\204\351\224\231\357\274\237.md" rename to "legacy/articles/2017.3.27/Kotlin \351\201\207\345\210\260 MyBatis\357\274\232\345\210\260\345\272\225\346\230\257 Int \347\232\204\351\224\231\357\274\214\350\277\230\346\230\257 data class \347\232\204\351\224\231\357\274\237.md" diff --git a/articles/2017.3.27/cover.jpg b/legacy/articles/2017.3.27/cover.jpg similarity index 100% rename from articles/2017.3.27/cover.jpg rename to legacy/articles/2017.3.27/cover.jpg diff --git a/articles/2017.3.4/Kotlin 1.1.md b/legacy/articles/2017.3.4/Kotlin 1.1.md similarity index 100% rename from articles/2017.3.4/Kotlin 1.1.md rename to legacy/articles/2017.3.4/Kotlin 1.1.md diff --git a/articles/2017.3.4/Kotlin11blogbanner1.jpg b/legacy/articles/2017.3.4/Kotlin11blogbanner1.jpg similarity index 100% rename from articles/2017.3.4/Kotlin11blogbanner1.jpg rename to legacy/articles/2017.3.4/Kotlin11blogbanner1.jpg diff --git "a/articles/2017.4.3/Kotlin \345\205\274\345\256\271 Java \351\201\207\345\210\260\347\232\204\346\234\200\345\244\247\347\232\204\345\235\221 .md" "b/legacy/articles/2017.4.3/Kotlin \345\205\274\345\256\271 Java \351\201\207\345\210\260\347\232\204\346\234\200\345\244\247\347\232\204\345\235\221 .md" similarity index 100% rename from "articles/2017.4.3/Kotlin \345\205\274\345\256\271 Java \351\201\207\345\210\260\347\232\204\346\234\200\345\244\247\347\232\204\345\235\221 .md" rename to "legacy/articles/2017.4.3/Kotlin \345\205\274\345\256\271 Java \351\201\207\345\210\260\347\232\204\346\234\200\345\244\247\347\232\204\345\235\221 .md" diff --git a/arts/Kotlin-logo.png b/legacy/arts/Kotlin-logo.png similarity index 100% rename from arts/Kotlin-logo.png rename to legacy/arts/Kotlin-logo.png diff --git a/arts/Kotlin.jpg b/legacy/arts/Kotlin.jpg similarity index 100% rename from arts/Kotlin.jpg rename to legacy/arts/Kotlin.jpg diff --git a/arts/contributes.jpg b/legacy/arts/contributes.jpg similarity index 100% rename from arts/contributes.jpg rename to legacy/arts/contributes.jpg diff --git a/arts/e_group.png b/legacy/arts/e_group.png similarity index 100% rename from arts/e_group.png rename to legacy/arts/e_group.png diff --git "a/arts/kotlin\346\211\253\347\240\201\345\205\263\346\263\250.png" "b/legacy/arts/kotlin\346\211\253\347\240\201\345\205\263\346\263\250.png" similarity index 100% rename from "arts/kotlin\346\211\253\347\240\201\345\205\263\346\263\250.png" rename to "legacy/arts/kotlin\346\211\253\347\240\201\345\205\263\346\263\250.png" diff --git a/code/Kt01/src/net/println/kt01/Main.kt b/legacy/code/Kt01/src/net/println/kt01/Main.kt similarity index 100% rename from code/Kt01/src/net/println/kt01/Main.kt rename to legacy/code/Kt01/src/net/println/kt01/Main.kt diff --git a/code/Kt02/src/net/println/kt02/Main.kt b/legacy/code/Kt02/src/net/println/kt02/Main.kt similarity index 100% rename from code/Kt02/src/net/println/kt02/Main.kt rename to legacy/code/Kt02/src/net/println/kt02/Main.kt diff --git a/code/Kt03/build.gradle b/legacy/code/Kt03/build.gradle similarity index 100% rename from code/Kt03/build.gradle rename to legacy/code/Kt03/build.gradle diff --git a/code/Kt03/gradle/wrapper/gradle-wrapper.jar b/legacy/code/Kt03/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from code/Kt03/gradle/wrapper/gradle-wrapper.jar rename to legacy/code/Kt03/gradle/wrapper/gradle-wrapper.jar diff --git a/code/Kt03/gradle/wrapper/gradle-wrapper.properties b/legacy/code/Kt03/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from code/Kt03/gradle/wrapper/gradle-wrapper.properties rename to legacy/code/Kt03/gradle/wrapper/gradle-wrapper.properties diff --git a/code/Kt03/gradlew b/legacy/code/Kt03/gradlew similarity index 100% rename from code/Kt03/gradlew rename to legacy/code/Kt03/gradlew diff --git a/code/Kt03/gradlew.bat b/legacy/code/Kt03/gradlew.bat similarity index 100% rename from code/Kt03/gradlew.bat rename to legacy/code/Kt03/gradlew.bat diff --git a/code/Kt03/settings.gradle b/legacy/code/Kt03/settings.gradle similarity index 100% rename from code/Kt03/settings.gradle rename to legacy/code/Kt03/settings.gradle diff --git a/code/Kt03/src/main/java/net/println/kt03/Hello.java b/legacy/code/Kt03/src/main/java/net/println/kt03/Hello.java similarity index 100% rename from code/Kt03/src/main/java/net/println/kt03/Hello.java rename to legacy/code/Kt03/src/main/java/net/println/kt03/Hello.java diff --git a/code/Kt03/src/main/java/net/println/kt03/HelloJava.kt b/legacy/code/Kt03/src/main/java/net/println/kt03/HelloJava.kt similarity index 100% rename from code/Kt03/src/main/java/net/println/kt03/HelloJava.kt rename to legacy/code/Kt03/src/main/java/net/println/kt03/HelloJava.kt diff --git a/code/Kt03/src/main/java/net/println/kt03/HelloKotlin.kt b/legacy/code/Kt03/src/main/java/net/println/kt03/HelloKotlin.kt similarity index 100% rename from code/Kt03/src/main/java/net/println/kt03/HelloKotlin.kt rename to legacy/code/Kt03/src/main/java/net/println/kt03/HelloKotlin.kt diff --git a/code/Kt03/src/main/kotlin/net/println/kt03/User.kt b/legacy/code/Kt03/src/main/kotlin/net/println/kt03/User.kt similarity index 100% rename from code/Kt03/src/main/kotlin/net/println/kt03/User.kt rename to legacy/code/Kt03/src/main/kotlin/net/println/kt03/User.kt diff --git a/code/Kt04/build.gradle b/legacy/code/Kt04/build.gradle similarity index 100% rename from code/Kt04/build.gradle rename to legacy/code/Kt04/build.gradle diff --git a/code/Kt04/gradle/wrapper/gradle-wrapper.jar b/legacy/code/Kt04/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from code/Kt04/gradle/wrapper/gradle-wrapper.jar rename to legacy/code/Kt04/gradle/wrapper/gradle-wrapper.jar diff --git a/code/Kt04/gradle/wrapper/gradle-wrapper.properties b/legacy/code/Kt04/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from code/Kt04/gradle/wrapper/gradle-wrapper.properties rename to legacy/code/Kt04/gradle/wrapper/gradle-wrapper.properties diff --git a/code/Kt04/gradlew b/legacy/code/Kt04/gradlew similarity index 100% rename from code/Kt04/gradlew rename to legacy/code/Kt04/gradlew diff --git a/code/Kt04/gradlew.bat b/legacy/code/Kt04/gradlew.bat similarity index 100% rename from code/Kt04/gradlew.bat rename to legacy/code/Kt04/gradlew.bat diff --git a/code/Kt04/settings.gradle b/legacy/code/Kt04/settings.gradle similarity index 100% rename from code/Kt04/settings.gradle rename to legacy/code/Kt04/settings.gradle diff --git a/code/Kt04/src/main/java/net/println/kt04/ConsoleParam.kt b/legacy/code/Kt04/src/main/java/net/println/kt04/ConsoleParam.kt similarity index 100% rename from code/Kt04/src/main/java/net/println/kt04/ConsoleParam.kt rename to legacy/code/Kt04/src/main/java/net/println/kt04/ConsoleParam.kt diff --git a/code/Kt04/src/main/java/net/println/kt04/ConsoleParamInJava.java b/legacy/code/Kt04/src/main/java/net/println/kt04/ConsoleParamInJava.java similarity index 100% rename from code/Kt04/src/main/java/net/println/kt04/ConsoleParamInJava.java rename to legacy/code/Kt04/src/main/java/net/println/kt04/ConsoleParamInJava.java diff --git a/code/Kt05/build.gradle b/legacy/code/Kt05/build.gradle similarity index 100% rename from code/Kt05/build.gradle rename to legacy/code/Kt05/build.gradle diff --git a/code/Kt05/gradle/wrapper/gradle-wrapper.jar b/legacy/code/Kt05/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from code/Kt05/gradle/wrapper/gradle-wrapper.jar rename to legacy/code/Kt05/gradle/wrapper/gradle-wrapper.jar diff --git a/code/Kt05/gradle/wrapper/gradle-wrapper.properties b/legacy/code/Kt05/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from code/Kt05/gradle/wrapper/gradle-wrapper.properties rename to legacy/code/Kt05/gradle/wrapper/gradle-wrapper.properties diff --git a/code/Kt05/gradlew b/legacy/code/Kt05/gradlew similarity index 100% rename from code/Kt05/gradlew rename to legacy/code/Kt05/gradlew diff --git a/code/Kt05/gradlew.bat b/legacy/code/Kt05/gradlew.bat similarity index 100% rename from code/Kt05/gradlew.bat rename to legacy/code/Kt05/gradlew.bat diff --git a/code/Kt05/settings.gradle b/legacy/code/Kt05/settings.gradle similarity index 100% rename from code/Kt05/settings.gradle rename to legacy/code/Kt05/settings.gradle diff --git a/code/Kt05/src/main/java/net/println/kt05/ConsoleParam2.kt b/legacy/code/Kt05/src/main/java/net/println/kt05/ConsoleParam2.kt similarity index 100% rename from code/Kt05/src/main/java/net/println/kt05/ConsoleParam2.kt rename to legacy/code/Kt05/src/main/java/net/println/kt05/ConsoleParam2.kt diff --git a/code/Kt05/src/main/java/net/println/kt05/ConsoleParamInJava.java b/legacy/code/Kt05/src/main/java/net/println/kt05/ConsoleParamInJava.java similarity index 100% rename from code/Kt05/src/main/java/net/println/kt05/ConsoleParamInJava.java rename to legacy/code/Kt05/src/main/java/net/println/kt05/ConsoleParamInJava.java diff --git a/code/Kt06/build.gradle b/legacy/code/Kt06/build.gradle similarity index 100% rename from code/Kt06/build.gradle rename to legacy/code/Kt06/build.gradle diff --git a/code/Kt06/gradle/wrapper/gradle-wrapper.jar b/legacy/code/Kt06/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from code/Kt06/gradle/wrapper/gradle-wrapper.jar rename to legacy/code/Kt06/gradle/wrapper/gradle-wrapper.jar diff --git a/code/Kt06/gradle/wrapper/gradle-wrapper.properties b/legacy/code/Kt06/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from code/Kt06/gradle/wrapper/gradle-wrapper.properties rename to legacy/code/Kt06/gradle/wrapper/gradle-wrapper.properties diff --git a/code/Kt06/gradlew b/legacy/code/Kt06/gradlew similarity index 100% rename from code/Kt06/gradlew rename to legacy/code/Kt06/gradlew diff --git a/code/Kt06/gradlew.bat b/legacy/code/Kt06/gradlew.bat similarity index 100% rename from code/Kt06/gradlew.bat rename to legacy/code/Kt06/gradlew.bat diff --git a/code/Kt06/settings.gradle b/legacy/code/Kt06/settings.gradle similarity index 100% rename from code/Kt06/settings.gradle rename to legacy/code/Kt06/settings.gradle diff --git a/code/Kt06/src/main/java/net/println/kt06/EnumInJava.java b/legacy/code/Kt06/src/main/java/net/println/kt06/EnumInJava.java similarity index 100% rename from code/Kt06/src/main/java/net/println/kt06/EnumInJava.java rename to legacy/code/Kt06/src/main/java/net/println/kt06/EnumInJava.java diff --git a/code/Kt06/src/main/java/net/println/kt06/Main.java b/legacy/code/Kt06/src/main/java/net/println/kt06/Main.java similarity index 100% rename from code/Kt06/src/main/java/net/println/kt06/Main.java rename to legacy/code/Kt06/src/main/java/net/println/kt06/Main.java diff --git a/code/Kt06/src/main/java/net/println/kt06/SayHello.kt b/legacy/code/Kt06/src/main/java/net/println/kt06/SayHello.kt similarity index 100% rename from code/Kt06/src/main/java/net/println/kt06/SayHello.kt rename to legacy/code/Kt06/src/main/java/net/println/kt06/SayHello.kt diff --git a/code/Kt08/build.gradle b/legacy/code/Kt08/build.gradle similarity index 100% rename from code/Kt08/build.gradle rename to legacy/code/Kt08/build.gradle diff --git a/code/Kt08/gradle/wrapper/gradle-wrapper.jar b/legacy/code/Kt08/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from code/Kt08/gradle/wrapper/gradle-wrapper.jar rename to legacy/code/Kt08/gradle/wrapper/gradle-wrapper.jar diff --git a/code/Kt08/gradle/wrapper/gradle-wrapper.properties b/legacy/code/Kt08/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from code/Kt08/gradle/wrapper/gradle-wrapper.properties rename to legacy/code/Kt08/gradle/wrapper/gradle-wrapper.properties diff --git a/code/Kt08/gradlew b/legacy/code/Kt08/gradlew similarity index 100% rename from code/Kt08/gradlew rename to legacy/code/Kt08/gradlew diff --git a/code/Kt08/gradlew.bat b/legacy/code/Kt08/gradlew.bat similarity index 100% rename from code/Kt08/gradlew.bat rename to legacy/code/Kt08/gradlew.bat diff --git a/code/Kt08/settings.gradle b/legacy/code/Kt08/settings.gradle similarity index 100% rename from code/Kt08/settings.gradle rename to legacy/code/Kt08/settings.gradle diff --git a/code/Kt08/src/main/java/net/println/kt08/Service.kt b/legacy/code/Kt08/src/main/java/net/println/kt08/Service.kt similarity index 100% rename from code/Kt08/src/main/java/net/println/kt08/Service.kt rename to legacy/code/Kt08/src/main/java/net/println/kt08/Service.kt diff --git a/code/Kt08/src/main/java/net/println/kt08/User.kt b/legacy/code/Kt08/src/main/java/net/println/kt08/User.kt similarity index 100% rename from code/Kt08/src/main/java/net/println/kt08/User.kt rename to legacy/code/Kt08/src/main/java/net/println/kt08/User.kt diff --git a/code/Kt09/build.gradle b/legacy/code/Kt09/build.gradle similarity index 100% rename from code/Kt09/build.gradle rename to legacy/code/Kt09/build.gradle diff --git a/code/Kt09/gradle/wrapper/gradle-wrapper.jar b/legacy/code/Kt09/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from code/Kt09/gradle/wrapper/gradle-wrapper.jar rename to legacy/code/Kt09/gradle/wrapper/gradle-wrapper.jar diff --git a/code/Kt09/gradle/wrapper/gradle-wrapper.properties b/legacy/code/Kt09/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from code/Kt09/gradle/wrapper/gradle-wrapper.properties rename to legacy/code/Kt09/gradle/wrapper/gradle-wrapper.properties diff --git a/code/Kt09/gradlew b/legacy/code/Kt09/gradlew similarity index 100% rename from code/Kt09/gradlew rename to legacy/code/Kt09/gradlew diff --git a/code/Kt09/gradlew.bat b/legacy/code/Kt09/gradlew.bat similarity index 100% rename from code/Kt09/gradlew.bat rename to legacy/code/Kt09/gradlew.bat diff --git a/code/Kt09/src/main/java/net/println/kt09/Tailrec.kt b/legacy/code/Kt09/src/main/java/net/println/kt09/Tailrec.kt similarity index 100% rename from code/Kt09/src/main/java/net/println/kt09/Tailrec.kt rename to legacy/code/Kt09/src/main/java/net/println/kt09/Tailrec.kt diff --git a/code/Kt10/build.gradle b/legacy/code/Kt10/build.gradle similarity index 100% rename from code/Kt10/build.gradle rename to legacy/code/Kt10/build.gradle diff --git a/code/Kt10/gradle/wrapper/gradle-wrapper.jar b/legacy/code/Kt10/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from code/Kt10/gradle/wrapper/gradle-wrapper.jar rename to legacy/code/Kt10/gradle/wrapper/gradle-wrapper.jar diff --git a/code/Kt10/gradle/wrapper/gradle-wrapper.properties b/legacy/code/Kt10/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from code/Kt10/gradle/wrapper/gradle-wrapper.properties rename to legacy/code/Kt10/gradle/wrapper/gradle-wrapper.properties diff --git a/code/Kt10/gradlew b/legacy/code/Kt10/gradlew similarity index 100% rename from code/Kt10/gradlew rename to legacy/code/Kt10/gradlew diff --git a/code/Kt10/gradlew.bat b/legacy/code/Kt10/gradlew.bat similarity index 100% rename from code/Kt10/gradlew.bat rename to legacy/code/Kt10/gradlew.bat diff --git a/code/Kt10/settings.gradle b/legacy/code/Kt10/settings.gradle similarity index 100% rename from code/Kt10/settings.gradle rename to legacy/code/Kt10/settings.gradle diff --git a/code/Kt10/src/main/java/net/println/kt10/java/LazyNotThreadSafe.java b/legacy/code/Kt10/src/main/java/net/println/kt10/java/LazyNotThreadSafe.java similarity index 100% rename from code/Kt10/src/main/java/net/println/kt10/java/LazyNotThreadSafe.java rename to legacy/code/Kt10/src/main/java/net/println/kt10/java/LazyNotThreadSafe.java diff --git a/code/Kt10/src/main/java/net/println/kt10/java/LazyThreadSafeDoubleCheck.java b/legacy/code/Kt10/src/main/java/net/println/kt10/java/LazyThreadSafeDoubleCheck.java similarity index 100% rename from code/Kt10/src/main/java/net/println/kt10/java/LazyThreadSafeDoubleCheck.java rename to legacy/code/Kt10/src/main/java/net/println/kt10/java/LazyThreadSafeDoubleCheck.java diff --git a/code/Kt10/src/main/java/net/println/kt10/java/LazyThreadSafeStaticInnerClass.java b/legacy/code/Kt10/src/main/java/net/println/kt10/java/LazyThreadSafeStaticInnerClass.java similarity index 100% rename from code/Kt10/src/main/java/net/println/kt10/java/LazyThreadSafeStaticInnerClass.java rename to legacy/code/Kt10/src/main/java/net/println/kt10/java/LazyThreadSafeStaticInnerClass.java diff --git a/code/Kt10/src/main/java/net/println/kt10/java/LazyThreadSafeSynchronized.java b/legacy/code/Kt10/src/main/java/net/println/kt10/java/LazyThreadSafeSynchronized.java similarity index 100% rename from code/Kt10/src/main/java/net/println/kt10/java/LazyThreadSafeSynchronized.java rename to legacy/code/Kt10/src/main/java/net/println/kt10/java/LazyThreadSafeSynchronized.java diff --git a/code/Kt10/src/main/java/net/println/kt10/java/PlainOldSingleton.java b/legacy/code/Kt10/src/main/java/net/println/kt10/java/PlainOldSingleton.java similarity index 100% rename from code/Kt10/src/main/java/net/println/kt10/java/PlainOldSingleton.java rename to legacy/code/Kt10/src/main/java/net/println/kt10/java/PlainOldSingleton.java diff --git a/code/Kt10/src/main/kotlin/net/println/kt10/kotlin/LazyNotThreadSafe.kt b/legacy/code/Kt10/src/main/kotlin/net/println/kt10/kotlin/LazyNotThreadSafe.kt similarity index 100% rename from code/Kt10/src/main/kotlin/net/println/kt10/kotlin/LazyNotThreadSafe.kt rename to legacy/code/Kt10/src/main/kotlin/net/println/kt10/kotlin/LazyNotThreadSafe.kt diff --git a/code/Kt10/src/main/kotlin/net/println/kt10/kotlin/LazyThreadSafeDoubleCheck.kt b/legacy/code/Kt10/src/main/kotlin/net/println/kt10/kotlin/LazyThreadSafeDoubleCheck.kt similarity index 100% rename from code/Kt10/src/main/kotlin/net/println/kt10/kotlin/LazyThreadSafeDoubleCheck.kt rename to legacy/code/Kt10/src/main/kotlin/net/println/kt10/kotlin/LazyThreadSafeDoubleCheck.kt diff --git a/code/Kt10/src/main/kotlin/net/println/kt10/kotlin/LazyThreadSafeStaticInnerObject.kt b/legacy/code/Kt10/src/main/kotlin/net/println/kt10/kotlin/LazyThreadSafeStaticInnerObject.kt similarity index 100% rename from code/Kt10/src/main/kotlin/net/println/kt10/kotlin/LazyThreadSafeStaticInnerObject.kt rename to legacy/code/Kt10/src/main/kotlin/net/println/kt10/kotlin/LazyThreadSafeStaticInnerObject.kt diff --git a/code/Kt10/src/main/kotlin/net/println/kt10/kotlin/LazyThreadSafeSynchronized.kt b/legacy/code/Kt10/src/main/kotlin/net/println/kt10/kotlin/LazyThreadSafeSynchronized.kt similarity index 100% rename from code/Kt10/src/main/kotlin/net/println/kt10/kotlin/LazyThreadSafeSynchronized.kt rename to legacy/code/Kt10/src/main/kotlin/net/println/kt10/kotlin/LazyThreadSafeSynchronized.kt diff --git a/code/Kt10/src/main/kotlin/net/println/kt10/kotlin/PlainOldSingleton.kt b/legacy/code/Kt10/src/main/kotlin/net/println/kt10/kotlin/PlainOldSingleton.kt similarity index 100% rename from code/Kt10/src/main/kotlin/net/println/kt10/kotlin/PlainOldSingleton.kt rename to legacy/code/Kt10/src/main/kotlin/net/println/kt10/kotlin/PlainOldSingleton.kt diff --git a/code/Kt11/build.gradle b/legacy/code/Kt11/build.gradle similarity index 100% rename from code/Kt11/build.gradle rename to legacy/code/Kt11/build.gradle diff --git a/code/Kt11/gradle/wrapper/gradle-wrapper.jar b/legacy/code/Kt11/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from code/Kt11/gradle/wrapper/gradle-wrapper.jar rename to legacy/code/Kt11/gradle/wrapper/gradle-wrapper.jar diff --git a/code/Kt11/gradle/wrapper/gradle-wrapper.properties b/legacy/code/Kt11/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from code/Kt11/gradle/wrapper/gradle-wrapper.properties rename to legacy/code/Kt11/gradle/wrapper/gradle-wrapper.properties diff --git a/code/Kt11/gradlew b/legacy/code/Kt11/gradlew similarity index 100% rename from code/Kt11/gradlew rename to legacy/code/Kt11/gradlew diff --git a/code/Kt11/gradlew.bat b/legacy/code/Kt11/gradlew.bat similarity index 100% rename from code/Kt11/gradlew.bat rename to legacy/code/Kt11/gradlew.bat diff --git a/code/Kt11/settings.gradle b/legacy/code/Kt11/settings.gradle similarity index 100% rename from code/Kt11/settings.gradle rename to legacy/code/Kt11/settings.gradle diff --git a/code/Kt11/src/main/kotlin/net/println/kt11/Main.kt b/legacy/code/Kt11/src/main/kotlin/net/println/kt11/Main.kt similarity index 100% rename from code/Kt11/src/main/kotlin/net/println/kt11/Main.kt rename to legacy/code/Kt11/src/main/kotlin/net/println/kt11/Main.kt diff --git a/code/Kt11/src/main/kotlin/net/println/kt11/Player.kt b/legacy/code/Kt11/src/main/kotlin/net/println/kt11/Player.kt similarity index 100% rename from code/Kt11/src/main/kotlin/net/println/kt11/Player.kt rename to legacy/code/Kt11/src/main/kotlin/net/println/kt11/Player.kt diff --git a/code/Kt11/src/main/kotlin/net/println/kt11/PlayerCmd.kt b/legacy/code/Kt11/src/main/kotlin/net/println/kt11/PlayerCmd.kt similarity index 100% rename from code/Kt11/src/main/kotlin/net/println/kt11/PlayerCmd.kt rename to legacy/code/Kt11/src/main/kotlin/net/println/kt11/PlayerCmd.kt diff --git a/code/Kt11/src/main/kotlin/net/println/kt11/State.kt b/legacy/code/Kt11/src/main/kotlin/net/println/kt11/State.kt similarity index 100% rename from code/Kt11/src/main/kotlin/net/println/kt11/State.kt rename to legacy/code/Kt11/src/main/kotlin/net/println/kt11/State.kt diff --git a/code/Kt12/Program.cs b/legacy/code/Kt12/Program.cs similarity index 100% rename from code/Kt12/Program.cs rename to legacy/code/Kt12/Program.cs diff --git a/code/Kt12/build.gradle b/legacy/code/Kt12/build.gradle similarity index 100% rename from code/Kt12/build.gradle rename to legacy/code/Kt12/build.gradle diff --git a/code/Kt12/gradle/wrapper/gradle-wrapper.jar b/legacy/code/Kt12/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from code/Kt12/gradle/wrapper/gradle-wrapper.jar rename to legacy/code/Kt12/gradle/wrapper/gradle-wrapper.jar diff --git a/code/Kt12/gradle/wrapper/gradle-wrapper.properties b/legacy/code/Kt12/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from code/Kt12/gradle/wrapper/gradle-wrapper.properties rename to legacy/code/Kt12/gradle/wrapper/gradle-wrapper.properties diff --git a/code/Kt12/gradlew b/legacy/code/Kt12/gradlew similarity index 100% rename from code/Kt12/gradlew rename to legacy/code/Kt12/gradlew diff --git a/code/Kt12/gradlew.bat b/legacy/code/Kt12/gradlew.bat similarity index 100% rename from code/Kt12/gradlew.bat rename to legacy/code/Kt12/gradlew.bat diff --git a/code/Kt12/result_singer.json b/legacy/code/Kt12/result_singer.json similarity index 100% rename from code/Kt12/result_singer.json rename to legacy/code/Kt12/result_singer.json diff --git a/code/Kt12/result_singer_field_loss.json b/legacy/code/Kt12/result_singer_field_loss.json similarity index 100% rename from code/Kt12/result_singer_field_loss.json rename to legacy/code/Kt12/result_singer_field_loss.json diff --git a/code/Kt12/result_songs.json b/legacy/code/Kt12/result_songs.json similarity index 100% rename from code/Kt12/result_songs.json rename to legacy/code/Kt12/result_songs.json diff --git a/code/Kt12/settings.gradle b/legacy/code/Kt12/settings.gradle similarity index 100% rename from code/Kt12/settings.gradle rename to legacy/code/Kt12/settings.gradle diff --git a/code/Kt12/singer.json b/legacy/code/Kt12/singer.json similarity index 100% rename from code/Kt12/singer.json rename to legacy/code/Kt12/singer.json diff --git a/code/Kt12/src/main/java/net/println/kt12/Main.java b/legacy/code/Kt12/src/main/java/net/println/kt12/Main.java similarity index 100% rename from code/Kt12/src/main/java/net/println/kt12/Main.java rename to legacy/code/Kt12/src/main/java/net/println/kt12/Main.java diff --git a/code/Kt12/src/main/kotlin/net/println/kt12/Api.kt b/legacy/code/Kt12/src/main/kotlin/net/println/kt12/Api.kt similarity index 100% rename from code/Kt12/src/main/kotlin/net/println/kt12/Api.kt rename to legacy/code/Kt12/src/main/kotlin/net/println/kt12/Api.kt diff --git a/code/Kt12/src/main/kotlin/net/println/kt12/Data.kt b/legacy/code/Kt12/src/main/kotlin/net/println/kt12/Data.kt similarity index 100% rename from code/Kt12/src/main/kotlin/net/println/kt12/Data.kt rename to legacy/code/Kt12/src/main/kotlin/net/println/kt12/Data.kt diff --git a/code/Kt12/src/main/kotlin/net/println/kt12/GsonExt.kt b/legacy/code/Kt12/src/main/kotlin/net/println/kt12/GsonExt.kt similarity index 100% rename from code/Kt12/src/main/kotlin/net/println/kt12/GsonExt.kt rename to legacy/code/Kt12/src/main/kotlin/net/println/kt12/GsonExt.kt diff --git a/code/Kt12/src/main/kotlin/net/println/kt12/Main.kt b/legacy/code/Kt12/src/main/kotlin/net/println/kt12/Main.kt similarity index 100% rename from code/Kt12/src/main/kotlin/net/println/kt12/Main.kt rename to legacy/code/Kt12/src/main/kotlin/net/println/kt12/Main.kt diff --git a/code/Kt13/build.gradle b/legacy/code/Kt13/build.gradle similarity index 100% rename from code/Kt13/build.gradle rename to legacy/code/Kt13/build.gradle diff --git a/code/Kt13/gradle/wrapper/gradle-wrapper.jar b/legacy/code/Kt13/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from code/Kt13/gradle/wrapper/gradle-wrapper.jar rename to legacy/code/Kt13/gradle/wrapper/gradle-wrapper.jar diff --git a/code/Kt13/gradle/wrapper/gradle-wrapper.properties b/legacy/code/Kt13/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from code/Kt13/gradle/wrapper/gradle-wrapper.properties rename to legacy/code/Kt13/gradle/wrapper/gradle-wrapper.properties diff --git a/code/Kt13/gradlew b/legacy/code/Kt13/gradlew similarity index 100% rename from code/Kt13/gradlew rename to legacy/code/Kt13/gradlew diff --git a/code/Kt13/gradlew.bat b/legacy/code/Kt13/gradlew.bat similarity index 100% rename from code/Kt13/gradlew.bat rename to legacy/code/Kt13/gradlew.bat diff --git a/code/Kt13/settings.gradle b/legacy/code/Kt13/settings.gradle similarity index 100% rename from code/Kt13/settings.gradle rename to legacy/code/Kt13/settings.gradle diff --git a/code/Kt13/src/main/kotlin/net/println/kt13/RESTFulComponent.kt b/legacy/code/Kt13/src/main/kotlin/net/println/kt13/RESTFulComponent.kt similarity index 100% rename from code/Kt13/src/main/kotlin/net/println/kt13/RESTFulComponent.kt rename to legacy/code/Kt13/src/main/kotlin/net/println/kt13/RESTFulComponent.kt diff --git a/code/Kt13/src/main/kotlin/net/println/kt13/Service.kt b/legacy/code/Kt13/src/main/kotlin/net/println/kt13/Service.kt similarity index 100% rename from code/Kt13/src/main/kotlin/net/println/kt13/Service.kt rename to legacy/code/Kt13/src/main/kotlin/net/println/kt13/Service.kt diff --git a/code/Kt13/src/main/kotlin/net/println/kt13/User.kt b/legacy/code/Kt13/src/main/kotlin/net/println/kt13/User.kt similarity index 100% rename from code/Kt13/src/main/kotlin/net/println/kt13/User.kt rename to legacy/code/Kt13/src/main/kotlin/net/println/kt13/User.kt diff --git a/code/Kt13/src/main/kotlin/net/println/kt13/config/Settings.kt b/legacy/code/Kt13/src/main/kotlin/net/println/kt13/config/Settings.kt similarity index 100% rename from code/Kt13/src/main/kotlin/net/println/kt13/config/Settings.kt rename to legacy/code/Kt13/src/main/kotlin/net/println/kt13/config/Settings.kt diff --git a/code/Kt13/src/main/kotlin/net/println/kt13/module/BaseUrlModule.kt b/legacy/code/Kt13/src/main/kotlin/net/println/kt13/module/BaseUrlModule.kt similarity index 100% rename from code/Kt13/src/main/kotlin/net/println/kt13/module/BaseUrlModule.kt rename to legacy/code/Kt13/src/main/kotlin/net/println/kt13/module/BaseUrlModule.kt diff --git a/code/Kt13/src/main/kotlin/net/println/kt13/module/CacheModule.kt b/legacy/code/Kt13/src/main/kotlin/net/println/kt13/module/CacheModule.kt similarity index 100% rename from code/Kt13/src/main/kotlin/net/println/kt13/module/CacheModule.kt rename to legacy/code/Kt13/src/main/kotlin/net/println/kt13/module/CacheModule.kt diff --git a/code/Kt13/src/main/kotlin/net/println/kt13/module/GsonConverterModule.kt b/legacy/code/Kt13/src/main/kotlin/net/println/kt13/module/GsonConverterModule.kt similarity index 100% rename from code/Kt13/src/main/kotlin/net/println/kt13/module/GsonConverterModule.kt rename to legacy/code/Kt13/src/main/kotlin/net/println/kt13/module/GsonConverterModule.kt diff --git a/code/Kt13/src/main/kotlin/net/println/kt13/module/GsonModule.kt b/legacy/code/Kt13/src/main/kotlin/net/println/kt13/module/GsonModule.kt similarity index 100% rename from code/Kt13/src/main/kotlin/net/println/kt13/module/GsonModule.kt rename to legacy/code/Kt13/src/main/kotlin/net/println/kt13/module/GsonModule.kt diff --git a/code/Kt13/src/main/kotlin/net/println/kt13/module/OkHttpClientModule.kt b/legacy/code/Kt13/src/main/kotlin/net/println/kt13/module/OkHttpClientModule.kt similarity index 100% rename from code/Kt13/src/main/kotlin/net/println/kt13/module/OkHttpClientModule.kt rename to legacy/code/Kt13/src/main/kotlin/net/println/kt13/module/OkHttpClientModule.kt diff --git a/code/Kt13/src/main/kotlin/net/println/kt13/module/RetrofitModule.kt b/legacy/code/Kt13/src/main/kotlin/net/println/kt13/module/RetrofitModule.kt similarity index 100% rename from code/Kt13/src/main/kotlin/net/println/kt13/module/RetrofitModule.kt rename to legacy/code/Kt13/src/main/kotlin/net/println/kt13/module/RetrofitModule.kt diff --git a/code/Kt13/src/main/kotlin/net/println/kt13/module/RxAdapterModule.kt b/legacy/code/Kt13/src/main/kotlin/net/println/kt13/module/RxAdapterModule.kt similarity index 100% rename from code/Kt13/src/main/kotlin/net/println/kt13/module/RxAdapterModule.kt rename to legacy/code/Kt13/src/main/kotlin/net/println/kt13/module/RxAdapterModule.kt diff --git a/code/Kt14/Kt14/build.gradle b/legacy/code/Kt14/Kt14/build.gradle similarity index 100% rename from code/Kt14/Kt14/build.gradle rename to legacy/code/Kt14/Kt14/build.gradle diff --git a/code/Kt14/Kt14/src/main/java/net/println/kt14/AccessToObject.java b/legacy/code/Kt14/Kt14/src/main/java/net/println/kt14/AccessToObject.java similarity index 100% rename from code/Kt14/Kt14/src/main/java/net/println/kt14/AccessToObject.java rename to legacy/code/Kt14/Kt14/src/main/java/net/println/kt14/AccessToObject.java diff --git a/code/Kt14/Kt14/src/main/java/net/println/kt14/AccessToOverloads.java b/legacy/code/Kt14/Kt14/src/main/java/net/println/kt14/AccessToOverloads.java similarity index 100% rename from code/Kt14/Kt14/src/main/java/net/println/kt14/AccessToOverloads.java rename to legacy/code/Kt14/Kt14/src/main/java/net/println/kt14/AccessToOverloads.java diff --git a/code/Kt14/Kt14/src/main/java/net/println/kt14/CallExtenstionMethod.java b/legacy/code/Kt14/Kt14/src/main/java/net/println/kt14/CallExtenstionMethod.java similarity index 100% rename from code/Kt14/Kt14/src/main/java/net/println/kt14/CallExtenstionMethod.java rename to legacy/code/Kt14/Kt14/src/main/java/net/println/kt14/CallExtenstionMethod.java diff --git a/code/Kt14/Kt14/src/main/java/net/println/kt14/CallInternalClass.java b/legacy/code/Kt14/Kt14/src/main/java/net/println/kt14/CallInternalClass.java similarity index 100% rename from code/Kt14/Kt14/src/main/java/net/println/kt14/CallInternalClass.java rename to legacy/code/Kt14/Kt14/src/main/java/net/println/kt14/CallInternalClass.java diff --git a/code/Kt14/Kt14/src/main/java/net/println/kt14/CallPackageMethod.java b/legacy/code/Kt14/Kt14/src/main/java/net/println/kt14/CallPackageMethod.java similarity index 100% rename from code/Kt14/Kt14/src/main/java/net/println/kt14/CallPackageMethod.java rename to legacy/code/Kt14/Kt14/src/main/java/net/println/kt14/CallPackageMethod.java diff --git a/code/Kt14/Kt14/src/main/java/net/println/kt14/PersonMain.java b/legacy/code/Kt14/Kt14/src/main/java/net/println/kt14/PersonMain.java similarity index 100% rename from code/Kt14/Kt14/src/main/java/net/println/kt14/PersonMain.java rename to legacy/code/Kt14/Kt14/src/main/java/net/println/kt14/PersonMain.java diff --git a/code/Kt14/Kt14/src/main/kotlin/net/println/kt14/CallInternalClass.kt b/legacy/code/Kt14/Kt14/src/main/kotlin/net/println/kt14/CallInternalClass.kt similarity index 100% rename from code/Kt14/Kt14/src/main/kotlin/net/println/kt14/CallInternalClass.kt rename to legacy/code/Kt14/Kt14/src/main/kotlin/net/println/kt14/CallInternalClass.kt diff --git a/code/Kt14/Kt14/src/main/kotlin/net/println/kt14/ExtensionMethod.kt b/legacy/code/Kt14/Kt14/src/main/kotlin/net/println/kt14/ExtensionMethod.kt similarity index 100% rename from code/Kt14/Kt14/src/main/kotlin/net/println/kt14/ExtensionMethod.kt rename to legacy/code/Kt14/Kt14/src/main/kotlin/net/println/kt14/ExtensionMethod.kt diff --git a/code/Kt14/Kt14/src/main/kotlin/net/println/kt14/InternalClass.kt b/legacy/code/Kt14/Kt14/src/main/kotlin/net/println/kt14/InternalClass.kt similarity index 100% rename from code/Kt14/Kt14/src/main/kotlin/net/println/kt14/InternalClass.kt rename to legacy/code/Kt14/Kt14/src/main/kotlin/net/println/kt14/InternalClass.kt diff --git a/code/Kt14/Kt14/src/main/kotlin/net/println/kt14/Overloads.kt b/legacy/code/Kt14/Kt14/src/main/kotlin/net/println/kt14/Overloads.kt similarity index 100% rename from code/Kt14/Kt14/src/main/kotlin/net/println/kt14/Overloads.kt rename to legacy/code/Kt14/Kt14/src/main/kotlin/net/println/kt14/Overloads.kt diff --git a/code/Kt14/Kt14/src/main/kotlin/net/println/kt14/Package.kt b/legacy/code/Kt14/Kt14/src/main/kotlin/net/println/kt14/Package.kt similarity index 100% rename from code/Kt14/Kt14/src/main/kotlin/net/println/kt14/Package.kt rename to legacy/code/Kt14/Kt14/src/main/kotlin/net/println/kt14/Package.kt diff --git a/code/Kt14/Kt14/src/main/kotlin/net/println/kt14/Person.kt b/legacy/code/Kt14/Kt14/src/main/kotlin/net/println/kt14/Person.kt similarity index 100% rename from code/Kt14/Kt14/src/main/kotlin/net/println/kt14/Person.kt rename to legacy/code/Kt14/Kt14/src/main/kotlin/net/println/kt14/Person.kt diff --git a/code/Kt14/Kt14/src/main/kotlin/net/println/kt14/Singleton.kt b/legacy/code/Kt14/Kt14/src/main/kotlin/net/println/kt14/Singleton.kt similarity index 100% rename from code/Kt14/Kt14/src/main/kotlin/net/println/kt14/Singleton.kt rename to legacy/code/Kt14/Kt14/src/main/kotlin/net/println/kt14/Singleton.kt diff --git a/code/Kt14/build.gradle b/legacy/code/Kt14/build.gradle similarity index 100% rename from code/Kt14/build.gradle rename to legacy/code/Kt14/build.gradle diff --git a/code/Kt14/gradle/wrapper/gradle-wrapper.jar b/legacy/code/Kt14/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from code/Kt14/gradle/wrapper/gradle-wrapper.jar rename to legacy/code/Kt14/gradle/wrapper/gradle-wrapper.jar diff --git a/code/Kt14/gradle/wrapper/gradle-wrapper.properties b/legacy/code/Kt14/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from code/Kt14/gradle/wrapper/gradle-wrapper.properties rename to legacy/code/Kt14/gradle/wrapper/gradle-wrapper.properties diff --git a/code/Kt14/gradlew b/legacy/code/Kt14/gradlew similarity index 100% rename from code/Kt14/gradlew rename to legacy/code/Kt14/gradlew diff --git a/code/Kt14/gradlew.bat b/legacy/code/Kt14/gradlew.bat similarity index 100% rename from code/Kt14/gradlew.bat rename to legacy/code/Kt14/gradlew.bat diff --git a/code/Kt14/kt14internal/build.gradle b/legacy/code/Kt14/kt14internal/build.gradle similarity index 100% rename from code/Kt14/kt14internal/build.gradle rename to legacy/code/Kt14/kt14internal/build.gradle diff --git a/code/Kt14/kt14internal/src/main/java/net/println/kt14internal/CallInternalClass.java b/legacy/code/Kt14/kt14internal/src/main/java/net/println/kt14internal/CallInternalClass.java similarity index 100% rename from code/Kt14/kt14internal/src/main/java/net/println/kt14internal/CallInternalClass.java rename to legacy/code/Kt14/kt14internal/src/main/java/net/println/kt14internal/CallInternalClass.java diff --git a/code/Kt14/kt14internal/src/main/kotlin/net/println/kt14internal/CallInternalClassKt.kt b/legacy/code/Kt14/kt14internal/src/main/kotlin/net/println/kt14internal/CallInternalClassKt.kt similarity index 100% rename from code/Kt14/kt14internal/src/main/kotlin/net/println/kt14internal/CallInternalClassKt.kt rename to legacy/code/Kt14/kt14internal/src/main/kotlin/net/println/kt14internal/CallInternalClassKt.kt diff --git a/code/Kt14/settings.gradle b/legacy/code/Kt14/settings.gradle similarity index 100% rename from code/Kt14/settings.gradle rename to legacy/code/Kt14/settings.gradle diff --git a/code/Kt15/build.gradle b/legacy/code/Kt15/build.gradle similarity index 100% rename from code/Kt15/build.gradle rename to legacy/code/Kt15/build.gradle diff --git a/code/Kt15/gradle/wrapper/gradle-wrapper.jar b/legacy/code/Kt15/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from code/Kt15/gradle/wrapper/gradle-wrapper.jar rename to legacy/code/Kt15/gradle/wrapper/gradle-wrapper.jar diff --git a/code/Kt15/gradle/wrapper/gradle-wrapper.properties b/legacy/code/Kt15/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from code/Kt15/gradle/wrapper/gradle-wrapper.properties rename to legacy/code/Kt15/gradle/wrapper/gradle-wrapper.properties diff --git a/code/Kt15/gradlew b/legacy/code/Kt15/gradlew similarity index 100% rename from code/Kt15/gradlew rename to legacy/code/Kt15/gradlew diff --git a/code/Kt15/gradlew.bat b/legacy/code/Kt15/gradlew.bat similarity index 100% rename from code/Kt15/gradlew.bat rename to legacy/code/Kt15/gradlew.bat diff --git a/code/Kt15/settings.gradle b/legacy/code/Kt15/settings.gradle similarity index 100% rename from code/Kt15/settings.gradle rename to legacy/code/Kt15/settings.gradle diff --git a/code/Kt15/src/main/java/net/println/kt15/DataClass.java b/legacy/code/Kt15/src/main/java/net/println/kt15/DataClass.java similarity index 100% rename from code/Kt15/src/main/java/net/println/kt15/DataClass.java rename to legacy/code/Kt15/src/main/java/net/println/kt15/DataClass.java diff --git a/code/Kt15/src/main/java/net/println/kt15/Generics.java b/legacy/code/Kt15/src/main/java/net/println/kt15/Generics.java similarity index 100% rename from code/Kt15/src/main/java/net/println/kt15/Generics.java rename to legacy/code/Kt15/src/main/java/net/println/kt15/Generics.java diff --git a/code/Kt15/src/main/java/net/println/kt15/NullSafetyAbsClass.java b/legacy/code/Kt15/src/main/java/net/println/kt15/NullSafetyAbsClass.java similarity index 100% rename from code/Kt15/src/main/java/net/println/kt15/NullSafetyAbsClass.java rename to legacy/code/Kt15/src/main/java/net/println/kt15/NullSafetyAbsClass.java diff --git a/code/Kt15/src/main/java/net/println/kt15/NullSafetyJava.java b/legacy/code/Kt15/src/main/java/net/println/kt15/NullSafetyJava.java similarity index 100% rename from code/Kt15/src/main/java/net/println/kt15/NullSafetyJava.java rename to legacy/code/Kt15/src/main/java/net/println/kt15/NullSafetyJava.java diff --git a/code/Kt15/src/main/java/net/println/kt15/SAMInJava.java b/legacy/code/Kt15/src/main/java/net/println/kt15/SAMInJava.java similarity index 100% rename from code/Kt15/src/main/java/net/println/kt15/SAMInJava.java rename to legacy/code/Kt15/src/main/java/net/println/kt15/SAMInJava.java diff --git a/code/Kt15/src/main/kotlin/net/println/kt15/AccessDataClass.kt b/legacy/code/Kt15/src/main/kotlin/net/println/kt15/AccessDataClass.kt similarity index 100% rename from code/Kt15/src/main/kotlin/net/println/kt15/AccessDataClass.kt rename to legacy/code/Kt15/src/main/kotlin/net/println/kt15/AccessDataClass.kt diff --git a/code/Kt15/src/main/kotlin/net/println/kt15/ConcurrentRelated.kt b/legacy/code/Kt15/src/main/kotlin/net/println/kt15/ConcurrentRelated.kt similarity index 100% rename from code/Kt15/src/main/kotlin/net/println/kt15/ConcurrentRelated.kt rename to legacy/code/Kt15/src/main/kotlin/net/println/kt15/ConcurrentRelated.kt diff --git a/code/Kt15/src/main/kotlin/net/println/kt15/GenericsInKt.kt b/legacy/code/Kt15/src/main/kotlin/net/println/kt15/GenericsInKt.kt similarity index 100% rename from code/Kt15/src/main/kotlin/net/println/kt15/GenericsInKt.kt rename to legacy/code/Kt15/src/main/kotlin/net/println/kt15/GenericsInKt.kt diff --git a/code/Kt15/src/main/kotlin/net/println/kt15/NullSafety.kt b/legacy/code/Kt15/src/main/kotlin/net/println/kt15/NullSafety.kt similarity index 100% rename from code/Kt15/src/main/kotlin/net/println/kt15/NullSafety.kt rename to legacy/code/Kt15/src/main/kotlin/net/println/kt15/NullSafety.kt diff --git a/code/Kt15/src/main/kotlin/net/println/kt15/NullSafetySubClass.kt b/legacy/code/Kt15/src/main/kotlin/net/println/kt15/NullSafetySubClass.kt similarity index 100% rename from code/Kt15/src/main/kotlin/net/println/kt15/NullSafetySubClass.kt rename to legacy/code/Kt15/src/main/kotlin/net/println/kt15/NullSafetySubClass.kt diff --git a/code/Kt15/src/main/kotlin/net/println/kt15/SAMConversion.kt b/legacy/code/Kt15/src/main/kotlin/net/println/kt15/SAMConversion.kt similarity index 100% rename from code/Kt15/src/main/kotlin/net/println/kt15/SAMConversion.kt rename to legacy/code/Kt15/src/main/kotlin/net/println/kt15/SAMConversion.kt diff --git a/code/MyBatisIssue/build.gradle b/legacy/code/MyBatisIssue/build.gradle similarity index 100% rename from code/MyBatisIssue/build.gradle rename to legacy/code/MyBatisIssue/build.gradle diff --git a/code/MyBatisIssue/gradle/wrapper/gradle-wrapper.jar b/legacy/code/MyBatisIssue/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from code/MyBatisIssue/gradle/wrapper/gradle-wrapper.jar rename to legacy/code/MyBatisIssue/gradle/wrapper/gradle-wrapper.jar diff --git a/code/MyBatisIssue/gradle/wrapper/gradle-wrapper.properties b/legacy/code/MyBatisIssue/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from code/MyBatisIssue/gradle/wrapper/gradle-wrapper.properties rename to legacy/code/MyBatisIssue/gradle/wrapper/gradle-wrapper.properties diff --git a/code/MyBatisIssue/gradlew b/legacy/code/MyBatisIssue/gradlew similarity index 100% rename from code/MyBatisIssue/gradlew rename to legacy/code/MyBatisIssue/gradlew diff --git a/code/MyBatisIssue/gradlew.bat b/legacy/code/MyBatisIssue/gradlew.bat similarity index 100% rename from code/MyBatisIssue/gradlew.bat rename to legacy/code/MyBatisIssue/gradlew.bat diff --git a/code/MyBatisIssue/libs/mysql-connector-java-5.1.40-bin.jar b/legacy/code/MyBatisIssue/libs/mysql-connector-java-5.1.40-bin.jar similarity index 100% rename from code/MyBatisIssue/libs/mysql-connector-java-5.1.40-bin.jar rename to legacy/code/MyBatisIssue/libs/mysql-connector-java-5.1.40-bin.jar diff --git a/code/MyBatisIssue/settings.gradle b/legacy/code/MyBatisIssue/settings.gradle similarity index 100% rename from code/MyBatisIssue/settings.gradle rename to legacy/code/MyBatisIssue/settings.gradle diff --git a/code/MyBatisIssue/src/main/kotlin/net/println/kotlin/mybatis/Main.java b/legacy/code/MyBatisIssue/src/main/kotlin/net/println/kotlin/mybatis/Main.java similarity index 100% rename from code/MyBatisIssue/src/main/kotlin/net/println/kotlin/mybatis/Main.java rename to legacy/code/MyBatisIssue/src/main/kotlin/net/println/kotlin/mybatis/Main.java diff --git a/code/MyBatisIssue/src/main/kotlin/net/println/kotlin/mybatis/Main.kt b/legacy/code/MyBatisIssue/src/main/kotlin/net/println/kotlin/mybatis/Main.kt similarity index 100% rename from code/MyBatisIssue/src/main/kotlin/net/println/kotlin/mybatis/Main.kt rename to legacy/code/MyBatisIssue/src/main/kotlin/net/println/kotlin/mybatis/Main.kt diff --git a/code/MyBatisIssue/src/main/kotlin/net/println/kotlin/mybatis/TestUnsafe.kt b/legacy/code/MyBatisIssue/src/main/kotlin/net/println/kotlin/mybatis/TestUnsafe.kt similarity index 100% rename from code/MyBatisIssue/src/main/kotlin/net/println/kotlin/mybatis/TestUnsafe.kt rename to legacy/code/MyBatisIssue/src/main/kotlin/net/println/kotlin/mybatis/TestUnsafe.kt diff --git a/code/MyBatisIssue/src/main/kotlin/net/println/kotlin/mybatis/User.kt b/legacy/code/MyBatisIssue/src/main/kotlin/net/println/kotlin/mybatis/User.kt similarity index 100% rename from code/MyBatisIssue/src/main/kotlin/net/println/kotlin/mybatis/User.kt rename to legacy/code/MyBatisIssue/src/main/kotlin/net/println/kotlin/mybatis/User.kt diff --git a/code/MyBatisIssue/src/main/kotlin/net/println/kotlin/mybatis/UserMapper.java b/legacy/code/MyBatisIssue/src/main/kotlin/net/println/kotlin/mybatis/UserMapper.java similarity index 100% rename from code/MyBatisIssue/src/main/kotlin/net/println/kotlin/mybatis/UserMapper.java rename to legacy/code/MyBatisIssue/src/main/kotlin/net/println/kotlin/mybatis/UserMapper.java diff --git a/code/MyBatisIssue/src/main/kotlin/net/println/kotlin/mybatis/annotations/PoKo.kt b/legacy/code/MyBatisIssue/src/main/kotlin/net/println/kotlin/mybatis/annotations/PoKo.kt similarity index 100% rename from code/MyBatisIssue/src/main/kotlin/net/println/kotlin/mybatis/annotations/PoKo.kt rename to legacy/code/MyBatisIssue/src/main/kotlin/net/println/kotlin/mybatis/annotations/PoKo.kt diff --git a/code/MyBatisIssue/src/main/resources/net/println/kotlin/mybatis/UserMapper.xml b/legacy/code/MyBatisIssue/src/main/resources/net/println/kotlin/mybatis/UserMapper.xml similarity index 100% rename from code/MyBatisIssue/src/main/resources/net/println/kotlin/mybatis/UserMapper.xml rename to legacy/code/MyBatisIssue/src/main/resources/net/println/kotlin/mybatis/UserMapper.xml diff --git a/code/MyBatisIssue/src/main/resources/net/println/kotlin/mybatis/config.xml b/legacy/code/MyBatisIssue/src/main/resources/net/println/kotlin/mybatis/config.xml similarity index 100% rename from code/MyBatisIssue/src/main/resources/net/println/kotlin/mybatis/config.xml rename to legacy/code/MyBatisIssue/src/main/resources/net/println/kotlin/mybatis/config.xml diff --git a/code/MyBatisIssue/src/main/resources/net/println/kotlin/mybatis/db.properties b/legacy/code/MyBatisIssue/src/main/resources/net/println/kotlin/mybatis/db.properties similarity index 100% rename from code/MyBatisIssue/src/main/resources/net/println/kotlin/mybatis/db.properties rename to legacy/code/MyBatisIssue/src/main/resources/net/println/kotlin/mybatis/db.properties diff --git a/code/MyBatisIssue/src/main/resources/net/println/kotlin/mybatis/userinfo.sql b/legacy/code/MyBatisIssue/src/main/resources/net/println/kotlin/mybatis/userinfo.sql similarity index 100% rename from code/MyBatisIssue/src/main/resources/net/println/kotlin/mybatis/userinfo.sql rename to legacy/code/MyBatisIssue/src/main/resources/net/println/kotlin/mybatis/userinfo.sql diff --git a/code/RealmIssue/.gitignore b/legacy/code/RealmIssue/.gitignore similarity index 100% rename from code/RealmIssue/.gitignore rename to legacy/code/RealmIssue/.gitignore diff --git a/code/RealmIssue/app/.gitignore b/legacy/code/RealmIssue/app/.gitignore similarity index 100% rename from code/RealmIssue/app/.gitignore rename to legacy/code/RealmIssue/app/.gitignore diff --git a/code/RealmIssue/app/build.gradle b/legacy/code/RealmIssue/app/build.gradle similarity index 100% rename from code/RealmIssue/app/build.gradle rename to legacy/code/RealmIssue/app/build.gradle diff --git a/code/RealmIssue/app/proguard-rules.pro b/legacy/code/RealmIssue/app/proguard-rules.pro similarity index 100% rename from code/RealmIssue/app/proguard-rules.pro rename to legacy/code/RealmIssue/app/proguard-rules.pro diff --git a/code/RealmIssue/app/src/main/AndroidManifest.xml b/legacy/code/RealmIssue/app/src/main/AndroidManifest.xml similarity index 100% rename from code/RealmIssue/app/src/main/AndroidManifest.xml rename to legacy/code/RealmIssue/app/src/main/AndroidManifest.xml diff --git a/code/RealmIssue/app/src/main/java/net/println/kotlin/realm/App.kt b/legacy/code/RealmIssue/app/src/main/java/net/println/kotlin/realm/App.kt similarity index 100% rename from code/RealmIssue/app/src/main/java/net/println/kotlin/realm/App.kt rename to legacy/code/RealmIssue/app/src/main/java/net/println/kotlin/realm/App.kt diff --git a/code/RealmIssue/app/src/main/java/net/println/kotlin/realm/MainActivity.kt b/legacy/code/RealmIssue/app/src/main/java/net/println/kotlin/realm/MainActivity.kt similarity index 100% rename from code/RealmIssue/app/src/main/java/net/println/kotlin/realm/MainActivity.kt rename to legacy/code/RealmIssue/app/src/main/java/net/println/kotlin/realm/MainActivity.kt diff --git a/code/RealmIssue/app/src/main/java/net/println/kotlin/realm/PoKo.kt b/legacy/code/RealmIssue/app/src/main/java/net/println/kotlin/realm/PoKo.kt similarity index 100% rename from code/RealmIssue/app/src/main/java/net/println/kotlin/realm/PoKo.kt rename to legacy/code/RealmIssue/app/src/main/java/net/println/kotlin/realm/PoKo.kt diff --git a/code/RealmIssue/app/src/main/java/net/println/kotlin/realm/User.kt b/legacy/code/RealmIssue/app/src/main/java/net/println/kotlin/realm/User.kt similarity index 100% rename from code/RealmIssue/app/src/main/java/net/println/kotlin/realm/User.kt rename to legacy/code/RealmIssue/app/src/main/java/net/println/kotlin/realm/User.kt diff --git a/code/RealmIssue/app/src/main/res/layout/activity_main.xml b/legacy/code/RealmIssue/app/src/main/res/layout/activity_main.xml similarity index 100% rename from code/RealmIssue/app/src/main/res/layout/activity_main.xml rename to legacy/code/RealmIssue/app/src/main/res/layout/activity_main.xml diff --git a/code/RealmIssue/app/src/main/res/mipmap-hdpi/ic_launcher.png b/legacy/code/RealmIssue/app/src/main/res/mipmap-hdpi/ic_launcher.png similarity index 100% rename from code/RealmIssue/app/src/main/res/mipmap-hdpi/ic_launcher.png rename to legacy/code/RealmIssue/app/src/main/res/mipmap-hdpi/ic_launcher.png diff --git a/code/RealmIssue/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/legacy/code/RealmIssue/app/src/main/res/mipmap-hdpi/ic_launcher_round.png similarity index 100% rename from code/RealmIssue/app/src/main/res/mipmap-hdpi/ic_launcher_round.png rename to legacy/code/RealmIssue/app/src/main/res/mipmap-hdpi/ic_launcher_round.png diff --git a/code/RealmIssue/app/src/main/res/mipmap-mdpi/ic_launcher.png b/legacy/code/RealmIssue/app/src/main/res/mipmap-mdpi/ic_launcher.png similarity index 100% rename from code/RealmIssue/app/src/main/res/mipmap-mdpi/ic_launcher.png rename to legacy/code/RealmIssue/app/src/main/res/mipmap-mdpi/ic_launcher.png diff --git a/code/RealmIssue/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/legacy/code/RealmIssue/app/src/main/res/mipmap-mdpi/ic_launcher_round.png similarity index 100% rename from code/RealmIssue/app/src/main/res/mipmap-mdpi/ic_launcher_round.png rename to legacy/code/RealmIssue/app/src/main/res/mipmap-mdpi/ic_launcher_round.png diff --git a/code/RealmIssue/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/legacy/code/RealmIssue/app/src/main/res/mipmap-xhdpi/ic_launcher.png similarity index 100% rename from code/RealmIssue/app/src/main/res/mipmap-xhdpi/ic_launcher.png rename to legacy/code/RealmIssue/app/src/main/res/mipmap-xhdpi/ic_launcher.png diff --git a/code/RealmIssue/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/legacy/code/RealmIssue/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png similarity index 100% rename from code/RealmIssue/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png rename to legacy/code/RealmIssue/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png diff --git a/code/RealmIssue/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/legacy/code/RealmIssue/app/src/main/res/mipmap-xxhdpi/ic_launcher.png similarity index 100% rename from code/RealmIssue/app/src/main/res/mipmap-xxhdpi/ic_launcher.png rename to legacy/code/RealmIssue/app/src/main/res/mipmap-xxhdpi/ic_launcher.png diff --git a/code/RealmIssue/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/legacy/code/RealmIssue/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png similarity index 100% rename from code/RealmIssue/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png rename to legacy/code/RealmIssue/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png diff --git a/code/RealmIssue/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/legacy/code/RealmIssue/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png similarity index 100% rename from code/RealmIssue/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png rename to legacy/code/RealmIssue/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png diff --git a/code/RealmIssue/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/legacy/code/RealmIssue/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png similarity index 100% rename from code/RealmIssue/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png rename to legacy/code/RealmIssue/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png diff --git a/code/RealmIssue/app/src/main/res/values/colors.xml b/legacy/code/RealmIssue/app/src/main/res/values/colors.xml similarity index 100% rename from code/RealmIssue/app/src/main/res/values/colors.xml rename to legacy/code/RealmIssue/app/src/main/res/values/colors.xml diff --git a/code/RealmIssue/app/src/main/res/values/strings.xml b/legacy/code/RealmIssue/app/src/main/res/values/strings.xml similarity index 100% rename from code/RealmIssue/app/src/main/res/values/strings.xml rename to legacy/code/RealmIssue/app/src/main/res/values/strings.xml diff --git a/code/RealmIssue/app/src/main/res/values/styles.xml b/legacy/code/RealmIssue/app/src/main/res/values/styles.xml similarity index 100% rename from code/RealmIssue/app/src/main/res/values/styles.xml rename to legacy/code/RealmIssue/app/src/main/res/values/styles.xml diff --git a/code/RealmIssue/build.gradle b/legacy/code/RealmIssue/build.gradle similarity index 100% rename from code/RealmIssue/build.gradle rename to legacy/code/RealmIssue/build.gradle diff --git a/code/RealmIssue/gradle.properties b/legacy/code/RealmIssue/gradle.properties similarity index 100% rename from code/RealmIssue/gradle.properties rename to legacy/code/RealmIssue/gradle.properties diff --git a/code/RealmIssue/gradle/wrapper/gradle-wrapper.jar b/legacy/code/RealmIssue/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from code/RealmIssue/gradle/wrapper/gradle-wrapper.jar rename to legacy/code/RealmIssue/gradle/wrapper/gradle-wrapper.jar diff --git a/code/RealmIssue/gradle/wrapper/gradle-wrapper.properties b/legacy/code/RealmIssue/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from code/RealmIssue/gradle/wrapper/gradle-wrapper.properties rename to legacy/code/RealmIssue/gradle/wrapper/gradle-wrapper.properties diff --git a/code/RealmIssue/gradlew b/legacy/code/RealmIssue/gradlew similarity index 100% rename from code/RealmIssue/gradlew rename to legacy/code/RealmIssue/gradlew diff --git a/code/RealmIssue/gradlew.bat b/legacy/code/RealmIssue/gradlew.bat similarity index 100% rename from code/RealmIssue/gradlew.bat rename to legacy/code/RealmIssue/gradlew.bat diff --git a/code/RealmIssue/settings.gradle b/legacy/code/RealmIssue/settings.gradle similarity index 100% rename from code/RealmIssue/settings.gradle rename to legacy/code/RealmIssue/settings.gradle diff --git a/code/kt07/build.gradle b/legacy/code/kt07/build.gradle similarity index 100% rename from code/kt07/build.gradle rename to legacy/code/kt07/build.gradle diff --git a/code/kt07/gradle/wrapper/gradle-wrapper.jar b/legacy/code/kt07/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from code/kt07/gradle/wrapper/gradle-wrapper.jar rename to legacy/code/kt07/gradle/wrapper/gradle-wrapper.jar diff --git a/code/kt07/gradle/wrapper/gradle-wrapper.properties b/legacy/code/kt07/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from code/kt07/gradle/wrapper/gradle-wrapper.properties rename to legacy/code/kt07/gradle/wrapper/gradle-wrapper.properties diff --git a/code/kt07/gradlew b/legacy/code/kt07/gradlew similarity index 100% rename from code/kt07/gradlew rename to legacy/code/kt07/gradlew diff --git a/code/kt07/gradlew.bat b/legacy/code/kt07/gradlew.bat similarity index 100% rename from code/kt07/gradlew.bat rename to legacy/code/kt07/gradlew.bat diff --git a/code/kt07/settings.gradle b/legacy/code/kt07/settings.gradle similarity index 100% rename from code/kt07/settings.gradle rename to legacy/code/kt07/settings.gradle diff --git a/code/kt07/src/main/Resources/input b/legacy/code/kt07/src/main/Resources/input similarity index 100% rename from code/kt07/src/main/Resources/input rename to legacy/code/kt07/src/main/Resources/input diff --git a/code/kt07/src/main/java/net/println/kt07/Lambda.kt b/legacy/code/kt07/src/main/java/net/println/kt07/Lambda.kt similarity index 100% rename from code/kt07/src/main/java/net/println/kt07/Lambda.kt rename to legacy/code/kt07/src/main/java/net/println/kt07/Lambda.kt diff --git "a/script/14 Kotlin \344\270\216 Java \345\205\261\345\255\230\357\274\2101\357\274\211.md" "b/legacy/script/14 Kotlin \344\270\216 Java \345\205\261\345\255\230\357\274\2101\357\274\211.md" similarity index 100% rename from "script/14 Kotlin \344\270\216 Java \345\205\261\345\255\230\357\274\2101\357\274\211.md" rename to "legacy/script/14 Kotlin \344\270\216 Java \345\205\261\345\255\230\357\274\2101\357\274\211.md" diff --git "a/script/15 Kotlin \344\270\216 Java \345\205\261\345\255\230 (2).md" "b/legacy/script/15 Kotlin \344\270\216 Java \345\205\261\345\255\230 (2).md" similarity index 100% rename from "script/15 Kotlin \344\270\216 Java \345\205\261\345\255\230 (2).md" rename to "legacy/script/15 Kotlin \344\270\216 Java \345\205\261\345\255\230 (2).md" diff --git "a/script/Kt01 \347\256\200\344\273\213.pptx" "b/legacy/script/Kt01 \347\256\200\344\273\213.pptx" similarity index 100% rename from "script/Kt01 \347\256\200\344\273\213.pptx" rename to "legacy/script/Kt01 \347\256\200\344\273\213.pptx" diff --git "a/script/Kt12 \350\247\243\346\236\220Json\346\225\260\346\215\256.key" "b/legacy/script/Kt12 \350\247\243\346\236\220Json\346\225\260\346\215\256.key" similarity index 100% rename from "script/Kt12 \350\247\243\346\236\220Json\346\225\260\346\215\256.key" rename to "legacy/script/Kt12 \350\247\243\346\236\220Json\346\225\260\346\215\256.key" diff --git "a/script/Kt12 \351\235\242\345\220\221\345\257\271\350\261\241\347\232\204\345\207\240\344\270\252\346\246\202\345\277\265.key" "b/legacy/script/Kt12 \351\235\242\345\220\221\345\257\271\350\261\241\347\232\204\345\207\240\344\270\252\346\246\202\345\277\265.key" similarity index 100% rename from "script/Kt12 \351\235\242\345\220\221\345\257\271\350\261\241\347\232\204\345\207\240\344\270\252\346\246\202\345\277\265.key" rename to "legacy/script/Kt12 \351\235\242\345\220\221\345\257\271\350\261\241\347\232\204\345\207\240\344\270\252\346\246\202\345\277\265.key" diff --git "a/script/Kt14 Kotlin \344\270\216 Java \345\205\261\345\255\230(\344\270\200).potx" "b/legacy/script/Kt14 Kotlin \344\270\216 Java \345\205\261\345\255\230(\344\270\200).potx" similarity index 100% rename from "script/Kt14 Kotlin \344\270\216 Java \345\205\261\345\255\230(\344\270\200).potx" rename to "legacy/script/Kt14 Kotlin \344\270\216 Java \345\205\261\345\255\230(\344\270\200).potx" From a24212c2a33243921c0392d780c2dbf43130ccde Mon Sep 17 00:00:00 2001 From: Bennyhuo Date: Sat, 5 Jun 2021 11:53:10 +0800 Subject: [PATCH 16/60] Update README.md --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index fd517bd..da941a0 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,5 @@ [![GitHub license](https://img.shields.io/badge/license-CC%20BY--NC--ND%204.0-blue.svg)](https://creativecommons.org/licenses/by-nc-nd/4.0/) -[TOC] - # Kotlin-Tutorials **2021.6 更新** From 375cf3f1a551d34f1739c5222f20bb327ae8e3b8 Mon Sep 17 00:00:00 2001 From: bennyhuo Date: Sat, 5 Jun 2021 11:53:56 +0800 Subject: [PATCH 17/60] remove empty files --- docs/Dive-into-Kotlin-Coroutines.md | 0 docs/Tutorials-IMOOC.md | 0 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 docs/Dive-into-Kotlin-Coroutines.md delete mode 100644 docs/Tutorials-IMOOC.md diff --git a/docs/Dive-into-Kotlin-Coroutines.md b/docs/Dive-into-Kotlin-Coroutines.md deleted file mode 100644 index e69de29..0000000 diff --git a/docs/Tutorials-IMOOC.md b/docs/Tutorials-IMOOC.md deleted file mode 100644 index e69de29..0000000 From adceb181f9c20b126d26e2e855b6f6750de98d25 Mon Sep 17 00:00:00 2001 From: Bennyhuo Date: Sat, 5 Jun 2021 11:55:36 +0800 Subject: [PATCH 18/60] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index da941a0..90d19fe 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ 过去几年我所在的[腾讯公司](https://www.tencent.com)当中,Kotlin 的落地项目实际上已经相当可观,例如: * 外部开源的 Android 插件化框架 [Shadow](https://github.com/Tencent/Shadow),核心逻辑基本上使用 Kotlin 编写。 -* [蓝鲸 CI 平台](https://github.com/Tencent/bk-ci),这是一个后端项目,在腾讯内部已经成为公司主推的 CI 平台,之前我在上面做持续集成时需要二次开发,惊喜地发现打印出来的调用堆栈居然有 Kotlin 身影。 +* [蓝鲸 CI 平台](https://github.com/Tencent/bk-ci),这是一个后端项目,在腾讯内部已经成为公司主推的 CI 平台,之前我在上面做持续集成时需要做插件开发,惊喜地发现打印出来的调用堆栈居然有 Kotlin 身影。 * 内部还有团队使用 KMM 做跨平台的 UI 控件渲染,这可以说时非常有挑战的工作了,不仅要在移动端支持 Android、iOS,还要同时支持桌面版。基于这个框架所属产品的体量,我们大概率已经是这套技术方案的用户了。 今年初我因个人原因离开了鹅厂,去了[北京猿力科技有限公司(猿辅导)](https://www.yuanfudao.com/),不出所料,在这家号称**小而美**且**有技术追求**的公司当中,Kotlin 在项目上的应用已经相当广泛了,新代码很少能见到 Java 的身影(有需要内推的小伙伴可以找我)。 From a85b0d9579dce0c6d180622ae57dc63c93fe6a32 Mon Sep 17 00:00:00 2001 From: Bennyhuo Date: Sat, 5 Jun 2021 11:56:14 +0800 Subject: [PATCH 19/60] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 90d19fe..9f34417 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ 过去几年我所在的[腾讯公司](https://www.tencent.com)当中,Kotlin 的落地项目实际上已经相当可观,例如: * 外部开源的 Android 插件化框架 [Shadow](https://github.com/Tencent/Shadow),核心逻辑基本上使用 Kotlin 编写。 * [蓝鲸 CI 平台](https://github.com/Tencent/bk-ci),这是一个后端项目,在腾讯内部已经成为公司主推的 CI 平台,之前我在上面做持续集成时需要做插件开发,惊喜地发现打印出来的调用堆栈居然有 Kotlin 身影。 -* 内部还有团队使用 KMM 做跨平台的 UI 控件渲染,这可以说时非常有挑战的工作了,不仅要在移动端支持 Android、iOS,还要同时支持桌面版。基于这个框架所属产品的体量,我们大概率已经是这套技术方案的用户了。 +* 内部还有团队使用 KMM 做跨平台的 UI 控件渲染,这可以说是非常有挑战的工作了,不仅要在移动端支持 Android、iOS,还要同时支持桌面版。基于这个框架所属产品的体量,我们大概率已经是这套技术方案的用户了。 今年初我因个人原因离开了鹅厂,去了[北京猿力科技有限公司(猿辅导)](https://www.yuanfudao.com/),不出所料,在这家号称**小而美**且**有技术追求**的公司当中,Kotlin 在项目上的应用已经相当广泛了,新代码很少能见到 Java 的身影(有需要内推的小伙伴可以找我)。 From f2bf0f0f0594c7e46912e212c9c3790c7993f065 Mon Sep 17 00:00:00 2001 From: Bennyhuo Date: Sat, 5 Jun 2021 11:58:06 +0800 Subject: [PATCH 20/60] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9f34417..51ab1a1 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ * [蓝鲸 CI 平台](https://github.com/Tencent/bk-ci),这是一个后端项目,在腾讯内部已经成为公司主推的 CI 平台,之前我在上面做持续集成时需要做插件开发,惊喜地发现打印出来的调用堆栈居然有 Kotlin 身影。 * 内部还有团队使用 KMM 做跨平台的 UI 控件渲染,这可以说是非常有挑战的工作了,不仅要在移动端支持 Android、iOS,还要同时支持桌面版。基于这个框架所属产品的体量,我们大概率已经是这套技术方案的用户了。 -今年初我因个人原因离开了鹅厂,去了[北京猿力科技有限公司(猿辅导)](https://www.yuanfudao.com/),不出所料,在这家号称**小而美**且**有技术追求**的公司当中,Kotlin 在项目上的应用已经相当广泛了,新代码很少能见到 Java 的身影(有需要内推的小伙伴可以找我)。 +今年初我因个人原因离开了鹅厂,去了[北京猿力教育科技有限公司(猿辅导)](https://www.yuanfudao.com/),不出所料,在这家号称**小而美**且**有技术追求**的公司当中,Kotlin 在项目上的应用已经相当广泛了,新代码很少能见到 Java 的身影(有需要内推的小伙伴可以找我)。 所以,作为“布道者”,过去我们总是想着怎么让更多的开发者知道 Kotlin,现在我们则需要提供更多的 Kotlin 的学习材料,来帮助大家更好的使用 Kotlin。 From be15024ba46c3b1a18358d44189e0c09ce148363 Mon Sep 17 00:00:00 2001 From: Bennyhuo Date: Sat, 5 Jun 2021 11:58:45 +0800 Subject: [PATCH 21/60] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 51ab1a1..e1483c7 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ * 邮箱: [bennyhuo@kotliner.cn](mailto:bennyhuo@kotliner.cn) * B 站账号:[**bennyhuo 不是算命的**](https://space.bilibili.com/28615855),我个人的视频会优先在 B 站发布 * 微信公众号 **Kotlin**,公众号主要用来发布 Kotlin 以及移动端开发相关的内容。 + * 加入社区 QQ 群 * Kotlin 中文社区群 大群:162452394 (已满) From 9e1e5adf903758f5aa396fdb811fd314e8d801f6 Mon Sep 17 00:00:00 2001 From: bennyhuo Date: Sun, 6 Jun 2021 12:13:45 +0800 Subject: [PATCH 22/60] rename to avoid problem with windows path --- ...1\346\225\260\347\273\204\347\261\273\345\236\213 IntArray.md" | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename "legacy/articles/2017.1.9/\344\270\272\344\273\200\344\271\210\344\270\215\347\233\264\346\216\245\344\275\277\347\224\250 Array \350\200\214\346\230\257 IntArray \357\274\237.md" => "legacy/articles/2017.1.9/\344\270\272\344\273\200\344\271\210\350\246\201\344\270\272 Int \344\270\223\351\227\250\345\256\232\344\271\211\346\225\260\347\273\204\347\261\273\345\236\213 IntArray.md" (100%) diff --git "a/legacy/articles/2017.1.9/\344\270\272\344\273\200\344\271\210\344\270\215\347\233\264\346\216\245\344\275\277\347\224\250 Array \350\200\214\346\230\257 IntArray \357\274\237.md" "b/legacy/articles/2017.1.9/\344\270\272\344\273\200\344\271\210\350\246\201\344\270\272 Int \344\270\223\351\227\250\345\256\232\344\271\211\346\225\260\347\273\204\347\261\273\345\236\213 IntArray.md" similarity index 100% rename from "legacy/articles/2017.1.9/\344\270\272\344\273\200\344\271\210\344\270\215\347\233\264\346\216\245\344\275\277\347\224\250 Array \350\200\214\346\230\257 IntArray \357\274\237.md" rename to "legacy/articles/2017.1.9/\344\270\272\344\273\200\344\271\210\350\246\201\344\270\272 Int \344\270\223\351\227\250\345\256\232\344\271\211\346\225\260\347\273\204\347\261\273\345\236\213 IntArray.md" From 81fe706a1ec676dd63940166fd726d5fa603c57f Mon Sep 17 00:00:00 2001 From: bennyhuo Date: Sun, 6 Jun 2021 12:44:26 +0800 Subject: [PATCH 23/60] Update Readme with video index. Add source code of samples. --- README.md | 27 ++- code/Kotlin-Sample/build.gradle.kts | 30 +++ code/Kotlin-Sample/gradle.properties | 2 + .../gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 59203 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 + code/Kotlin-Sample/gradlew | 185 ++++++++++++++++++ code/Kotlin-Sample/gradlew.bat | 89 +++++++++ code/Kotlin-Sample/settings.gradle.kts | 2 + .../bennyhuo/kotlin/samissue/Java8Sam.java | 17 ++ .../com/bennyhuo/kotlin/samissue/KotlinSam.kt | 7 + .../com/bennyhuo/kotlin/samissue/View.java | 12 ++ .../kotlin/samissue/sub/Java8Sam.java | 19 ++ .../bennyhuo/kotlin/samissue/sub/SubSam.kt | 10 + .../scheduledtask/CoroutineUpdateTask.kt | 31 +++ .../kotlin/scheduledtask/HandlerUpdateTask.kt | 53 +++++ .../com/bennyhuo/kotlin/scheduledtask/Main.kt | 23 +++ .../kotlin/scheduledtask/RxJavaUpdateTask.kt | 30 +++ .../kotlin/scheduledtask/TimerUpdateTask.kt | 40 ++++ .../kotlin/scheduledtask/UpdateApi.kt | 41 ++++ .../kotlin/scheduledtask/UpdateTask.kt | 10 + 20 files changed, 630 insertions(+), 3 deletions(-) create mode 100644 code/Kotlin-Sample/build.gradle.kts create mode 100644 code/Kotlin-Sample/gradle.properties create mode 100644 code/Kotlin-Sample/gradle/wrapper/gradle-wrapper.jar create mode 100644 code/Kotlin-Sample/gradle/wrapper/gradle-wrapper.properties create mode 100644 code/Kotlin-Sample/gradlew create mode 100644 code/Kotlin-Sample/gradlew.bat create mode 100644 code/Kotlin-Sample/settings.gradle.kts create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/samissue/Java8Sam.java create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/samissue/KotlinSam.kt create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/samissue/View.java create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/samissue/sub/Java8Sam.java create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/samissue/sub/SubSam.kt create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/CoroutineUpdateTask.kt create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/HandlerUpdateTask.kt create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/Main.kt create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/RxJavaUpdateTask.kt create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/TimerUpdateTask.kt create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/UpdateApi.kt create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/UpdateTask.kt diff --git a/README.md b/README.md index e1483c7..738e9f2 100644 --- a/README.md +++ b/README.md @@ -19,12 +19,33 @@ 还有一个相对长期的规划是做一套电子书,后面会在这个 [issue](https://github.com/bennyhuo/Kotlin-Tutorials/issues/36) 当中跟进,电子书的主体内容与我之前的课程 [Kotlin 从入门到精通 视频教程](http://coding.imooc.com/class/398.html) 会有一定程度上的重叠,但电子书的好处就是更新维护方便,相比之下视频教程制作成本太高且不易维护。 -有想法的小伙伴欢迎与我交流。 +有想法的小伙伴欢迎与我交流,也欢迎加入**催更群:966752510**一起讨论。 + +## 视频清单 + +### [Kotlin 杂谈 (持续更新中)](https://github.com/bennyhuo/Kotlin-Tutorials/issues/35) + +Kotlin 的一些很零碎的内容,放到这个栏目下面。 + +- [x] [[Kotlin 杂谈] SAM 转换遇到包内可见](https://www.bilibili.com/video/BV1wB4y1g79W/) >>[示例代码](code\Kotlin-Sample\src\main\java\com\bennyhuo\kotlin\samissue) +- [x] [[Kotlin 杂谈] 使用协程实现轮询任务竟是这么简单](https://www.bilibili.com/video/BV11b4y1Z7sz/) >>[示例代码](code\Kotlin-Sample\src\main\java\com\bennyhuo\kotlin\scheduledtask) + +### [Gradle 迁移 KTS 系列视频 (2021.4 已完结)](https://github.com/bennyhuo/Kotlin-Tutorials/issues/25) + +前不久开源了一个小项目 [Android-LuaJavax](https://github.com/bennyhuo/Android-LuaJavax),在改造 Gradle 脚本的时候也同时看到群里有不少小伙伴在问 KTS 编写 Gradle 脚本的问题,于是想要做几个视频来介绍下 Gradle 脚本从 Groovy 到 Kotlin 需要掌握哪些内容。 + +- [x] [你的 Gradle脚本究竟是什么?](https://www.bilibili.com/video/BV18K4y1D7Yb/) +- [x] [你的 Gradle 脚本是怎么运行起来的?](https://www.bilibili.com/video/BV1ep4y1h7qU/) +- [x] [Gradle Project 的属性都是哪里来的?](https://www.bilibili.com/video/BV16h411D77Q/) +- [x] [Gradle Task 创建的特殊语法](https://www.bilibili.com/video/BV1ib4y1D74X/) +- [x] [快速迁移 Gradle 脚本至 KTS](https://www.bilibili.com/video/BV1Kf4y1p7zq/) +- [x] [番外:如何调试 Gradle 源码](https://www.bilibili.com/video/BV1m54y1L7vK) +- [x] [如何为 Gradle 的 KTS 脚本添加扩展?](https://www.bilibili.com/video/BV1BU4y1b7Wk/) ## 联系我 * 邮箱: [bennyhuo@kotliner.cn](mailto:bennyhuo@kotliner.cn) -* B 站账号:[**bennyhuo 不是算命的**](https://space.bilibili.com/28615855),我个人的视频会优先在 B 站发布 +* B 站账号:[**bennyhuo 不是算命的**](https://space.bilibili.com/28615855),我的个人视频会优先在 B 站发布 * 微信公众号 **Kotlin**,公众号主要用来发布 Kotlin 以及移动端开发相关的内容。 @@ -37,7 +58,7 @@ --- -以下是这几年我的一些积累和产出,有兴趣可以关注。 +以下是过去几年我的一些积累和产出,有兴趣可以关注。 ## [《深入理解 Kotlin 协程》](https://www.bennyhuo.com/project/kotlin-coroutines.html) 2020.6 出版 diff --git a/code/Kotlin-Sample/build.gradle.kts b/code/Kotlin-Sample/build.gradle.kts new file mode 100644 index 0000000..291fe6f --- /dev/null +++ b/code/Kotlin-Sample/build.gradle.kts @@ -0,0 +1,30 @@ +plugins { + java + kotlin("jvm") version "1.5.10" +} + +group = "com.bennyhuo.kotlin.hello" +version = "1.0-SNAPSHOT" + +repositories { + maven("https://mirrors.tencent.com/nexus/repository/maven-public/") +} + +dependencies { + implementation(kotlin("stdlib")) + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0") + + implementation("com.squareup.retrofit2:retrofit:2.9.0") + implementation("com.squareup.retrofit2:adapter-rxjava3:2.9.0") + implementation("com.squareup.retrofit2:converter-gson:2.9.0") + implementation("com.bennyhuo:portable-android-handler:1.0") + implementation("io.reactivex.rxjava3:rxjava:3.0.13") + + + testImplementation("org.junit.jupiter:junit-jupiter-api:5.6.0") + testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine") +} + +tasks.getByName("test") { + useJUnitPlatform() +} \ No newline at end of file diff --git a/code/Kotlin-Sample/gradle.properties b/code/Kotlin-Sample/gradle.properties new file mode 100644 index 0000000..94b6fbc --- /dev/null +++ b/code/Kotlin-Sample/gradle.properties @@ -0,0 +1,2 @@ +kotlin.code.style=official +org.gradle.daemon=true \ No newline at end of file diff --git a/code/Kotlin-Sample/gradle/wrapper/gradle-wrapper.jar b/code/Kotlin-Sample/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..e708b1c023ec8b20f512888fe07c5bd3ff77bb8f GIT binary patch literal 59203 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

K7UpUK$>l@ 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 E2O(~oYXATM literal 0 HcmV?d00001 diff --git a/code/Kotlin-Sample/gradle/wrapper/gradle-wrapper.properties b/code/Kotlin-Sample/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..8cf6eb5 --- /dev/null +++ b/code/Kotlin-Sample/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-all.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/code/Kotlin-Sample/gradlew b/code/Kotlin-Sample/gradlew new file mode 100644 index 0000000..4f906e0 --- /dev/null +++ b/code/Kotlin-Sample/gradlew @@ -0,0 +1,185 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/code/Kotlin-Sample/gradlew.bat b/code/Kotlin-Sample/gradlew.bat new file mode 100644 index 0000000..107acd3 --- /dev/null +++ b/code/Kotlin-Sample/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/code/Kotlin-Sample/settings.gradle.kts b/code/Kotlin-Sample/settings.gradle.kts new file mode 100644 index 0000000..c6685f2 --- /dev/null +++ b/code/Kotlin-Sample/settings.gradle.kts @@ -0,0 +1,2 @@ +rootProject.name = "Kotlin-Sample" + diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/samissue/Java8Sam.java b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/samissue/Java8Sam.java new file mode 100644 index 0000000..f4dda4f --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/samissue/Java8Sam.java @@ -0,0 +1,17 @@ +package com.bennyhuo.kotlin.samissue; + +public class Java8Sam { + public static void main(String[] args) { + View view = new View(); + view.setOnSizeChangedListener((width, height) -> { + System.out.println("w: " + width + ", h: " + height); + }); + + view.setOnSizeChangedListener(new View.OnSizeChangedListener() { + @Override + public void onSizeChanged(int width, int height) { + System.out.println("w: " + width + ", h: " + height); + } + }); + } +} diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/samissue/KotlinSam.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/samissue/KotlinSam.kt new file mode 100644 index 0000000..5cd2de1 --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/samissue/KotlinSam.kt @@ -0,0 +1,7 @@ +package com.bennyhuo.kotlin.samissue + +fun main() { + View().setOnSizeChangedListener { width, height -> + println("w: $width, h: $height") + } +} \ No newline at end of file diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/samissue/View.java b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/samissue/View.java new file mode 100644 index 0000000..a0f38de --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/samissue/View.java @@ -0,0 +1,12 @@ +package com.bennyhuo.kotlin.samissue; + +public class View { + // Single Abstract method + public interface OnSizeChangedListener { + void onSizeChanged(int width, int height); + } + + public void setOnSizeChangedListener(OnSizeChangedListener onSizeChangedListener) { + + } +} diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/samissue/sub/Java8Sam.java b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/samissue/sub/Java8Sam.java new file mode 100644 index 0000000..5f5d172 --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/samissue/sub/Java8Sam.java @@ -0,0 +1,19 @@ +package com.bennyhuo.kotlin.samissue.sub; + +import com.bennyhuo.kotlin.samissue.View; + +public class Java8Sam { + public static void main(String[] args) { + View view = new View(); + view.setOnSizeChangedListener((width, height) -> { + System.out.println("w: " + width + ", h: " + height); + }); + + view.setOnSizeChangedListener(new View.OnSizeChangedListener() { + @Override + public void onSizeChanged(int width, int height) { + System.out.println("w: " + width + ", h: " + height); + } + }); + } +} diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/samissue/sub/SubSam.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/samissue/sub/SubSam.kt new file mode 100644 index 0000000..13c1811 --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/samissue/sub/SubSam.kt @@ -0,0 +1,10 @@ +package com.bennyhuo.kotlin.samissue.sub + +import com.bennyhuo.kotlin.samissue.View + +fun main() { + View().setOnSizeChangedListener { width, height -> + println("w: $width, h: $height") + } + +} \ No newline at end of file diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/CoroutineUpdateTask.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/CoroutineUpdateTask.kt new file mode 100644 index 0000000..c7d8476 --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/CoroutineUpdateTask.kt @@ -0,0 +1,31 @@ +package com.bennyhuo.kotlin.scheduledtask + +import kotlinx.coroutines.* + +class CoroutineUpdateTask : UpdateTask { + + private var scope: CoroutineScope? = null + + override fun scheduleUpdate(interval: Long) { + cancel() + val scope = CoroutineScope(Dispatchers.IO) + scope.launch { + while (isActive) { + try { + updateApi.getConfigSuspend().let(::println) + } catch (e: Exception) { + e.printStackTrace() + if (e is CancellationException) throw e + } + delay(interval) + } + } + + this.scope = scope + } + + override fun cancel() { + scope?.cancel() + scope = null + } +} \ No newline at end of file diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/HandlerUpdateTask.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/HandlerUpdateTask.kt new file mode 100644 index 0000000..2e93f0d --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/HandlerUpdateTask.kt @@ -0,0 +1,53 @@ +package com.bennyhuo.kotlin.scheduledtask + +import android.os.Handler +import android.os.HandlerThread +import android.os.Message +import retrofit2.Call +import retrofit2.Callback +import retrofit2.Response + +class HandlerUpdateTask : UpdateTask { + + private var handlerThread: HandlerThread? = null + private var handler: Handler? = null + + private fun Handler.triggerUpdateNext(delay: Long) { + val message = Message.obtain(handler) { + updateApi.getConfig().enqueue(object : Callback> { + override fun onResponse( + call: Call>, + response: Response> + ) { + println(response.body()) + } + + override fun onFailure(call: Call>, t: Throwable) { + t.printStackTrace() + } + }) + triggerUpdateNext(delay) + } + message.obj = this@HandlerUpdateTask + sendMessageDelayed(message, delay) + } + + override fun scheduleUpdate(interval: Long) { + cancel() + + val handlerThread = HandlerThread("handler-thread") + handlerThread.start() + val handler = Handler(handlerThread.looper) + handler.triggerUpdateNext(interval) + + this.handlerThread = handlerThread + this.handler = handler + } + + override fun cancel() { + handler?.removeCallbacksAndMessages(this) + handler = null + handlerThread?.quit() + handlerThread = null + } +} \ No newline at end of file diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/Main.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/Main.kt new file mode 100644 index 0000000..49268a0 --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/Main.kt @@ -0,0 +1,23 @@ +package com.bennyhuo.kotlin.scheduledtask + +import kotlinx.coroutines.delay + +suspend fun main() { + + val taskClasses = listOf( + TimerUpdateTask::class, + RxJavaUpdateTask::class, + HandlerUpdateTask::class, + CoroutineUpdateTask::class + ) + + taskClasses.forEach { + val task = it.java.newInstance() + println("${it.simpleName} start") + task.scheduleUpdate(1000) + delay(5000) + task.cancel() + println("${it.simpleName} cancel") + } + +} \ No newline at end of file diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/RxJavaUpdateTask.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/RxJavaUpdateTask.kt new file mode 100644 index 0000000..818eb56 --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/RxJavaUpdateTask.kt @@ -0,0 +1,30 @@ +package com.bennyhuo.kotlin.scheduledtask + +import io.reactivex.rxjava3.core.Observable +import io.reactivex.rxjava3.disposables.Disposable +import io.reactivex.rxjava3.schedulers.Schedulers +import java.util.concurrent.TimeUnit + +class RxJavaUpdateTask : UpdateTask { + + private var disposable: Disposable? = null + + override fun scheduleUpdate(interval: Long) { + cancel() + + disposable = Observable.interval(interval, TimeUnit.MILLISECONDS) + .observeOn(Schedulers.io()) + .flatMap { + updateApi.getConfigObservable() + }.onErrorResumeNext { + Observable.just(emptyList()) + }.subscribe { + println(it) + } + } + + override fun cancel() { + disposable?.dispose() + disposable = null + } +} \ No newline at end of file diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/TimerUpdateTask.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/TimerUpdateTask.kt new file mode 100644 index 0000000..31aab65 --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/TimerUpdateTask.kt @@ -0,0 +1,40 @@ +package com.bennyhuo.kotlin.scheduledtask + +import retrofit2.Call +import retrofit2.Callback +import retrofit2.Response +import java.util.* + +class TimerUpdateTask : UpdateTask { + + private var timer: Timer? = null + + override fun scheduleUpdate(interval: Long) { + cancel() + + val timer = Timer() + timer.schedule(object : TimerTask() { + override fun run() { + updateApi.getConfig().enqueue(object : Callback> { + override fun onResponse( + call: Call>, + response: Response> + ) { + println(response.body()) + } + + override fun onFailure(call: Call>, t: Throwable) { + t.printStackTrace() + } + }) + } + }, 0L, interval) + + this.timer = timer + } + + override fun cancel() { + timer?.cancel() + timer = null + } +} \ No newline at end of file diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/UpdateApi.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/UpdateApi.kt new file mode 100644 index 0000000..87b592a --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/UpdateApi.kt @@ -0,0 +1,41 @@ +package com.bennyhuo.kotlin.scheduledtask + +import io.reactivex.rxjava3.core.Observable +import okhttp3.Dispatcher +import okhttp3.OkHttpClient +import retrofit2.Call +import retrofit2.Retrofit +import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory +import retrofit2.converter.gson.GsonConverterFactory +import retrofit2.http.GET +import java.util.concurrent.Executors + +data class Config(val bannerId: String, val bannerUrl: String) + +interface UpdateApi { + + @GET("/") + suspend fun getConfigSuspend(): List + + @GET("/") + fun getConfig(): Call> + + @GET("/") + fun getConfigObservable(): Observable> +} + +val updateApi by lazy { + Retrofit.Builder() + .client( + OkHttpClient.Builder() + .dispatcher(Dispatcher(Executors.newFixedThreadPool(3) { + Thread(it).also { it.isDaemon = true } + })) + .build() + ) + .addCallAdapterFactory(RxJava3CallAdapterFactory.create()) + .addConverterFactory(GsonConverterFactory.create()) + .baseUrl("http://localhost:8080") + .build() + .create(UpdateApi::class.java) +} diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/UpdateTask.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/UpdateTask.kt new file mode 100644 index 0000000..e36dd43 --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/UpdateTask.kt @@ -0,0 +1,10 @@ +package com.bennyhuo.kotlin.scheduledtask + +interface UpdateTask { + + fun scheduleUpdate(interval: Long) + + fun cancel() + +} + From 1685cb1d253720426b77a073f8a9822d939482d0 Mon Sep 17 00:00:00 2001 From: bennyhuo Date: Sun, 6 Jun 2021 22:29:50 +0800 Subject: [PATCH 24/60] Update code of Delicate GlobalScope. --- code/Kotlin-Sample/build.gradle.kts | 7 +++++++ .../coroutinesupdate/DelicatedGlobalScope.kt | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/DelicatedGlobalScope.kt diff --git a/code/Kotlin-Sample/build.gradle.kts b/code/Kotlin-Sample/build.gradle.kts index 291fe6f..a427597 100644 --- a/code/Kotlin-Sample/build.gradle.kts +++ b/code/Kotlin-Sample/build.gradle.kts @@ -1,3 +1,5 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + plugins { java kotlin("jvm") version "1.5.10" @@ -25,6 +27,11 @@ dependencies { testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine") } +val compileKotlin: KotlinCompile by tasks +compileKotlin.kotlinOptions { + freeCompilerArgs = listOf("-Xopt-in=kotlin.RequiresOptIn") +} + tasks.getByName("test") { useJUnitPlatform() } \ No newline at end of file diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/DelicatedGlobalScope.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/DelicatedGlobalScope.kt new file mode 100644 index 0000000..d777222 --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/DelicatedGlobalScope.kt @@ -0,0 +1,19 @@ +package com.bennyhuo.kotlin.coroutinesupdate + +import kotlinx.coroutines.* + +@OptIn(DelicateCoroutinesApi::class) +suspend fun main() { + val jobInGlobal = GlobalScope.launch() { + println("扶我起来!我还能再战两年!") + }.join() + GlobalScope.cancel() + + val scope = CoroutineScope(Dispatchers.IO) + val job = scope.launch { + + } + + job.cancel() + scope.cancel() +} \ No newline at end of file From 07571f14404344c26ebff56bf8115097f7f2be9e Mon Sep 17 00:00:00 2001 From: bennyhuo Date: Sun, 6 Jun 2021 22:30:39 +0800 Subject: [PATCH 25/60] fix filename --- .../{DelicatedGlobalScope.kt => DelicateGlobalScope.kt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/{DelicatedGlobalScope.kt => DelicateGlobalScope.kt} (100%) diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/DelicatedGlobalScope.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/DelicateGlobalScope.kt similarity index 100% rename from code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/DelicatedGlobalScope.kt rename to code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/DelicateGlobalScope.kt From 80abe4b39db1f4ba3e84b2b85aa5d17b999297c4 Mon Sep 17 00:00:00 2001 From: Bennyhuo Date: Mon, 7 Jun 2021 09:39:23 +0800 Subject: [PATCH 26/60] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 738e9f2..a710236 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,8 @@ Kotlin 的一些很零碎的内容,放到这个栏目下面。 - [x] [[Kotlin 杂谈] SAM 转换遇到包内可见](https://www.bilibili.com/video/BV1wB4y1g79W/) >>[示例代码](code\Kotlin-Sample\src\main\java\com\bennyhuo\kotlin\samissue) - [x] [[Kotlin 杂谈] 使用协程实现轮询任务竟是这么简单](https://www.bilibili.com/video/BV11b4y1Z7sz/) >>[示例代码](code\Kotlin-Sample\src\main\java\com\bennyhuo\kotlin\scheduledtask) +- [x] [[Kotlin 协程 1.5] 什么?GlobalScope 竟被废弃了?](https://www.bilibili.com/video/BV1P64y1C7bF/) >>[示例代码](https://github.com/bennyhuo/Kotlin-Tutorials/blob/master/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/DelicateGlobalScope.kt) 2021-06-09 18:00:00 发布 + ### [Gradle 迁移 KTS 系列视频 (2021.4 已完结)](https://github.com/bennyhuo/Kotlin-Tutorials/issues/25) From b0394372027fc799ec1ecc3f4a21d4b9d3ce4b7a Mon Sep 17 00:00:00 2001 From: bennyhuo Date: Mon, 7 Jun 2021 22:03:10 +0800 Subject: [PATCH 27/60] OptIn --- code/Kotlin-Sample/build.gradle.kts | 1 + .../opt-in-sample/build.gradle.kts | 27 +++++++++++++++++++ .../kotlin/optinsample/Annotations.kt | 7 +++++ .../bennyhuo/kotlin/optinsample/SampleApi.kt | 17 ++++++++++++ code/Kotlin-Sample/settings.gradle.kts | 1 + .../com/bennyhuo/kotlin/optin/OptInSample.kt | 17 ++++++++++++ 6 files changed, 70 insertions(+) create mode 100644 code/Kotlin-Sample/opt-in-sample/build.gradle.kts create mode 100644 code/Kotlin-Sample/opt-in-sample/src/main/java/com/bennyhuo/kotlin/optinsample/Annotations.kt create mode 100644 code/Kotlin-Sample/opt-in-sample/src/main/java/com/bennyhuo/kotlin/optinsample/SampleApi.kt create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/optin/OptInSample.kt diff --git a/code/Kotlin-Sample/build.gradle.kts b/code/Kotlin-Sample/build.gradle.kts index a427597..2a749ce 100644 --- a/code/Kotlin-Sample/build.gradle.kts +++ b/code/Kotlin-Sample/build.gradle.kts @@ -22,6 +22,7 @@ dependencies { implementation("com.bennyhuo:portable-android-handler:1.0") implementation("io.reactivex.rxjava3:rxjava:3.0.13") + implementation(project(":opt-in-sample")) testImplementation("org.junit.jupiter:junit-jupiter-api:5.6.0") testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine") diff --git a/code/Kotlin-Sample/opt-in-sample/build.gradle.kts b/code/Kotlin-Sample/opt-in-sample/build.gradle.kts new file mode 100644 index 0000000..1642f91 --- /dev/null +++ b/code/Kotlin-Sample/opt-in-sample/build.gradle.kts @@ -0,0 +1,27 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + java + kotlin("jvm") +} + +group = "com.bennyhuo" +version = "1.0-SNAPSHOT" + +repositories { + maven("https://mirrors.tencent.com/nexus/repository/maven-public/") +} + +dependencies { + implementation("org.jetbrains.kotlin:kotlin-stdlib") + testImplementation("org.junit.jupiter:junit-jupiter-api:5.7.0") + testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.7.0") +} + +tasks.getByName("compileKotlin") { + kotlinOptions.freeCompilerArgs = listOf("-Xopt-in=kotlin.RequiresOptIn") +} + +tasks.getByName("test") { + useJUnitPlatform() +} \ No newline at end of file diff --git a/code/Kotlin-Sample/opt-in-sample/src/main/java/com/bennyhuo/kotlin/optinsample/Annotations.kt b/code/Kotlin-Sample/opt-in-sample/src/main/java/com/bennyhuo/kotlin/optinsample/Annotations.kt new file mode 100644 index 0000000..9a02a36 --- /dev/null +++ b/code/Kotlin-Sample/opt-in-sample/src/main/java/com/bennyhuo/kotlin/optinsample/Annotations.kt @@ -0,0 +1,7 @@ +package com.bennyhuo.kotlin.optinsample + +@RequiresOptIn("This api is not stable!!", RequiresOptIn.Level.WARNING) +annotation class UnstableApi + +@RequiresOptIn("This api is removed.", RequiresOptIn.Level.ERROR) +annotation class UnsupportedApi diff --git a/code/Kotlin-Sample/opt-in-sample/src/main/java/com/bennyhuo/kotlin/optinsample/SampleApi.kt b/code/Kotlin-Sample/opt-in-sample/src/main/java/com/bennyhuo/kotlin/optinsample/SampleApi.kt new file mode 100644 index 0000000..6e04f60 --- /dev/null +++ b/code/Kotlin-Sample/opt-in-sample/src/main/java/com/bennyhuo/kotlin/optinsample/SampleApi.kt @@ -0,0 +1,17 @@ +package com.bennyhuo.kotlin.optinsample + +class SampleApi { + + fun stableAndFreeToUse() { + + } + + @UnstableApi + fun unstableAndPayAttention() { + + } + + @UnsupportedApi + fun removedApiDontUse(): Unit = error("removed.") + +} \ No newline at end of file diff --git a/code/Kotlin-Sample/settings.gradle.kts b/code/Kotlin-Sample/settings.gradle.kts index c6685f2..26492ed 100644 --- a/code/Kotlin-Sample/settings.gradle.kts +++ b/code/Kotlin-Sample/settings.gradle.kts @@ -1,2 +1,3 @@ rootProject.name = "Kotlin-Sample" +include(":opt-in-sample") \ No newline at end of file diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/optin/OptInSample.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/optin/OptInSample.kt new file mode 100644 index 0000000..04651a2 --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/optin/OptInSample.kt @@ -0,0 +1,17 @@ +package com.bennyhuo.kotlin.optin + +import com.bennyhuo.kotlin.optinsample.SampleApi +import com.bennyhuo.kotlin.optinsample.UnsupportedApi + +@UnsupportedApi +fun main() { + val sampleApi = SampleApi() + sampleApi.stableAndFreeToUse() + sampleApi.unstableAndPayAttention() + sampleApi.removedApiDontUse() +} + +@UnsupportedApi +fun main2() { + main() +} \ No newline at end of file From 2d4b70cd27e1f75f67ea139e3f4dd508affe2e8d Mon Sep 17 00:00:00 2001 From: bennyhuo Date: Mon, 7 Jun 2021 22:14:48 +0800 Subject: [PATCH 28/60] add optin video info --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index a710236..21ced7f 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ Kotlin 的一些很零碎的内容,放到这个栏目下面。 - [x] [[Kotlin 杂谈] SAM 转换遇到包内可见](https://www.bilibili.com/video/BV1wB4y1g79W/) >>[示例代码](code\Kotlin-Sample\src\main\java\com\bennyhuo\kotlin\samissue) - [x] [[Kotlin 杂谈] 使用协程实现轮询任务竟是这么简单](https://www.bilibili.com/video/BV11b4y1Z7sz/) >>[示例代码](code\Kotlin-Sample\src\main\java\com\bennyhuo\kotlin\scheduledtask) - [x] [[Kotlin 协程 1.5] 什么?GlobalScope 竟被废弃了?](https://www.bilibili.com/video/BV1P64y1C7bF/) >>[示例代码](https://github.com/bennyhuo/Kotlin-Tutorials/blob/master/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/DelicateGlobalScope.kt) 2021-06-09 18:00:00 发布 +- [x] [[Kotlin 杂谈] [Kotlin 杂谈] API 要谨慎使用?你可能需要 OptIn 注解!](https://www.bilibili.com/video/BV1Hh411a72d/) >>[示例代码](code\Kotlin-Sample\opt-in-sample) 2021-06-11 18:00:00 发布 ### [Gradle 迁移 KTS 系列视频 (2021.4 已完结)](https://github.com/bennyhuo/Kotlin-Tutorials/issues/25) From e7a75d5b0b152d2a8c534d065a0a625b6b4d049d Mon Sep 17 00:00:00 2001 From: Bennyhuo Date: Tue, 8 Jun 2021 10:13:35 +0800 Subject: [PATCH 29/60] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 21ced7f..dffe10e 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Kotlin 的一些很零碎的内容,放到这个栏目下面。 - [x] [[Kotlin 杂谈] SAM 转换遇到包内可见](https://www.bilibili.com/video/BV1wB4y1g79W/) >>[示例代码](code\Kotlin-Sample\src\main\java\com\bennyhuo\kotlin\samissue) - [x] [[Kotlin 杂谈] 使用协程实现轮询任务竟是这么简单](https://www.bilibili.com/video/BV11b4y1Z7sz/) >>[示例代码](code\Kotlin-Sample\src\main\java\com\bennyhuo\kotlin\scheduledtask) - [x] [[Kotlin 协程 1.5] 什么?GlobalScope 竟被废弃了?](https://www.bilibili.com/video/BV1P64y1C7bF/) >>[示例代码](https://github.com/bennyhuo/Kotlin-Tutorials/blob/master/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/DelicateGlobalScope.kt) 2021-06-09 18:00:00 发布 -- [x] [[Kotlin 杂谈] [Kotlin 杂谈] API 要谨慎使用?你可能需要 OptIn 注解!](https://www.bilibili.com/video/BV1Hh411a72d/) >>[示例代码](code\Kotlin-Sample\opt-in-sample) 2021-06-11 18:00:00 发布 +- [x] [[Kotlin 杂谈] API 要谨慎使用?你可能需要 OptIn 注解!](https://www.bilibili.com/video/BV1Hh411a72d/) >>[示例代码](code\Kotlin-Sample\opt-in-sample) 2021-06-11 18:00:00 发布 ### [Gradle 迁移 KTS 系列视频 (2021.4 已完结)](https://github.com/bennyhuo/Kotlin-Tutorials/issues/25) From d48181ca8d0b4abd7ad40b1e3b08941c4c999bda Mon Sep 17 00:00:00 2001 From: bennyhuo Date: Wed, 9 Jun 2021 07:42:23 +0800 Subject: [PATCH 30/60] Deprecated --- code/Kotlin-Sample/build.gradle.kts | 1 + .../deprecated-sample/build.gradle.kts | 27 +++++++++++++++++++ .../bennyhuo/kotlin/deprecatedsample/Api.kt | 20 ++++++++++++++ .../kotlin/deprecatedsample/v2/NewApi.kt | 9 +++++++ .../bennyhuo/kotlin/optinsample/SampleApi.kt | 16 +++++++++++ code/Kotlin-Sample/settings.gradle.kts | 2 +- .../kotlin/coroutinesupdate/NewChannelApis.kt | 11 ++++++++ .../kotlin/deprecated/DeprecatedSample.kt | 7 +++++ .../com/bennyhuo/kotlin/optin/OptInSample.kt | 6 ++--- 9 files changed, 95 insertions(+), 4 deletions(-) create mode 100644 code/Kotlin-Sample/deprecated-sample/build.gradle.kts create mode 100644 code/Kotlin-Sample/deprecated-sample/src/main/java/com/bennyhuo/kotlin/deprecatedsample/Api.kt create mode 100644 code/Kotlin-Sample/deprecated-sample/src/main/java/com/bennyhuo/kotlin/deprecatedsample/v2/NewApi.kt create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/NewChannelApis.kt create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/deprecated/DeprecatedSample.kt diff --git a/code/Kotlin-Sample/build.gradle.kts b/code/Kotlin-Sample/build.gradle.kts index 2a749ce..af1efa8 100644 --- a/code/Kotlin-Sample/build.gradle.kts +++ b/code/Kotlin-Sample/build.gradle.kts @@ -23,6 +23,7 @@ dependencies { implementation("io.reactivex.rxjava3:rxjava:3.0.13") implementation(project(":opt-in-sample")) + implementation(project(":deprecated-sample")) testImplementation("org.junit.jupiter:junit-jupiter-api:5.6.0") testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine") diff --git a/code/Kotlin-Sample/deprecated-sample/build.gradle.kts b/code/Kotlin-Sample/deprecated-sample/build.gradle.kts new file mode 100644 index 0000000..1642f91 --- /dev/null +++ b/code/Kotlin-Sample/deprecated-sample/build.gradle.kts @@ -0,0 +1,27 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + java + kotlin("jvm") +} + +group = "com.bennyhuo" +version = "1.0-SNAPSHOT" + +repositories { + maven("https://mirrors.tencent.com/nexus/repository/maven-public/") +} + +dependencies { + implementation("org.jetbrains.kotlin:kotlin-stdlib") + testImplementation("org.junit.jupiter:junit-jupiter-api:5.7.0") + testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.7.0") +} + +tasks.getByName("compileKotlin") { + kotlinOptions.freeCompilerArgs = listOf("-Xopt-in=kotlin.RequiresOptIn") +} + +tasks.getByName("test") { + useJUnitPlatform() +} \ No newline at end of file diff --git a/code/Kotlin-Sample/deprecated-sample/src/main/java/com/bennyhuo/kotlin/deprecatedsample/Api.kt b/code/Kotlin-Sample/deprecated-sample/src/main/java/com/bennyhuo/kotlin/deprecatedsample/Api.kt new file mode 100644 index 0000000..337d9e1 --- /dev/null +++ b/code/Kotlin-Sample/deprecated-sample/src/main/java/com/bennyhuo/kotlin/deprecatedsample/Api.kt @@ -0,0 +1,20 @@ +package com.bennyhuo.kotlin.deprecatedsample + +object Api { + + fun newApiForDeprecated(key: String, value: String) { + + } + + @Deprecated( + message = "Use newApiForDeprecated instead.", + replaceWith = ReplaceWith( + expression = "NewApi.newApiForDeprecated(key, value)", + imports = ["com.bennyhuo.kotlin.deprecatedsample.v2.NewApi"] + ) + ) + fun deprecatedDontUse(key: String, value: String) { + + } + +} \ No newline at end of file diff --git a/code/Kotlin-Sample/deprecated-sample/src/main/java/com/bennyhuo/kotlin/deprecatedsample/v2/NewApi.kt b/code/Kotlin-Sample/deprecated-sample/src/main/java/com/bennyhuo/kotlin/deprecatedsample/v2/NewApi.kt new file mode 100644 index 0000000..6bf9e99 --- /dev/null +++ b/code/Kotlin-Sample/deprecated-sample/src/main/java/com/bennyhuo/kotlin/deprecatedsample/v2/NewApi.kt @@ -0,0 +1,9 @@ +package com.bennyhuo.kotlin.deprecatedsample.v2 + +object NewApi { + + fun newApiForDeprecated(key: String, value: String) { + + } + +} \ No newline at end of file diff --git a/code/Kotlin-Sample/opt-in-sample/src/main/java/com/bennyhuo/kotlin/optinsample/SampleApi.kt b/code/Kotlin-Sample/opt-in-sample/src/main/java/com/bennyhuo/kotlin/optinsample/SampleApi.kt index 6e04f60..81b3e8a 100644 --- a/code/Kotlin-Sample/opt-in-sample/src/main/java/com/bennyhuo/kotlin/optinsample/SampleApi.kt +++ b/code/Kotlin-Sample/opt-in-sample/src/main/java/com/bennyhuo/kotlin/optinsample/SampleApi.kt @@ -11,7 +11,23 @@ class SampleApi { } + @Deprecated( + message = "Use stableAndFreeToUse instead.", + ReplaceWith("stableAndFreeToUse()") + ) @UnsupportedApi fun removedApiDontUse(): Unit = error("removed.") + fun newApiForDeprecated(key: String, value: String) { + + } + + @Deprecated( + message = "Use newApiForDeprecated instead.", + replaceWith = ReplaceWith("newApiForDeprecated(key, value)") + ) + fun deprecatedDontUse(key: String, value: String) { + + } + } \ No newline at end of file diff --git a/code/Kotlin-Sample/settings.gradle.kts b/code/Kotlin-Sample/settings.gradle.kts index 26492ed..c16ed77 100644 --- a/code/Kotlin-Sample/settings.gradle.kts +++ b/code/Kotlin-Sample/settings.gradle.kts @@ -1,3 +1,3 @@ rootProject.name = "Kotlin-Sample" -include(":opt-in-sample") \ No newline at end of file +include(":opt-in-sample",":deprecated-sample") \ No newline at end of file diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/NewChannelApis.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/NewChannelApis.kt new file mode 100644 index 0000000..0436ad3 --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/NewChannelApis.kt @@ -0,0 +1,11 @@ +package com.bennyhuo.kotlin.coroutinesupdate + +import kotlinx.coroutines.channels.Channel + +fun main() { + // offer -> + + val channel = Channel() + +// channel.offer() +} \ No newline at end of file diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/deprecated/DeprecatedSample.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/deprecated/DeprecatedSample.kt new file mode 100644 index 0000000..ab34d63 --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/deprecated/DeprecatedSample.kt @@ -0,0 +1,7 @@ +package com.bennyhuo.kotlin.deprecated + +import com.bennyhuo.kotlin.deprecatedsample.v2.NewApi + +fun main() { + NewApi.newApiForDeprecated("name", "bennyhuo 不是算命的") +} \ No newline at end of file diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/optin/OptInSample.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/optin/OptInSample.kt index 04651a2..ede6b53 100644 --- a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/optin/OptInSample.kt +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/optin/OptInSample.kt @@ -1,14 +1,14 @@ package com.bennyhuo.kotlin.optin -import com.bennyhuo.kotlin.optinsample.SampleApi -import com.bennyhuo.kotlin.optinsample.UnsupportedApi +import com.bennyhuo.kotlin.deprecatedsample.UnsupportedApi @UnsupportedApi fun main() { - val sampleApi = SampleApi() + val sampleApi = Api() sampleApi.stableAndFreeToUse() sampleApi.unstableAndPayAttention() sampleApi.removedApiDontUse() + sampleApi.newApiForDeprecated("a", "b") } @UnsupportedApi From 6131f2b63d2492284fce8f63127535bcc0062e25 Mon Sep 17 00:00:00 2001 From: bennyhuo Date: Thu, 10 Jun 2021 07:10:42 +0800 Subject: [PATCH 31/60] Channel Update --- .../kotlin/coroutinesupdate/NewChannelApis.kt | 51 +++++++++++++++++-- .../com/bennyhuo/kotlin/optin/OptInSample.kt | 6 ++- 2 files changed, 50 insertions(+), 7 deletions(-) diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/NewChannelApis.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/NewChannelApis.kt index 0436ad3..7ca8191 100644 --- a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/NewChannelApis.kt +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/NewChannelApis.kt @@ -1,11 +1,52 @@ package com.bennyhuo.kotlin.coroutinesupdate -import kotlinx.coroutines.channels.Channel - -fun main() { - // offer -> +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.channels.* +import kotlinx.coroutines.isActive +import kotlinx.coroutines.launch +import kotlinx.coroutines.selects.select +import kotlinx.coroutines.withContext +suspend fun main() { val channel = Channel() +// channel.trySend(1).isSuccess // offer +// channel.tryReceive().getOrNull() // poll +// +// channel.trySendBlocking(1) // sendBlocking + + withContext(Dispatchers.Default) { + val producer = launch { + (0 .. 5).forEach { + channel.send(it) + } + channel.close() + } + + val consumer = launch { + while (isActive && !channel.isClosedForReceive) { + select { + channel.onReceiveCatching { + println("$it - ${it.isClosed}") + } + } + + // or + // val value = channel.onReceiveCatching() + } + } + + + val consumer1 = produce { + + } + + val producer1 = actor { + + } + + + BroadcastChannel(1) + ConflatedBroadcastChannel() -// channel.offer() + } } \ No newline at end of file diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/optin/OptInSample.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/optin/OptInSample.kt index ede6b53..a6df165 100644 --- a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/optin/OptInSample.kt +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/optin/OptInSample.kt @@ -1,10 +1,12 @@ package com.bennyhuo.kotlin.optin -import com.bennyhuo.kotlin.deprecatedsample.UnsupportedApi +import com.bennyhuo.kotlin.optinsample.SampleApi +import com.bennyhuo.kotlin.optinsample.UnsupportedApi + @UnsupportedApi fun main() { - val sampleApi = Api() + val sampleApi = SampleApi() sampleApi.stableAndFreeToUse() sampleApi.unstableAndPayAttention() sampleApi.removedApiDontUse() From e5b95525c7e6fbb22ca860d28f372d2f0b44d76b Mon Sep 17 00:00:00 2001 From: Bennyhuo Date: Mon, 14 Jun 2021 19:41:39 +0800 Subject: [PATCH 32/60] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index dffe10e..d6cae4f 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,8 @@ Kotlin 的一些很零碎的内容,放到这个栏目下面。 - [x] [[Kotlin 杂谈] 使用协程实现轮询任务竟是这么简单](https://www.bilibili.com/video/BV11b4y1Z7sz/) >>[示例代码](code\Kotlin-Sample\src\main\java\com\bennyhuo\kotlin\scheduledtask) - [x] [[Kotlin 协程 1.5] 什么?GlobalScope 竟被废弃了?](https://www.bilibili.com/video/BV1P64y1C7bF/) >>[示例代码](https://github.com/bennyhuo/Kotlin-Tutorials/blob/master/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/DelicateGlobalScope.kt) 2021-06-09 18:00:00 发布 - [x] [[Kotlin 杂谈] API 要谨慎使用?你可能需要 OptIn 注解!](https://www.bilibili.com/video/BV1Hh411a72d/) >>[示例代码](code\Kotlin-Sample\opt-in-sample) 2021-06-11 18:00:00 发布 +- [x] [[Kotlin 杂谈] 要废弃 API ?@Deprecated 你学废了吗?](https://www.bilibili.com/video/BV1Mb4y1d7nv/) >>[示例代码](code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/deprecated/DeprecatedSample.kt) 2021-06-11 18:00:00 发布 +- [x] [[Kotlin 协程 1.5] 越更越惨的 Channel:我 TM 就是个倒霉蛋](https://www.bilibili.com/video/BV1rb4y1d7wL/) >>[示例代码](code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/NewChannelApis.kt) 2021-06-11 18:00:00 发布 ### [Gradle 迁移 KTS 系列视频 (2021.4 已完结)](https://github.com/bennyhuo/Kotlin-Tutorials/issues/25) From aca10dcf353346a9602581457625ea2fc6568315 Mon Sep 17 00:00:00 2001 From: Bennyhuo Date: Mon, 14 Jun 2021 19:42:23 +0800 Subject: [PATCH 33/60] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index d6cae4f..a7fbbb6 100644 --- a/README.md +++ b/README.md @@ -29,10 +29,10 @@ Kotlin 的一些很零碎的内容,放到这个栏目下面。 - [x] [[Kotlin 杂谈] SAM 转换遇到包内可见](https://www.bilibili.com/video/BV1wB4y1g79W/) >>[示例代码](code\Kotlin-Sample\src\main\java\com\bennyhuo\kotlin\samissue) - [x] [[Kotlin 杂谈] 使用协程实现轮询任务竟是这么简单](https://www.bilibili.com/video/BV11b4y1Z7sz/) >>[示例代码](code\Kotlin-Sample\src\main\java\com\bennyhuo\kotlin\scheduledtask) -- [x] [[Kotlin 协程 1.5] 什么?GlobalScope 竟被废弃了?](https://www.bilibili.com/video/BV1P64y1C7bF/) >>[示例代码](https://github.com/bennyhuo/Kotlin-Tutorials/blob/master/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/DelicateGlobalScope.kt) 2021-06-09 18:00:00 发布 -- [x] [[Kotlin 杂谈] API 要谨慎使用?你可能需要 OptIn 注解!](https://www.bilibili.com/video/BV1Hh411a72d/) >>[示例代码](code\Kotlin-Sample\opt-in-sample) 2021-06-11 18:00:00 发布 -- [x] [[Kotlin 杂谈] 要废弃 API ?@Deprecated 你学废了吗?](https://www.bilibili.com/video/BV1Mb4y1d7nv/) >>[示例代码](code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/deprecated/DeprecatedSample.kt) 2021-06-11 18:00:00 发布 -- [x] [[Kotlin 协程 1.5] 越更越惨的 Channel:我 TM 就是个倒霉蛋](https://www.bilibili.com/video/BV1rb4y1d7wL/) >>[示例代码](code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/NewChannelApis.kt) 2021-06-11 18:00:00 发布 +- [x] [[Kotlin 协程 1.5] 什么?GlobalScope 竟被废弃了?](https://www.bilibili.com/video/BV1P64y1C7bF/) >>[示例代码](https://github.com/bennyhuo/Kotlin-Tutorials/blob/master/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/DelicateGlobalScope.kt) +- [x] [[Kotlin 杂谈] API 要谨慎使用?你可能需要 OptIn 注解!](https://www.bilibili.com/video/BV1Hh411a72d/) >>[示例代码](code\Kotlin-Sample\opt-in-sample) +- [x] [[Kotlin 杂谈] 要废弃 API ?@Deprecated 你学废了吗?](https://www.bilibili.com/video/BV1Mb4y1d7nv/) >>[示例代码](code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/deprecated/DeprecatedSample.kt) +- [x] [[Kotlin 协程 1.5] 越更越惨的 Channel:我 TM 就是个倒霉蛋](https://www.bilibili.com/video/BV1rb4y1d7wL/) >>[示例代码](code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/NewChannelApis.kt) ### [Gradle 迁移 KTS 系列视频 (2021.4 已完结)](https://github.com/bennyhuo/Kotlin-Tutorials/issues/25) From ce46386dadd33992abe179d8d319651c5e42cf61 Mon Sep 17 00:00:00 2001 From: bennyhuo Date: Fri, 11 Jun 2021 07:57:17 +0800 Subject: [PATCH 34/60] suspend to blocking --- code/Kotlin-Sample/build.gradle.kts | 1 + .../bennyhuo/kotlin/coroutines/JavaMain.java | 38 +++++++++++++++++++ .../kotlin/coroutines/SuspendToBlocking.kt | 34 +++++++++++++++++ 3 files changed, 73 insertions(+) create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutines/JavaMain.java create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutines/SuspendToBlocking.kt diff --git a/code/Kotlin-Sample/build.gradle.kts b/code/Kotlin-Sample/build.gradle.kts index af1efa8..dd41d33 100644 --- a/code/Kotlin-Sample/build.gradle.kts +++ b/code/Kotlin-Sample/build.gradle.kts @@ -15,6 +15,7 @@ repositories { dependencies { implementation(kotlin("stdlib")) implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.5.0") implementation("com.squareup.retrofit2:retrofit:2.9.0") implementation("com.squareup.retrofit2:adapter-rxjava3:2.9.0") diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutines/JavaMain.java b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutines/JavaMain.java new file mode 100644 index 0000000..d74b456 --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutines/JavaMain.java @@ -0,0 +1,38 @@ +package com.bennyhuo.kotlin.coroutines; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.CompletableFuture; + +import kotlin.coroutines.Continuation; +import kotlin.coroutines.CoroutineContext; +import kotlin.coroutines.EmptyCoroutineContext; +import kotlin.coroutines.intrinsics.IntrinsicsKt; + +public class JavaMain { + public static void main(String[] args) { + CompletableFuture future = new CompletableFuture<>(); + Object result = SuspendToBlockingKt.suspendableApi(new Continuation() { + @NotNull + @Override + public CoroutineContext getContext() { + return EmptyCoroutineContext.INSTANCE; + } + + @Override + public void resumeWith(@NotNull Object o) { + if(o instanceof String) { + future.complete((String) o); + } else { + future.completeExceptionally((Throwable) o); + } + } + }); + + if (result != IntrinsicsKt.getCOROUTINE_SUSPENDED()) { + future.complete((String) result); + } + + System.out.println(future.join()); + } +} diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutines/SuspendToBlocking.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutines/SuspendToBlocking.kt new file mode 100644 index 0000000..130eb62 --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutines/SuspendToBlocking.kt @@ -0,0 +1,34 @@ +package com.bennyhuo.kotlin.coroutines + +import kotlinx.coroutines.* +import kotlinx.coroutines.future.future +import kotlin.coroutines.EmptyCoroutineContext + +suspend fun suspendableApi(): String { + if(Math.random() > 0.5) delay(1000) + + return "bilibli 关注我:bennyhuo 不是算命的" +} + +fun futureMain() { + val scope = CoroutineScope(Dispatchers.IO) + + scope.future { + suspendableApi() + }.join() + .let(::println) +} + +fun main() { + val value = runBlocking { + suspendableApi() + } + println(value) + + futureMain() +} + +//suspend fun main() { +// val value = suspendableApi() +// println(value) +//} \ No newline at end of file From a64e7feea796b2be1ce5e15f52163661f3099691 Mon Sep 17 00:00:00 2001 From: bennyhuo Date: Mon, 14 Jun 2021 19:49:32 +0800 Subject: [PATCH 35/60] flow updates --- code/Kotlin-Sample/.gitignore | 5 + code/Kotlin-Sample/build.gradle.kts | 17 ++- code/Kotlin-Sample/buildSrc/build.gradle.kts | 7 + .../buildSrc/src/main/kotlin/Versions.kt | 2 + .../kotlin-android-sample/.gitignore | 1 + .../kotlin-android-sample/build.gradle.kts | 51 +++++++ .../kotlin-android-sample/gradle.properties | 2 + .../kotlin-android-sample/proguard-rules.pro | 21 +++ .../android/sample/ExampleInstrumentedTest.kt | 24 ++++ .../src/main/AndroidManifest.xml | 17 +++ .../src/main/assets/logback.xml | 13 ++ .../kotlin/android/sample/MainActivity.kt | 57 ++++++++ .../drawable-v24/ic_launcher_foreground.xml | 18 +++ .../res/drawable/ic_launcher_background.xml | 37 +++++ .../src/main/res/layout/activity_main.xml | 19 +++ .../res/mipmap-anydpi-v26/ic_launcher.xml | 5 + .../mipmap-anydpi-v26/ic_launcher_round.xml | 5 + .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 3593 bytes .../res/mipmap-hdpi/ic_launcher_round.png | Bin 0 -> 5339 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 2636 bytes .../res/mipmap-mdpi/ic_launcher_round.png | Bin 0 -> 3388 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 4926 bytes .../res/mipmap-xhdpi/ic_launcher_round.png | Bin 0 -> 7472 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 7909 bytes .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin 0 -> 11873 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 10652 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin 0 -> 16570 bytes .../src/main/res/values-night/themes.xml | 10 ++ .../src/main/res/values/colors.xml | 10 ++ .../src/main/res/values/strings.xml | 3 + .../src/main/res/values/themes.xml | 10 ++ .../kotlin/android/sample/ExampleUnitTest.kt | 17 +++ code/Kotlin-Sample/settings.gradle.kts | 3 +- .../{scheduledtask => api}/UpdateApi.kt | 2 +- .../kotlin/coroutinesupdate/FlowUpdates.kt | 129 ++++++++++++++++++ .../kotlin/coroutinesupdate/widgets/Button.kt | 22 +++ .../scheduledtask/CoroutineUpdateTask.kt | 1 + .../kotlin/scheduledtask/HandlerUpdateTask.kt | 2 + .../kotlin/scheduledtask/RxJavaUpdateTask.kt | 1 + .../kotlin/scheduledtask/TimerUpdateTask.kt | 2 + 40 files changed, 509 insertions(+), 4 deletions(-) create mode 100644 code/Kotlin-Sample/.gitignore create mode 100644 code/Kotlin-Sample/buildSrc/build.gradle.kts create mode 100644 code/Kotlin-Sample/buildSrc/src/main/kotlin/Versions.kt create mode 100644 code/Kotlin-Sample/kotlin-android-sample/.gitignore create mode 100644 code/Kotlin-Sample/kotlin-android-sample/build.gradle.kts create mode 100644 code/Kotlin-Sample/kotlin-android-sample/gradle.properties create mode 100644 code/Kotlin-Sample/kotlin-android-sample/proguard-rules.pro create mode 100644 code/Kotlin-Sample/kotlin-android-sample/src/androidTest/java/com/bennyhuo/kotlin/android/sample/ExampleInstrumentedTest.kt create mode 100644 code/Kotlin-Sample/kotlin-android-sample/src/main/AndroidManifest.xml create mode 100644 code/Kotlin-Sample/kotlin-android-sample/src/main/assets/logback.xml create mode 100644 code/Kotlin-Sample/kotlin-android-sample/src/main/java/com/bennyhuo/kotlin/android/sample/MainActivity.kt create mode 100644 code/Kotlin-Sample/kotlin-android-sample/src/main/res/drawable-v24/ic_launcher_foreground.xml create mode 100644 code/Kotlin-Sample/kotlin-android-sample/src/main/res/drawable/ic_launcher_background.xml create mode 100644 code/Kotlin-Sample/kotlin-android-sample/src/main/res/layout/activity_main.xml create mode 100644 code/Kotlin-Sample/kotlin-android-sample/src/main/res/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 code/Kotlin-Sample/kotlin-android-sample/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml create mode 100644 code/Kotlin-Sample/kotlin-android-sample/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 code/Kotlin-Sample/kotlin-android-sample/src/main/res/mipmap-hdpi/ic_launcher_round.png create mode 100644 code/Kotlin-Sample/kotlin-android-sample/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 code/Kotlin-Sample/kotlin-android-sample/src/main/res/mipmap-mdpi/ic_launcher_round.png create mode 100644 code/Kotlin-Sample/kotlin-android-sample/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 code/Kotlin-Sample/kotlin-android-sample/src/main/res/mipmap-xhdpi/ic_launcher_round.png create mode 100644 code/Kotlin-Sample/kotlin-android-sample/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 code/Kotlin-Sample/kotlin-android-sample/src/main/res/mipmap-xxhdpi/ic_launcher_round.png create mode 100644 code/Kotlin-Sample/kotlin-android-sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 code/Kotlin-Sample/kotlin-android-sample/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png create mode 100644 code/Kotlin-Sample/kotlin-android-sample/src/main/res/values-night/themes.xml create mode 100644 code/Kotlin-Sample/kotlin-android-sample/src/main/res/values/colors.xml create mode 100644 code/Kotlin-Sample/kotlin-android-sample/src/main/res/values/strings.xml create mode 100644 code/Kotlin-Sample/kotlin-android-sample/src/main/res/values/themes.xml create mode 100644 code/Kotlin-Sample/kotlin-android-sample/src/test/java/com/bennyhuo/kotlin/android/sample/ExampleUnitTest.kt rename code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/{scheduledtask => api}/UpdateApi.kt (96%) create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/FlowUpdates.kt create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/widgets/Button.kt diff --git a/code/Kotlin-Sample/.gitignore b/code/Kotlin-Sample/.gitignore new file mode 100644 index 0000000..6ea006e --- /dev/null +++ b/code/Kotlin-Sample/.gitignore @@ -0,0 +1,5 @@ +.idea +.gradle +*.iml +local.properties +build \ No newline at end of file diff --git a/code/Kotlin-Sample/build.gradle.kts b/code/Kotlin-Sample/build.gradle.kts index dd41d33..2628b05 100644 --- a/code/Kotlin-Sample/build.gradle.kts +++ b/code/Kotlin-Sample/build.gradle.kts @@ -1,5 +1,16 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile +buildscript { + val kotlin_version by extra("1.5.10") + repositories { + maven("https://mirrors.tencent.com/nexus/repository/maven-public/") + } + dependencies { + classpath("com.android.tools.build:gradle:4.1.3") + classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version") + } +} + plugins { java kotlin("jvm") version "1.5.10" @@ -8,8 +19,10 @@ plugins { group = "com.bennyhuo.kotlin.hello" version = "1.0-SNAPSHOT" -repositories { - maven("https://mirrors.tencent.com/nexus/repository/maven-public/") +allprojects { + repositories { + maven("https://mirrors.tencent.com/nexus/repository/maven-public/") + } } dependencies { diff --git a/code/Kotlin-Sample/buildSrc/build.gradle.kts b/code/Kotlin-Sample/buildSrc/build.gradle.kts new file mode 100644 index 0000000..3917f98 --- /dev/null +++ b/code/Kotlin-Sample/buildSrc/build.gradle.kts @@ -0,0 +1,7 @@ +plugins { + `kotlin-dsl` +} + +repositories { + maven("https://mirrors.tencent.com/nexus/repository/maven-public/") +} \ No newline at end of file diff --git a/code/Kotlin-Sample/buildSrc/src/main/kotlin/Versions.kt b/code/Kotlin-Sample/buildSrc/src/main/kotlin/Versions.kt new file mode 100644 index 0000000..4f99bd2 --- /dev/null +++ b/code/Kotlin-Sample/buildSrc/src/main/kotlin/Versions.kt @@ -0,0 +1,2 @@ +val kotlinVersion = "1.5.10" +val kotlinCoroutineVersion = "1.5.0" \ No newline at end of file diff --git a/code/Kotlin-Sample/kotlin-android-sample/.gitignore b/code/Kotlin-Sample/kotlin-android-sample/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/code/Kotlin-Sample/kotlin-android-sample/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/code/Kotlin-Sample/kotlin-android-sample/build.gradle.kts b/code/Kotlin-Sample/kotlin-android-sample/build.gradle.kts new file mode 100644 index 0000000..6e20a19 --- /dev/null +++ b/code/Kotlin-Sample/kotlin-android-sample/build.gradle.kts @@ -0,0 +1,51 @@ +plugins { + id("com.android.application") + id("kotlin-android") + id("kotlin-android-extensions") +} + +android { + compileSdkVersion(30) + buildToolsVersion ("30.0.3") + + defaultConfig { + applicationId = "com.bennyhuo.kotlin.android.sample" + minSdkVersion(16) + targetSdkVersion(30) + versionCode = 1 + versionName = "1.0" + + testInstrumentationRunner("android.support.test.runner.AndroidJUnitRunner") + } + + buildTypes { + val release by getting { + isMinifyEnabled = false + proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + kotlinOptions { + jvmTarget = "1.8" + } +} + +dependencies { + implementation("org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlinCoroutineVersion") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlinCoroutineVersion") + + implementation("androidx.appcompat:appcompat:1.3.0") + implementation("androidx.constraintlayout:constraintlayout:2.0.4") + implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.3.1") + + api("org.slf4j:slf4j-api:1.7.30") + api("com.github.tony19:logback-android:2.0.0") + + testImplementation("junit:junit:4.+") + androidTestImplementation("com.android.support.test:runner:1.0.2") + androidTestImplementation("com.android.support.test.espresso:espresso-core:3.0.2") +} \ No newline at end of file diff --git a/code/Kotlin-Sample/kotlin-android-sample/gradle.properties b/code/Kotlin-Sample/kotlin-android-sample/gradle.properties new file mode 100644 index 0000000..646c51b --- /dev/null +++ b/code/Kotlin-Sample/kotlin-android-sample/gradle.properties @@ -0,0 +1,2 @@ +android.useAndroidX=true +android.enableJetifier=true diff --git a/code/Kotlin-Sample/kotlin-android-sample/proguard-rules.pro b/code/Kotlin-Sample/kotlin-android-sample/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/code/Kotlin-Sample/kotlin-android-sample/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/code/Kotlin-Sample/kotlin-android-sample/src/androidTest/java/com/bennyhuo/kotlin/android/sample/ExampleInstrumentedTest.kt b/code/Kotlin-Sample/kotlin-android-sample/src/androidTest/java/com/bennyhuo/kotlin/android/sample/ExampleInstrumentedTest.kt new file mode 100644 index 0000000..5f627d2 --- /dev/null +++ b/code/Kotlin-Sample/kotlin-android-sample/src/androidTest/java/com/bennyhuo/kotlin/android/sample/ExampleInstrumentedTest.kt @@ -0,0 +1,24 @@ +package com.bennyhuo.kotlin.android.sample + +import android.support.test.InstrumentationRegistry +import android.support.test.runner.AndroidJUnit4 + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("com.bennyhuo.kotlin.android.sample", appContext.packageName) + } +} \ No newline at end of file diff --git a/code/Kotlin-Sample/kotlin-android-sample/src/main/AndroidManifest.xml b/code/Kotlin-Sample/kotlin-android-sample/src/main/AndroidManifest.xml new file mode 100644 index 0000000..d2a8aa2 --- /dev/null +++ b/code/Kotlin-Sample/kotlin-android-sample/src/main/AndroidManifest.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/code/Kotlin-Sample/kotlin-android-sample/src/main/assets/logback.xml b/code/Kotlin-Sample/kotlin-android-sample/src/main/assets/logback.xml new file mode 100644 index 0000000..e7cb5ba --- /dev/null +++ b/code/Kotlin-Sample/kotlin-android-sample/src/main/assets/logback.xml @@ -0,0 +1,13 @@ + + + + + + [%thread](%file:%line\)%M: %msg%n + + + + + + + diff --git a/code/Kotlin-Sample/kotlin-android-sample/src/main/java/com/bennyhuo/kotlin/android/sample/MainActivity.kt b/code/Kotlin-Sample/kotlin-android-sample/src/main/java/com/bennyhuo/kotlin/android/sample/MainActivity.kt new file mode 100644 index 0000000..1f5ba4b --- /dev/null +++ b/code/Kotlin-Sample/kotlin-android-sample/src/main/java/com/bennyhuo/kotlin/android/sample/MainActivity.kt @@ -0,0 +1,57 @@ +package com.bennyhuo.kotlin.android.sample + +import android.animation.ObjectAnimator +import android.os.Bundle +import android.view.View +import android.view.ViewPropertyAnimator +import androidx.appcompat.app.AppCompatActivity +import androidx.lifecycle.lifecycleScope +import kotlinx.android.synthetic.main.activity_main.* +import kotlinx.coroutines.channels.awaitClose +import kotlinx.coroutines.channels.trySendBlocking +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.callbackFlow +import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.launch +import org.slf4j.LoggerFactory + +class MainActivity : AppCompatActivity() { + private val logger = LoggerFactory.getLogger(MainActivity::class.java) + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_main) + + lifecycleScope.launch { + getTextViewPositionFlow() + .collect { + logger.debug(it.toString()) + } + } + + textView.setOnClickListener { + ObjectAnimator.ofFloat(textView, "x", 0f, 1000f) + .setDuration(1000) + .start() + + ObjectAnimator.ofFloat(textView, "y", 0f, 500f) + .setDuration(1000) + .start() + } + } + + private fun getTextViewPositionFlow(): Flow> { + return callbackFlow> { + val listener = + View.OnLayoutChangeListener { v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom -> + logger.debug("left: $left, top: $top") + trySendBlocking(top to left) + } + textView.addOnLayoutChangeListener(listener) + + awaitClose { + textView.removeOnLayoutChangeListener(listener) + } + } + } +} \ No newline at end of file diff --git a/code/Kotlin-Sample/kotlin-android-sample/src/main/res/drawable-v24/ic_launcher_foreground.xml b/code/Kotlin-Sample/kotlin-android-sample/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..1babaae --- /dev/null +++ b/code/Kotlin-Sample/kotlin-android-sample/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/code/Kotlin-Sample/kotlin-android-sample/src/main/res/drawable/ic_launcher_background.xml b/code/Kotlin-Sample/kotlin-android-sample/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..f9a2c5a --- /dev/null +++ b/code/Kotlin-Sample/kotlin-android-sample/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/code/Kotlin-Sample/kotlin-android-sample/src/main/res/layout/activity_main.xml b/code/Kotlin-Sample/kotlin-android-sample/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..ca40db6 --- /dev/null +++ b/code/Kotlin-Sample/kotlin-android-sample/src/main/res/layout/activity_main.xml @@ -0,0 +1,19 @@ + + + + + + \ No newline at end of file diff --git a/code/Kotlin-Sample/kotlin-android-sample/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/code/Kotlin-Sample/kotlin-android-sample/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000..eca70cf --- /dev/null +++ b/code/Kotlin-Sample/kotlin-android-sample/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/code/Kotlin-Sample/kotlin-android-sample/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/code/Kotlin-Sample/kotlin-android-sample/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000..eca70cf --- /dev/null +++ b/code/Kotlin-Sample/kotlin-android-sample/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/code/Kotlin-Sample/kotlin-android-sample/src/main/res/mipmap-hdpi/ic_launcher.png b/code/Kotlin-Sample/kotlin-android-sample/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..a571e60098c92c2baca8a5df62f2929cbff01b52 GIT binary patch literal 3593 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 P00000NkvXXu0mjfP=x?Y literal 0 HcmV?d00001 diff --git a/code/Kotlin-Sample/kotlin-android-sample/src/main/res/mipmap-hdpi/ic_launcher_round.png b/code/Kotlin-Sample/kotlin-android-sample/src/main/res/mipmap-hdpi/ic_launcher_round.png new file mode 100644 index 0000000000000000000000000000000000000000..61da551c5594a1f9d26193983d2cd69189014603 GIT binary patch literal 5339 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 literal 0 HcmV?d00001 diff --git a/code/Kotlin-Sample/kotlin-android-sample/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/code/Kotlin-Sample/kotlin-android-sample/src/main/res/mipmap-xxhdpi/ic_launcher_round.png new file mode 100644 index 0000000000000000000000000000000000000000..b216f2d313cc673d8b8c4da591c174ebed52795c GIT binary patch literal 11873 zcmV-nE}qeeP)>j(mnvHsDN`- z)Hpc!RY~GsN8h7-e0h){1pPyutMv!xY8((UfI!|$uSc$h*USS<3D;)>jA&v@d9D7< zHT4Fjd$j16?%uwChG$oUbXRr5R1Xal{*3>Jzr)wyYfFQK2UQ7FC4)xfYKnLmrg}CT zknXNCFx_kFjC)(1$K4CqX>!La*yN7qWum)8&xqa=WfSER0aGsfzxV7lce(d?1>-gF zT6j&oHvWy`fRfqbDIfBK#+iKbXJl;cI`!U`>C-Z|ZJwUFC3f0BTOUu$+zK-?w}I2c zzrg0fKA2AaJ?-8WL7Gm4*T8GxHSyZ?Z`|7&Lw??be;eC?ZBfFcU=N%Wj6KBvZxnGY zW*HlYn%(vHHM_eZiRe8Mh?L<^HSumhuE(R}*~|XjpKX@0A;&bsKgTTHKNn@1?*FMI ziC%~AA@9X&;I$@Z1myD9r^@@g@42>+Hj%br8^zmsYn%e-Q zJ01asY3^x8Y3?9WsvAD%7~OWuCO_vGrn==C-gf&mAk`CW|2+V+?`;R8+vIh(-2}>= zUIVX%*Tie%-@w1c|4r5gk!Tx9TaD8^OlXWGW|a;qty1|t3YvTjXbn@{9SzdluNiU^ z!ztArCo!8S#{egkOmsn+hyeP9f?z06_+GpQUdx07sE`aesB*~9*{p4%w$iqfK44!8 zx@6^ymlHUykB{k(yz9H$@Q(YNJZRid*#?}2DRtuI2~Z)RxHe|9HgoMKeZf9q-;^Mg zAvod#XmH1E(8!GSL2i$a!N?3>9-M6U>6U8ZD-xi55?LlU+9$4W>w}EbJq8yy4$6lF zagKOwV4UiyM_@UH!0>}S;_kZa;@nfE0!YlwjYwaY?fU3w-iL$qnZ!)}#A7{Wd{oLq z9Gw0ct2>ZE+$|R0d_r(sA0CAfch(7>EJXweg?*xZBOuXODX-tVaV&}&Bjuwgt3!S^ zyzOpF2JWTUAm-#7|# z`yNb>^X^rtA>vKwyn8#kxj#Pszl~4MgXR5QS#vXYfKb`o-v`^DgwbbNu4D1fF4*v2 z5Sg%JU@pUT@V$5qycS+lLHd@3W9^c8=*iT0FZD|4&iEj1N&3F__74yKyMc6Q=hKKR z$AAAMpVmJF%jMw_*#9h+KFe|)Y{$+g;owgu-cE+=;Ct~JcrC^1TSOL)`I7WK56myD z?Odq>Yd(!MxVpO0pgUeEgVWcLPsL6O&#*La7?|cISZ3+|;Q8i!p>Z7KX9f6f5WwIcT{gIli9H^Jc;nVYHw=1SpQ z7lFssgJ0*VG=uy(1H>&jX6yg$47#zlJ~&4T=gRmUVS`&PV?_nyY>`k2P{sF+&IOs1 zepgq5)&=WH3bl*R)7IZ)QRxyI=d~uIkcu^ap zN`MroZ&;vr(*<;6Y-7lreO2M{5L@M}qJPWPMLh0N0;IrwBXiX68gXU8HfwS2Dr}{i z51I{9R_GRtdz1hvZr}KLNH56=dLNnJzhWTDGkaBuS&S>Grbh{o0``q}Wzn|DWDcv# z-Ia-4*G*UJ;#`*!AO-Imy0R-PK;!HpNBLSIZY8sdW|Un!l65_!uB(KiFeN~W**8|G z54v#<&%fI;;~QGhD34WY7W-5+xaGE8l5$ifKnmP9TwuJu3N+8#?87-N_q3i5ob@g{ z=@58wiwm5U09B5@@d34Nfjz^p{BlO8uZPm*N2~1c(`A;i0VI1*(V9sHAmT0=YhAe}LpS8KjTfWEvwOeZ#pNb=wC9g*co?D^%u3 z?j2;-$LZES9XwtIMH=}D8!CymJqe}Nb{-FpgQV{%N`8;e!NaWQkeizeS-IKp=d*Z0 z*THsRd$3)yv`5yyxj#GxA+P?1oZKARC+r*cQI_@y?As@tQ@d-sVAdZlCOFs5Wod=@ z%xhHIx^2=~pR%<;)9-G9lP@m8$DAxW;CJ3XhFSNvS6U0S`2O$kB&vH$Qx_Hth}coORr_6AxujsJMnz>RD@nll zJnIb|_y-@K!;HJzDjh%${~m;w*>7ndurJuBip(&vY7ysF@8WXk{inGz&belidG)f` z^FmcKxape2Quhi62n)}TJx>x@p|dZp(0jBh3qS)?S3}CXe?->jFA~dPpDKKbf&hdd zX$4tdC39YrTb-6+kBpCfbmQy{_|s6Oy&bu{)=I`_1i;g**P?(L&ugwM0HLem;lVy& zUld`DOSG^UXAj-CPaTGHFH=g-OxRcbt~vV%abM*L5L%o~{{_Pb7EogfEa~7^BtVlh zHo?6Q|D$cjwqqZ#FAB3rO6C|#U)2v;Zo#=1?#7t=>h3(QuEA~B6lsHJd92oszO!Bw zP-7P3MLyX=1{o)CXxdtO-7zF{`7wP1)ufC-m`KF`8~@&L@|wYEYeXm9OVc;wR1Y}# zEKZcRW83kXinPj(b4=Y>u+6PD)QZ|~AY%-^5JfZyY@ z;PdDdZIdK@o0qvm3R~qoy*wCm|ueH}s?oID#m1a>0T9L-7zgcs8c71)cM1bdal$rYTd~bX3S8@iZfsP_S{QnG z*)Pa~BBT^>#2 zAY?+KIEckR-!2*1bV|miOw$ZMg>zw8SZ12;Ph$ywKdCYb+m3x0o9?G@0O6eD+>Z`- zebCxew+)ShB&ic(rs^xr6V@8jGPh(=fMob;rSbsC=AXTg{3gB9f>Th5Z|;EgKYJ7l zATsCZeasTPvb%VWGp0;zm0(qxy{KBh2-_cLWc~sZ?goAus350!;UXb!qGGE2xxkZ` z{=XyED3SJ25l&yj4d03P0zXZ>`-pw5=o4sBwhs>EEWEQ52K;5S8<~&@AQk8S7z5QZ zy6${zTIN;^R&$Ih@GNEA0>Fhhd8{HUim%q%h-@J*xKe+>h?=jE(6`p^=@bJPhz_Bo@5Pw$X6Mu`BiRp=Vs11I+;(f>zz1B9!ne8IW23c8yJ zKZp3i_|wkxIpY2mg@ET{b`~7UhyaV2jW8)}HP|QafJ;x(1YHZq2FFO=0QHTu&+cqJ zSf8>{(rPphP`3>e`^Xz0{M{eVVg(IsNajW8xo0Ny+B=KWzFDCAhXtI=h_CR1vYofj zfzC-Q&^T^M^fQ(2sfB_eI`B9OOm2C|7oaHHEQtVO=Bb97w^=XaRL^(v1PC*YM;~7Z za$9I|#NpvJJ!mz&{7`Y3+_U$u;Kva6eDG+T;N+OR3*HKFXOG@LgIOt?zz~bRLdhkr0(BK)4P>voPD&ZRhsWmKdN;3kQEg()j<$ z3m_~$7h2cz^xaFCeSU2rcu=ONS5hlbQ2;%C{}M)Ba4rN7$|`;{y!a^0I^z50By6A% z8QgR&_cUJj!jh-0$M#V#9UxYT*lM(PTcew9neqS#|L@SVc)_>VV1{!nEebUEo9BZ^ z3% zE51hhef9?uNC(0AFi+4X!SjUh)v)hQi0szw!z&mSomf-}y3HYsrS^#9cjn^Aw&Cw^ossr>Jb~*@xHg zkiP%n@`hEC!vB#h{nq00VA&mT5W1 zC>fwu=9;z1bHhfQ z36vnnrYq0WK|j=1B;zm#Sdg%ZS|Y4yl(ndSLXr=txs0+vCR&Y@0H7{b-(wb5udDm$ zepBymeqUa<_25C_Ut*?5hlcVLBB*tFudt1(``Lt zqdY#eoohH0ndmU1f6Y<>VtIa@hJ8A=pPUwufdJ{>b}jQ83-RAyQk`?T)lX-C1e+_{ zDLgu%OF%!&mI1T|biH9cW&|WohA+o@jkO-hED&Kd(K)OM< z*@OCwz2p0o9xx^FfQ6y}!h;bqKRi)ReizW5pVjxV6BLMO6L^4I$GKgGD zKeay19R{7Zf6;NYjv=zZ77?pR1`q~IjT_e|Kerxrb#*ubBs7pN3ZQZ68zJ+}e{}0X zI=zNhAKubuY2H&vAGqsat&sTt2@zi7)yKEezxQK);SM|Q-Qjb=-<77!xBr9DaURrN z=||WxfV}g-Ves(kcX4@%5aC?ocZeAuSb#^|wWBOZ7(j~x>8AQ>^~iI}!NHDRWew1v zTdQGioIlJAT0`UoGtaNduVB>Le40gsg=1@@_QHY?f0%W_8)k(R*6dIprgeD=ns z1UyvHb{s^-xG%IoeUltPd&Bf?m`pX+?NVRT09q6WwHVS1GqI)`-jhbs6IunHlUQ69 zW{~1ci>->PB;-pn#HGG}4(K0T0CSG71_Sb}{>R)r9pu#ePjgOx%`2=!^QrnAo)6kb zEMfW?PZ)h_IcOZUfIhsASyFLDV3x%egHfGY0GdRm=UreX0ay3TBG5cz#p&$ALee_7 zC{IC5=dC#fTZ2i616apyfdL_oq770`i}Q)kwy46G_+S|UinJF4$hI&%3?K^8rNWko zKOd3&tsFJWAycFcp!3{V7a9jOB@NfYA z%m7-E2auHTZ~$3>X|M~md?J7Zz=ImV0~G2g7#@swC_qUBpm=YrWiA#T-58=+glI)R zh;WYagw|dM=G-K6{|#k;W1)(40I8@{Yhci>5yn9pXBPUF2SBvJ*H+PqD-9m?0}P-O zUIZX3!SGOkjuL>*@&H*%2ah;Fr+I*Upzj%L!SJBPLCcdLAnD;j8I%N&I6OpsW9?}{ zTEELH3b`+}_2YlVxv#I+rZK%ERZ4)wdw#-l>iR~=uZaF zUsi(Q>2t(_0JMMrw3-7*faT%g(c%FjF<0NS*2TjUR5CmiAOem}91oB%cre~Eh_VOE zfHx-s22`&c1XNYbKu zbY~b-6bBDl9JD;*011Hy-4zeenA03ULg1kQ5tn6l!4+na0KFhUl3JcZ0EIaUhKB>l zfdeQ(44_irp^A3^y=yCT^~s01=k8f}8b@a~_cf%Af5hEbb!Ng^_u4(%fj4pGbz`Ca zb!R$hMZv=ZH1{M2kWhFiK*tuqPv;mw0^z}UhX-hO0f3~12VE8gD1Ive$Vo6f2upr| z>?DRqmx#EoTVLjfYNhyXfgBemNS&$iI=hyx@99tu!2 z0q7zDD3JgpAv_eIM2FnI2@cR>_ssw5cWa}IbKX>~X+5FtE1w&y+ovU-4b$HEwB4_x z(|pVQOLs@!@P+|F_F(kaLZ(GvbZ8L_J7Nn9Pp^mXkJ^Fp5o=CIZ3^qy;yfKkEdk>b zocf7`Eu%6ygRAXFW1N;=~4GSXz zU`VhN3=DRFffrDYFfb%fgF>A06v}Hk3<~2kID9#bjdX|QiMzlw$^!;RtboChsFg4z ziq|R_5-l!g7#hPAi*kXXaV{`C-W_Z&@1*NQ!{S{zB@iXLGf+qp$^S=?8?Y^-q?x+>kuz;fKM73l{)%HwOloih)?&!PU*;_$LM?F(MP zyI|p&^q+PH$aU0c=q+d8CZx?B4@~@mOa$0t22PXmz%Kpl4u=&O*@JTrgwpVvi z*` zVQP?Psg`Fzk(P%OTAUeS-V~al7nT>YJo&6o5te6AIA?tZhp(WPXL-_ZU>fa7txwUG z#~Fsi6k&Oo^+An53v^`{U7a45;8vvN878tky!G+SL2IYsI|Ym9JJo4U=em}x?kj&V z-JJ&0Z8}&F979sRY)MmkSq~b=bt26(3u(+_cz7YTJca}&X=0v&>pVIqtYF4@FBo%{ z#6YF2^N7bhh0=5)y!U-hxG(4hEtV?gDVVAc40obdXJEu~sbZdj>pTWAj_~uPEigH0 zU5POdRRWEDK4Gax??23QnorQcmFG6~TGx{~crFMKl32TT`=)qvSr?5H3l1CHaFOUs z=*r@xdV{}R=!79S=&nQn34kXbK<5aYCl*K)Fc-H-C<5sGV!`lWpp4+;14sZoB7iP$ zg~`dJO{Kv@q?hQJgKbdrHa&}TTf1rPujz@b+?_ziTVVhXO<_&X1uCpx`Bf;mHrs3c>K8 z4C5SO0RnVU44|UmNpPgr2ix4mbtGn9U23&%+=kXZmr?Ls^vX0xXuJB|+iH_e{fmo> zC9O`E^_Q(U|8ociT(B1m55_wP(98>KIe<K8 zyE2S(5(B6xaERL?@aQHvaqB)ietJ|(t+_t6KCS9CEsNB>#FU;|A&%6}U46$p>S0|; zn!DTp!fbB%-)rbZQE;S$2ZbkuQGm|p0VEYXB7m&n$1o2LpbJX`!&3+#f$)d`x=H}L zL;xzn@*q6a`XoE$;yAUp8SH^`S>Dzse=LMs{IzPeCC^<+KpjC{*=^Tsd4Ay>ZouLs z_7PCeLjelm0kRSV4+V&r|8WGMxlw);AffP}#X)coAX?ij5FQFpJOZ?h0JJ_2pn~uu zIb~~;zuV1kVgi}N??}SlmX+?PmY4M@l#$ix(5xk{8MK(7F+wML*}LNQ$;$H^3lSom zENSa`bWbf30i-3R+Y(RJDL~;x03@KEXAl7h7YGMMuM`XqJu3(Sy2b!1;I=40NshUA zuUOALv)?x!N(1Lk<&}ArWQA~zpnlDk4Lgu$wQhlvR+ETc?f`LnXRA1fq^Rf7J-vul z5n?HZmH^AcXIt9A44`O#df1aJm4s+{@&P0O9tu#xat4r}2p|zWWRCix>pE%)o$SB& z!?|N~Sf9;lRTVircq>HD5mIST6OX{}rvB%=;C@$E7Rt)x@vY6cCWR9!>8?5gG>ZpF zhB8zNP=se5Kr&PkA~?7;K>-p74?Sp#0`v<^x$GwbhlfWmiLLqgjElrMV{_M-&81wd zPoaQXg)@JhYjtg|r+Lo$K34OKLnN=S{ig1W42~qb>R5i744#q0W!}Akg#Gf z5kN7k1j8c&=sE{bzXI^+lGkh6nmljYr;9XgVg#%`4M=r}1 zkB8(15MK&{lUiCCDg`LihXCYCwq3RHgM}T5@fP_~PB0#t)S_mL1;NbzXy1pHz zUSR+wvbcw2%jyTrb6ZW(wWO}AMT3s?elIx$&ZW6B+;nSFqgnkfXcoJ!pXf~&v{Kza z;VQK}0pi^mT7r_cC$N4Q0m51yErIY9256Z~m4pZm0yJ10ASvO&c*ii22gskE&e0e5 zx-KsN)cddnbhQ0`BhC?(O(^PY3Czfw(ex1H`*C zoVen)Cn!K+>k0uRZ6%=&0d;&N0VsAuK7fQ2gHeDk?}Wjzs|3S?GD=(lRw*1ndWlZB z-jkzo$_l=59djJ#hRsp)igaDYxw3jHwW&|VTS0pE+&eQAtNV=zMDhkGUrbcQA|aNa zViloTh?@u?A!Vo>K&$fsB(#!nusA>h;lX$(4g2t1lW)}Xf5EQ-vDI-Q$ZDy`{U zRiNuC$_iCwOW+M_HmunmeJoLLt%H`yCYPPT;{L8|$NL9m{@QP|bbs)Cc!EAl^7;X{ zJi#E`9`w%GfZkcAbBn<+XerDK^Mi>Yp3pC7G0_s}cb+Mj*HTUwIO!8W3d$hV7N$h4 zg`eXB>B(UFVRrPC45|oT_ViX8PQ)rli7DEVQ;Z}05a$LCS9ZhjcoH|pI&q3aEeE4` zrUXvL2`e}yiYaL&)xcyISbTj4%(@)|-CH1;^;^FgJWX%t6sxoc&-GLQ1-6ph+IVx0}#d4ytT60SqLNUXseVpoy10dE>E#`?l5p9Tov`5YR!ak`o(E0Usf z+D>B~)WVcsMOvJ)0|L@dXFFfq1E#+$zSF2(GXtCpHYbf0A?_(H9>NvPruEykRC|NSjnmJ?sGvT^&9F#0Ub`(~&A0uy7_!nhC*B6pY=>IqKKzrv!( zKp0Pc#zVlxg@=JtMWDQ3LL^g^7fhsD0~4dyz@+H4uq0s{I4AFcsj)sVDRwQ9H%y8{ z`Otf_P?M?F!Q=!^Q&5R0Uzn1_32T_wr5vG^gi|lBC-Q@-mzXYdns(VgPggcjO~1O4 z(=~kF0JBpzWxEh~ChxSr*P>^qK{yBXo7Km#qA8o3YKjO?zUoC5pf%$&v(}nwCR2~O z+%igDNn#=o!RJnoB(V>E=^8#u`(8tmo#AmOT4xs#H)cbNzz`)LH<9|mfojM6=h3rx5=kydl(Yu z40cy{!H{@oS_q~W>p*wYMZ){G;vMrX4)#lM;)KC65ym_ii;dZ~IE}%>XI#zLoK#n2 zcnWTH(A$A(aP)U;)UK6&pFMMuaWMC2@xPX zlMv74k)@JwFagMx0^}lbz^uow^I)ou0WSjJUXo?8`V2@yv7 zE$X$d_bqwuUcGvCjqcm0h3JsMr0YbfZgkO6UI6jyMEWGi#h3?cdC>9*g+~_wit(Z+ zf>D5Es3aUrEDzo_F(ko7VtD%IEfRjxII#fKJjX_mG1kJduF;f^c?&iN)fFvhmNYX{ zWgTeAI@FDHuy?nBiGSiG@MrN!3Q<`AgzA689W0VJ5r90X+Y(wy$N{v50c0mrB_UcK z5kLjuNhlf~+@8=&UQVksyEuSz?$u_t{+wP1=47%}>)g^@T3G^w z3!Agjx6zK>w;rc$f$*r- zRqd`)Q>7CNnCmLiLSb3PM0Hp?*^WWfvtGMq2HiGKzMw@c0lify)h%0I0O1O`;ol@X zi?$V142Id32%t!NnJNhp91bAY;>%EzoU+mS;Jy}#cf#tnX=sdNsM?}#4_edAjcuLE z81qPKiK?@;2;9hPOCaio`!g69bzV7QZJ(o-Z*YL{h*^44Rsm~N9sn7!`_AwfTxsih zcz|%B5CM{N>A7>pn+}Tx`Qn)2*s%{{TQ;V(KSy|q zT5QDCP(1ytl}f!D->NpM(-X~blcC*4ciS>03WHkymLYMsR$c(n?Cd79L{gMw;93u! zMTh_y@Bj%c21Cmu0*Kx8M?Oqgewu^7$3VI38q=62`rnvRmsLl#CypH*LvAcK3M*u z;3+CDs>ODRTNbcJy_*mGc8r?uxZ{0J{QLpq1hhaSGkkOS7|B4uH_?>#y`l&aPI74_ z8F&se9%hLrf)xTt0(f-U$zVDpvl^Q0o`XlM;7Mibd**!j#&y)mCI;V*EyC)wWMft9 zbB}kVwMI4A+C@|P39CV4qh6Tq;~=&etvR{RhN-75f_&c&j$H}taEDL4dy@tvNxqmC z18WLV3ELA05UwQ^0;m*ta65;@IG;$YlY?=NZoED8KW7KC{&IV(?m7NU^I<)vGH`m) zF{q*PEwegJ*%;OMQmu}p)~EsV@9ofJS8rGc7s=FdP`eJ(HtoH3;vNzs-KSr$c4Y){0F$KOY>eN6Od%>}g&Eh7L;yuQln4*HVcj^pPdW(>xw-@z%r@~_eU4i~k8RWL z_gFc0?>B~h%osT8w9lNoYR|@^fzs+o7aP@K*+ok_h;>!J!)%SWNVOW()9<`=sC)OV zQxp0evwW*VCJ#^Wz+-CJmxbgM2b45ljZNKIoPCjtgcP6zA9^Ms1xO4Y9qu6SPsG~f zlK1Bji$m{4*CFwh#_5I7Ywzs0UDuCKXlr5YLHc4KvN&}}A4y*sI4#*2)cKNQ9ii5! z8Z*^(Ss~QdG(IAqN-@{gn@F?854|RR<2-6>&z(PA(L8DS9w%6zSSEzShyX<_RIU+q zb*{Pi^MF*(Pqz2>!|c1i(62u-x?Qrc6a>pD3a|6n!Q@153Xpz`!zZ0+yIdUvCe|*8 z#5TD!K#t?S!vgD)d+nd|{yYDPS324b+uC$cx5?Ocww^;>l`3a(I%)#$RH%s@+&69twDR~x`*&V;!krzF3hsU|*4v!~_ zbI%zO@1A3EX-kgd_1(E+l2*frBoF$xzK?Q-!RH;p;NHy8uHez)y7+7{vt*hEiwK=g$s;azI!U@u7 z+_mkH9_B+9_I01K&3Mba(4l`UO&fmN>7{9eJ6K)Z3iGdTfk}V+!{pQen3}#BrrzBG z(=xXftEm~AVf>YKU>5HMrZJu{Cc+J7gnPr>3qCOX1WCmY*u3n&ZGM`b&rhM6PG;NG zruJXdxJ%oi%+mCs)`ql^S{u@4Y&+{ibJi!N#gP+8s%+W5KFdtLW_v-MDNJO7#4M8t zD5Abi^g55}ILpvV%fWPw&f3Ypb@Q8as@JyZvAy@rPSH4Eo}qcj;=b1L1^;QETKJUc zxz6cD&$Ul4e5!R~!GD^EE${ch*`klWX)~I*u;f=K0jie$!X<9PQpwA006m`<{e}F6La+= zCd8M<-#v%`fZtK;j*4l}+;#zxjj6@lrQXeft0k7uxxrm_q5=Z^mah{O(wnZ5c5%MLzTW;;&e^OY}{C ztn=uo)88w2r^)?25qlV}=l{KscK|wyNki?gG439O9Ob7R3OhtCXdyc=$QtU~O_t|@bak=wm@0{To0s)&_Zz1!!m}mZOs<$X= zET`&U*9Oz92!>_Pu;{solz-KYaP!x*ake?!GkD4CRh8LAD2}#rNlS*SKyLViG_!I( z1FgP^KFw-}(ir1Q^VGs4;=q_V1Jxr{Y@h7ZOUgLY>X6yAh(($%rQIVRuhH1JK0$?? zDVETM)0ZlvrEy$>Gl;7A<~rVKXEWL?rYzPOP*rZLr_Z&ew{A=BKHnDMjVTFVF^T05 zU+CA~s#slbJC%8kQg|J*jjotd*)yq{R%x`cJiWs(;{koDvs7e3|GgMLTcTSprt+cm z$Qu#|^U0zRF3Xu6(D^SzXUTeo>HfKDw`H-FhLu}LGujq%FRt(A!YEt+U=FLE5s9qV z>mp~3l~Dx;l{3-Ie?rVQH$N1%ki^ZM|53Ck`L%B0?e@o={qdjI3V%>D&t^oczm8Ow zejO?rJKz^}X-5yo|6PdRX6q_tv7?yoMmo8|?m|$Qq^Nyr%K6TK23~y>ycU&{~1j>eq z9Ks%pHs*?t6Gd*W_95ED&{lfYk0tA+@CF-c-D;(j`1uXsgS?!tf;aT*MYD)0Dcg)Gf>o-L(^(hCWMLVT>W-XzfyVgh> z71+re>L}QeGnM}kB`otCsaJmRKk4<_w^M8;WaOECJ*n=8y?`>B2}f;VMFhk6VTV}F z$RjM})O8LL!|{8oejqzB&>a}!wu!+hrd+eiD7$8DjL&U+!Je^Jzq?LEg${eYDq|QL z1cP#raZbKu;)z6ve3C72s_MjP6+JEle_rU`Wr}l{tcn7ljGAj_Hh>74myG*8M9H)! zZdZK%rT_66EW3W^I_aEy6;S&}VV#AW#L!?t-UrkQFq0@ZN>m`p17ur$|QOx<5RQ~W_&MB%xL7dV@g%DwdXyX%4G$lRh{;Nr9t zXkn+r-AhRXfMZ=raH6O6B{$vg@}Q5MZw1ULmMOu}q&QP(9qUcP#>2fRU)Clyw1paI z;b-gpL*S}U1qo6-M95i>4r_+5;u}{(sTRquUcNw&N4&nsjLd0-^euj30NJHNi65Wi1e>h&2Vob#rZ8%B4Aeqp*24#Hf89%mFnR07bX9*k5qv~pZ$~Bv&049y9 zecv-?UEvhXde2-OdzUO`Q9CXpD;ZJsGhCA7@GKov^@intitK?(UT5M)C#&{ryxeX4 zUG;gd!oiv*MQUV`S5H*aV2bpE0`mYTNN zgDMeX-veiiXwoY~UWG0`&aa&D|E-GUp$ED-C4N6t%df@k1u~1EZ5>R$gMg z=(pN3C{Ez2Z9sKMRA}7j43qs&>j$QdOw}T>g6pP_qZS_j(ZvAA_D>_BPOA--@uS~b z=pU(6nD!b3KEnK1rbu$nwI|EUJF@CDsQAj_?tYilT9AEOa6@dd`jp<>PH|)_{D1T1 z#xesVvv=9?oLBWj>48m)xM?dqR(Dq!X`gXApDjBv#MmW2zcy<%Mb@55tR%Se3Bge| zWcR855UnnG{zkp8tFQq%nxW~u`ww?(v{ft(z4*Iive7bUr*DSw|%YaE904Z zg{vWQQ+U$&HgW2LK2BY7H1;RccF z%W9%LoluENSHos%bNi&CP*L;$Of)~u>^PJkv62)NY(@PqL>F#&UHh)yiYL*2GKWlO zi#XLn8Jz{X@e_{OO*d|vkRTlj=vY!*MrfDMdw^E(d`W#?^tay?5$#7KQ4GXqAHJxD zkGGy^_mlEqFk+8n&P?>9@Auzddl11CrKDsPo&w zf5lM3T*L6I04aY%Fj6}Qq1@d3k+Rj5LwL(G=yHx1L)_3MHuYohe!n9O#fm1KPzL0c zP(R9Sn#H*vZTRySJ_6xPy$gcoXnQKCL!xctL0jfQFcr3c z&jo+~#;V}%_`1Ev&n6Kn*ni?)Ut~xUs+%t@m)1RFihj9Tg$?~3DzEos{O{RPZ%7C| zvnY!&hlyzTUewaT{-%q|-j_wJ7-bR!(|LB7$8T6$T{dj2k;%U?r-c%Pz_EK^Y<}Cp z#r@z~tFT>~FpH&c#UarjzyIuW-cwB(pVAB&Ryo)P4|V#p3GCRvE@P{mI@c9dp0A2f zu9f3>M0d1gKF`{Ef|L3p->P+SdH0sLQixnu?DWcSYT|dOG?p@tS3O=ILVFyU|4hE% zIdc2i;EP{l1|3Wkms>A_rXd6gk!%wqn|tFp*r2#5Bzkdbh3Zm=+J+mHdH7DKCwhiN zte__}3pWXjFOwOarn|7@%KWx_HB;}siOlK zR+XE$-me7BjT+tXWB#X?S ztn}K*Jab4!Fok!*gBuuWhy6fxvydq!Q*X#*?)FF5^_fqn_LgWt2D$9I`82goeu%fR z!TH0;Eb>%lXf_` zR$b6ml)W@-+X_AUEi~dIWL)sQ#GA+d=eE+5%o6?G)mXJAR%w%sTb}|t{|l6+9=^w~ zUJnu4inQ1qkn99qb6*ymN*S6=iw3*Y}^?WbKD_OG| z$U}o#TJq-T5oqv|w5|P5279l0{tDaAbIB(}#}dN8I7cAq7uMe==s2&tW#~n9-ZCC;pWNW|TxL(LE8LTc@mZqI*7oX+y_&V%h1c$=-sfXe#J!67BW5eU`y4&jAAMd5&L){8I49A(cAs9mNf{t|Aqj+^!f9Z7CX5G|@Hv z;WU8=na%*rCo@YEN9^*M5DUlO6T9EX{B8WbN-{0)gt&w3fuJ9Lw5Pyvn11FsuE+nU z+*5i8XhE3gPgoCdgL4|_u29lmsQechRfT!}}Y2jra)p)QFcRw;DZ^>vWZYnI1@1wjCI}G}uwScRd=*TQ-P=?$Rwwb1XprSCVL^0hk^hkHfJ0>D zQ0gjJgL=P|rLl;NbA#A(24TmNbTIKjY$S)qSS}-6}dcmw#4oQ|ptbv>Au9q5g zDFnzOXP0r07KBNB`U{BbVziFi*=#f+bu>3s?G)TU)r7SIH7*GnFvJsKn37mX_iJr{a48G=gc^#ZLRq2v zl~wTd_xzOf9JaQ=Xm7F!n-$ulkRi^#_|e0Ce4yO@Yg4qw?ILp4`kp;pnGXA&N4GaQ z(M285>ovF zJzq~ruP6+0RIUx^^(C9UpnhMC*@%%=;Ogf*lUY>(B|bMq)8oev4HHl%B*BhxpD`Xp zx~2hLH55uO=v713XC+hcS@B@p$|1j{3c*P^judPe4;GpdI&*svs?O5L3qCdkS>lcD z(;G`%_ck8zBv+#606~epIF+sO>#+`;x$12QoA`(`X<)|7HGw?^oiNBuprzob?<>iQ znh+Uv$ZU7I*0FCgUQkO0A2($QIrfb$M# zR@IX<1W~~X=O?#*OT(_Gf#Cggs%(~Zb(A;k){Q&*cPpN#RYR9e$r2l>pTM=0JsfNr zNG+W`qu4)pI3SCK$+VkjHI2EL>fxGJDopv6>dea=DLa6p_;<`ZB&laQQ`!<=3O_<( zQj0?;$>Tv}ek|E=;7c;4RYFIdPM81QN)5p0=IOfcXmsCd8hiJU^4K=X_?E3Av7pAne0?v_c67v2D~<5Kd}?Z1`066k_+- z4N+7Liguy53`HfvN0gSJYrZOVyuL))gEfz#H#(vBsM$|k0zr#}j00RKWO~s(hvM!; zH9z9x`#S`A=}C2b{K_1%hR(hu4Vm}y1=8N?J8Qio&e_+oOvTj-%RofhxM!s zGlkP=IUUnz1yZWi7YGpztUX4IrD|Bh3nROBb8S{5Y@2rr70a;=tD$ z@;Z^PFvVtS?akp(2jjH7-&;JK$)2)^M@S0DLl z=w`n;hbp=8BQl!%L`wZZXwNXdktbGKC~r!~>^rpv}IRweYExXtAchM>lx+nxaBwkWXA(U;~`Ou1@j8YMUPfHzD8`gp*Q`yepy^l z1U=YX4&hF5r1*xB7hBANP9V-20ADw-3nLx}C~2XLwCfmdJmzIVCNd!SKd;`h3)cT( zoxCLInUMKeUziLWt)|eSj}Vztp~4oyt^l~$5Ky{8)GVkbj0S>-SOH}kY7RL_z@&V3 zj6DtJ;D9#+V2))scw7uj8lgEw029y#*VI#j9>lZ;Ly@rm#o+p1BedEb^mQY1-7ARA zfcW51RSS4N2zI#|t~3`Q>lG!&0+Xa_pl6k&6Y-=){Qe>_XwOxziTDO24Jre;h{CtQ zLpdGNwKDf=x-xlFGz+Kli2&~vbs)9SVG+DbW#AvA;El9sqzJ}@3iI-zQliN3m>up{ zxv_Zs{BBN#ZKc0bX?e@^%A)if!BB-3gDcul0W>o36D-~sx1+;kk>VtvjMhu!;o~x& z(QY)T{NIM4Wizk~Gv1QJ;C?wVn9|Ok88`_4q~~}_>=R4uBY@UAP6hn}vxu*O<%K~T zowv(aAux%JAIwaiH%Kv@XKBFjXVa@8oLsm-668wy!MVgm4##`bhoG`2fEwx!U@wB1 zWKhmTLz-(wh4?V{=s4zb{~>fd(1VcbiPyr@FuzmRi$+kX6MpJ$ZnTv{HU~Z;q^UWg zu1-=@csP1IhR^Zb1&Np&7^sZwj0eaY3%cB<-iS(Y{@!G1Iz0q*pceUaF<*zYNVqH2yb#@SY4(TJ{3tg z&!a{!lI*p^IJ73X27ko2NEZRKn1y`6)6+2>!kF~~-_e$V!=3y&j_bBxzQf_+HrxmDBIAP{E+Xg{TWMTfYN_Q?@&+bYwcSWj473Y9Hhgp(DXpS$Fpev=QRPDyATA+Z8 zo-kT(r zjwl`?IM9jC5Z9hj9p^LI_IP6Cols~?Z~P#bpQWSr4&SzW1jM>w##sgTM`kuykUl>i zQtd`)^ECC^w)N@V;g1D%2w|$V8^@R^h`nVBA2NrAL@_6{0url*;=Dj+3n61(K@1s6 zwIQGH(mef)zgRIA8X$bwz9n2IZ2*Omz@xcELA+ z#*RBlpFQdJKW`)Lc#TDnMqLC#0^ARy%vMD#%>oTwAEM+Em423QI7{1w<}IIkTbGOf z3{x)f9W}S~buIjyvgJTtDSfkN<)abtJ2p}s_qXCz@kxi*rI#@W%VScVD1BFiuGV2u zvS2Dg_kdvLz!M?*i6~&jqEgeROjpa43$}-@_~7=6qY7e7ZD5%~O+ zGL|;n>BAQmQD^e4+rMov9YKN{@Hg)J`GtOWW2&tSR3Btp(G=wyGZdY_2SiH%0hlfn zH1wVQ^ijnX{9GgchYyx^RO(RV6h*CIZZFZ&G~F0KJVw8Btx~egXtkN&^aEu^)s^nB(z8O&=lk zA?I+{7{n-9X9Dt*A_gPekY(VMzn4umS2Cvo{yZQFGNm0;L$np2vMgMA6RI4bbJimv zm@ZXc=Z0j@5h6+X^%0LhL8Xn_|G`cgBRpHeAwH2-_lto~Hb4y=Irq02YuKE;(`+SK zCryo3!D9%Pj08K1@3+Bkp@MEyxgtgxK@vmiA!v{t1T$H+G9EmMYuH#~%~6F6&1*t@ z9Pt{;4>OGzq2;~tqUl|6`1w$J8i`?7CMm81hPJ3aO-*_d>Y?|IQKM7_27c9c(;ew; z4v>FiGy7=Z)54l_W@-f=hL_O*g7=A{d>%_3gBLXf`2`~a zLs0&QOf5Jux3(FuyYD&|2c`cMk~f~vf_D5t%p`aqe!A89%}?oa$n=2?0oUhx~bjsg`VO}G2FACuxVVfj$l3!l)w@&LFBTK5rNdoDlQc;Fi{BvKSl^bQZqqwWvr zUuA^5Plu@&mEqPa9}cIF#_jN{>zdCw3k&rYO#Wp-2LMGVo!{L^ee?Qk}IfM&H>n z>)zXizgwd04%7W3t{H%LbLeg-<=pwt?Mt5S3%?<$m6}dk;i5&^tVKhxo)XN?6yyZ^ zT+J4o>TXI%QfEblHX;ZmxLV@US4R{#dnEM#_=2J+u$E`D+&h;1K&zfcvpKWJ8`&Z-3#M%}S1FXZ78wxP#q?G{jAyIJ zJCpe<_`G5JzWRC%q-uE^vDu__Fl>80r3~Dit-6*T!*w7^B`b^`-%e$;`T?5GSgI@X zARyxlVBj;39Og3-TGBQMq~Pc-O_5d74@HP8XdYj-hiH>I!^Hm_UUnosKrhfY9#+1E zP1woPpDbCkcgBIwlvK-5?(2_}lNzEw$i6^Si4h-EMrDY>qtZjxtz-M}H|o2BsoG(4 zcXaIcxvNEE1;cCA`Qhe|Z&taQH`+4!NZxg|>3ls^TVTad{$+IERDbL@)sUT9PTqQL zfFPL#^IENm{+R9SFQb1vG}#*Nazr%yX;$`1!yi+wT{X zcN8VGJJt8@%UfL^UDX6ixgMND5~gIn_gocOO{9rfP5cZn*+^-(-E!v- zs_Lu$7zlPEin3y=A7|;KqAyb>yXSp{V z0(`|SZ5Id{t8V8^NtAzuOlKWMp+;k+I_+9Gfv$0D=t|@KecX$49_UMi_#(V({0~QU z@ufPiJyNx+EWw1P%0V?UA--(JuoQk0`JrvJC_?Iq7iGMb8s~$~DI7K5VdMvz^)Rz^ zVqH;k$mISv(6!mX;WM-Jr>4h~tG7!{AtdQUm>qTSV&a+8>l@@sA1Fqt zKBQ&y*L**fzM#Vh21NAlHwS%L*cp|+oWD4KG~tw9B>3{%W^MPvslj=7{=weC3&KL( zUDsKfuKcMPT$L38+2zg77Kf_{S1cUsS}S|C7U4|(N=dR(vbk(&k@t`zK>Up8@88uQ zT|XWeoSc>(xJVZ2@@@vW+4mXTIFdU1_Jb`qayPIN_oAD7_*}L^@cg1)_owT@-j^4I z+0YS)Gl95jV^q%duP>Qs8V)pWTHkFu@($8dKF$uY$SksL7oF?e8=P@^`7Ypi|CCP! zu0=?pF%p%MbR-urP(3kH-h25byJDtU7Qc0@l}ZCBZEzzKWe29_?GNo!p<7SHnj&g% zw;Zx}%@j7qS+Qb zNQ2d2uxsw~Z;7Dxb~?GSB>u_AW;Vj#&aI2C5toylWYAw7#^Jm^y3T)=#1o_^|KRkk zOx&q*6Ehs=UA$W8W9O#G(1?TIyvF{-D%g5t%zfPYnEj6{F80{y@R`eD`?71z(bO?| z-?*r2bdk0ZM|AU=cf3{bc`yaa5%xui+751TzwZE)6{(Dl_=O2uPr^#4sU`u-9mD)b2?jxVyVsk)p-j-5rV+cZc8GGY5%N`)qq>0%lm8H1uS zrdQ3<#fnm=+YqTy#qn+McW{6Nihq7Z%e?^;q5A?s$#eedqJriK_0fw%PWwIn2(QJCG|R zma%s1hZS$wg$RPFr;`@@oHqFnTgJs^f|N}7y)BROi2PG7Z`I^f3&-^cBK>#d0vX|3BeajwXf_ z)j5U~=eY+eVY^!~Xi7h8=*EXHwV9nP};_?~c{#{?CH^oz@I@oeyA*pCWq zw2e#6in8t6VUg~3Fa&usGc3uUi`HwI8+pFV13Xc|MXc`&C~b;JS1rj~QNxgMew1nB z4D7_d;*5Jbetta2!F8;T+(Ah#V>?ty2MFS6m6!<7mjssNi9{{Jd6I@mONNHezENXl zm{#X~@>eZ-wi)$l+aKLnZ2t9gmg+|&I7jf48W7C)9)&jHBVmI}LsCPnYKEx&wW^VE zk_3I6Gz;n!XV3;6E?$whGo9~QBJ*mamzN?lAAM2Z4##_ND)HcXvtF(%>8NKz?UEE7 z?rLi929wAH*}Huek?7#OH9uDR4r4^!8 z!+gxw8yooRJ9R2gT&#u1ip(KfX%ZPD1Itr{km7v6<~ij(mB;Bl>MGf)sg^~Y0&dEE z#jWUQy1G&(W2h^+1%V_jB8^WDOj>ccmDoPAwDo4W>ZW)X17o$#|!LpDQEjR{+@%F;CNwQpbc zB&8N0M*~3Y(j31o2D+X~GVwA~fpbLt){>Oy*EQ|ti6O=2AeMa0bkTZp=5}8qH9C+Q z)!f4wQMt#uQe08ZqjVMvz>g*=u!sV=m|~a>$aBCW%zE4~9)Vkv!7nZN>}OGF7M&&U z$9Ixf(P|^!>m1XHitm*4XvJ}eeQ`7@bP=-I+erOa?-J-(`Zm$} zF<@@r4$ienzdE>v(!MbukitTUz5knc2hpuUPVoh~^3=n&#$4MsQ>|%MXh%Wyw3;Lc;%mI@i9@)W#Xg-2d^JJUX z&~w&rf_aYhCEa*bztc-(zwJ3V?3Zdid|1Z^p{R#y0mB@CKH^fF0JdLmoAQ!CBD!aA zH(hG-<9ec^3IF^y>>_1~G;E-+nJ_m*CrhTt#>(o-<`u^eA;|X61@utYA?h#B8<`&9 zlOihJ2^g-wYZsEa3g!N2YrnuitM(`ixg2I^P2DLf^5|iizv$Ndw|5~I+5+os3<|WQ zNe`R0z-@R^Gpv|v8kDp{=x=PpkL+5!`Ip{bk#dPaVEL;dW&5qXS|7ZG*Zh}2%bO^sQ zRZp&#l~(^~BpJ^=RO5lj(Vs_7TB}3bJ}{CZatr-DylRxD)fKHJ*}4Y$@8uzmlTdSNLC-=#x*qinNNdsti|E&#<_>gdGl#&xN0zplKnw zc{7i+`iFZT@HicD(p39DwfCUBR%9fzNdNE&BEEMS-5-UA4vVkY zK8b37zeRds)B-+MadU0|0jB$KV1lk`XDa7dZYcpm%r4=?U?K``7nh!}!PiG*Dl}S1@NdjmWipaWmOme@#>Sqa> zU7c~ErR-P1Z_^JhP0W3JSpY4-V#yp;zVTmiSl|faj&}H;tS?d((}FQ+=wzv}{tTo~ zSB@lFKq)|wC+#;&@HJ$`?)Wnk;~;gax{mFb%n8?lxcUD)j&Mg-E5XXH!BSd8e!WDn zRVvQZ_B(VxbNp^And`q1mup(`;z`zVtlpmYvPp%I@`{uYGwJ&v2v3MCC=Se`n2DN* z=F=rA@$IJLJtn^aqADzbm+5v*pT%TYiU7(2eU&3^G_pt`^)j$_GsaUlAHP@ok4c0S z4j4Tz+VcwVA%HES+4{n@USMIhH7XMB316QN8I3_)jbmt(^cAD34uk>VjP3WBEa2%T5 z?e9T7(kD6id^PQe`Vwc8v-d_83T?Ebb0P6OE_p43-*cEc)U|!Ci6Jy-lH-dV5mpRS z;JH1zTW>Q32jb&{`XG0CTTicx0NcQK=>U;^K9CS=QsVcujRm0U_;VWtV(sC+*(5p- z_BHjg2L$M%nt%(4>r;C}7^Vn1fr4%v`BM@;n&3TgCQySCP`X|z>FX;H)vH2R_WPX{ zz+or$2Q}q62=ZbZ5>p)J+V6bXRDmYRi;iO<>DC)f=-DtvFI{(X;CA-TJoKon7MDn) zHGDYZGq#X-8J#32uaN?fMh?b<6J*3HIkb{ z!q>07-hB&0EF`ZFU&K4g=Ti(~4w)=IjksgKvRFFjRph))2}uY^3`q*9I|@j3%19UJ zi`y8!_<_t{+0z$Snh!C}Z4V=j{eUp|yO0_oKJl%vgG5z?EotRu-$%uzt9v%iiISs$ z%fS*sEj$p7d-EVzQ@UWCc^iWwkQ~x!9{XkY`Tu&-xT|lt`FHHZfO67xd=Szap|3U92aA!?O1 zheL&W8p?FKNvPt*EV- zty)SrPzD8-1<(p*Zck)|O7$wXrB~>8Z&8V|lEaYOSVlF#K`>cm6m~n30zXefVzM2V;gS5NNcITZli$)d{hZ z$u*se_D@8bWq#j5)Rm%qLe+MoaQUeDG^+lj=a`Z!j5vhLHk>Ipj|%CHxM}Q!t=`6% z5J%#^e+C9N6c)i}655NIiKfND`I}f$3xAF8USJfVFP7vVa%|eW?8BYQKFiJc)(_+Dd_GUGu1kc?Sw?w4 zte+9lcOQw`0C`bE1Xk*z36A7i|In_Z$4yQ1p9 zXIkrsPieLFTyy+rrZocx7%OM!g(sDZnsUHWD~r41(iI;^sBc88loByuk3@=S+&gzm zzG~*qH%60Hc+wdvNW9um7M6@NORc6DdzQV0!1I@SOei|YB35Rx{M9s=MC3HB`2&g_ zW=(KtatzVmP=Dp|r>(1X-T`ewl3HbE>2FV)s6OU0>%SoybQqI=WGlOAn)Jdh+h+e} z*iMnlg=R5Zy(a{8%tVm!cM|=KI_M3IrqJx4H$1PP4-*DXNg)VOht<7&ck6;0$JX=juH0!J$fGM`N)ijC;R(Z?3t%tvk<5f1l_Hx z+%aFtq-B`n&ZG_dB+By2)C73oGKsFSY>$;4UZ2dFjIVF=71H)VOQUYB*i3KI3$i&pNg|u#aTrTTm@L z1+3toJ-o7oq;h%>I(*L>^RYqP%|OiGAh+*+;(fe?H zJy0=(cL~&mOmaQ5N&C=kU&8D|-D9wF1*kLaK$g0;R}+@+G_v(U8;Pxlwm2aR+9C)x zm^Ay8q2u)3-E+{^*JQdR63{2lWpRW2AdP@7Msf&^&7BTDBGi|6WR>T6+Jca)w$FaZ z-iO&`R)@<|7anx2$tEW!8fN{r`W2Nn_IuzCWC{~LeHJ8|W(EVEm(D(~RXyqusl&*# zC)A(G&I|7ZM*oatC1+X|l15Qb61IUw{x)1opM9lxmT$T16>cf|j@@zE9Ze{y?}!7O z#SF0FI=*y29>u*%L8dMm%pdJ^Foat#jnhdjzooCGK#xwb=x&4ZF=#Tor`qLb*Z1Ow zo{~>;Ku#&NRa{@@^g3~!M6auYOT2e*|Irx&W5)YM{N_b+1igeVA`3IRRo9lVzX;h%`N94c2r_U10SXKEC^2_G3AKv)G{udqY~DTUCV!wU*5NmISYb z0S2_=#5n0cZ4=8>yKD>6#~N|5GXtCmM?$(s!Gn&}XqJ~{oJNdt0Ljmf3i2Pb>0s!X zsyIXQhg{JdTuYjY8~ZF;PybYS-Prtl61p(Y#=mMR)!BdpI1rWfOob zT~&5Eck1aXD}_AcB3_g@bWh9a@PS5sB<6bH=`CNzF~-kDDK2(;sM}Jz<2NQMgiwL* z<9`hdC_o$HSpX$dy55hz)UQ<`x*xzK>08M6_I6@VR??%sW45*wR_eg6Ne$`mk?X<- zFEwI7U!X6QGR&eL=GOzvGP(}L z|8Ruo|C!D$+MHdVroGT(8_ozbCr}y3?^mu2e#ZX!JPtK+`?+zps*rl|mwfCy-sjq{ ze2!D8ytcauy1>x8LmY=Ei?^$xA*mCFzZ&|$4t*Sy2J@@@{fU!65nP5L&*>LQR982N zXN2d)l>QBTtQlCJDz`W{LQH{YOhMZ#O}fn2mzBL?kc9fbk^SLymYyqQ9fd8?JhXq@ zpFJ>a&=}rvu){j>^seKL0ZIfH-j7SSXDOz2ZafXvQV>mfI;ac&Bs^Co?pO*;j<1`+ z_LI43#ida`P8=8isC!@B7L-m9#3a?(t<%Tl{PsOLEDZf0_z9oSaPmXnT{EF`dysL1 zQ$Zjlve}vA5r*ZBkvafbA=ZrH4`(}cC9zkwgJS0~0g3mP$?=+uD%N~w5u4%@raSvH zq3gQs|LDF9p=|67qD1d3N{kmj1ibP8SI;dK*;e!?eD}ASrSGEIl^s+?fSP>y-(jq& zomz1OD)ebvnRDUAN>#neL!G;4gHE|_;Zv35igN z19B?4=HLC@ubJK;Y811$q~D80>Knz|K<|3`OR0)&QNRql(f9$5)M>IhEx?a3!}nV< z8mU7lL+K2b)0_u$!>y~HnxoUtz!=C!ou3SmG`W=v(4cl$)-i-gi1O0ja9 zo6iixEu8IqUtbJkC3>+91;;L(2BcGm^YuL=_eYouo-gxrV>UyAwdBnAG}B&1734l$ zj(WsYD1Vg92SW2!Yrlsvc2|F>0s{b@_GX0-a2oF*zb1CNL@|2%O(A5aIu<)yYMpSqM#GIzb_SwrnvR zuSMKg`ABd;y2XMkIZ8v$9d9SA33qVrUaSYMWPW(Ulb*0naHX_6;pUh<=U_E@@M|j_ zQITFFy8hQxBzOfBO?iyH1U57fudPACUln(ujfFGsPN_}O205}b@%q|CLNGmE+5YGW zSHDW=v zt5_0tgTUHT1BC_#zsyOTtlKS;8y`L!jcx8l9$>(e#7EDiv0BAPE?o-VlrYQF^Ju2|jij})B5B*~ePB&; z54u5O;J}mzVfb&DaQrH{V4S6ER3_rG8QRB_v{whTo@Y+u5lBXbQP{wBqW5>5&z4`E zaBZdEXc`G*ks@c{KN+>M% zl+68+IY>@AQxhY>l#aGn7SIv}MNP)48|=;De8Hi!T*uAg;~gN!$VxJfU$Yf9)i(m2 zFM{8ZyX3!ifRl$JB=K{?N5*9fJm_O*klY7~B_`*L)FS-8=Fj|J!Nqh9(Nh=6(L^9m ze2a8J(V45Jvo7)Nv`&6ZpDMN{BpP~PA*c>EC&btNe*9SHe23}wcY-R=e)x1^u_(uz zsp+iL%|Zy|y`ilEtii=5pUV<~&nReCSS7GXFnsO87$O}99#7A;Z|MCp%@8wCqu=ot zrxhRNXukfpkmq$R)~`e*_pfjxlvR8SY=}AnOBCY9Y%JT!MxilQ2RLB3F;?ihM4;Q! z6LG<=;@hcjISBJ{o^9euKuC2wFk{Cy+T&33$Boupg%sqEc80ve2n0KAKBZWftft2w z2;P<~>e&l}YBJHF8qbQ#EQC+s6NWt56@nz~KK`C$l6SNDF zo7M%P>+w#o>*cy}rjNpZZ7zXz>T!L0S{gL{65bsn(ieu*QXp}KA3R2|L6%ER`!wi8 zLfT|%eawyrrMuKI)pKQ%1m!SvL@aMEr-YqUI7Q^^@q-yY5+w=fX0o-6^^!m1?fRCp zKxS?W1#8_c@xQ7^1kgTfn{Lw6xJA_=|BdV3pnhU*H~lRiCO?V2y~##RZW-!N6}Oaw z-ipXIyGl#*EL0Q!2BS6YBZ=$r*AJ&)o8W{dL#act4l1EL4ggTC25m79aMDu z6>d1CchA|i9IiW7gI1!L_X;-*ujM7JDe>v0AWPXTexJgMv-VOC<7kno=;jC3bjz?~ zOr8|@9t4Y)QgaoN>6EBsIh{<9TlWAoW0>HFML>uPVHcSvD0Y`A{}TO0m6phk;toA7r;<(k&G+hcSZ01(~pv zI0y{|x!xf~Hi_nc%wQJDFJd2tP`N+Q#j5Dfyct8?i+LD4n6d2&4i$GMh@d{&ISH9M zNkjFC;rf8KQKj>|V-F8=TyKYQSe;(xf*iL6D7Ig2*xOz#DDNx$2`MZC6bw59J4Z-R z?=2EwA(LvZo!vNrM0eV3hys$G^jT~f)I0hDwvn41FA%rloty1->~1E@G}esSWZlMW$BQ{H?03Lg3g&cKB8D=AEWi zQW71pnIs5>6pM2#CTD6fp9J@_WGKZ2BUs3pQ3&=0P+w{QpX;K-JchE-`qbSo>F*J* z5NYPerqO-!iUI2YFbfK7&}fGi%=PFn zbCt58p^})8o5FZT?Se@#{}Y{N#G^KdBMnUwXi@<4Zs~yXZ)0YIK`4r$?*Xp*s59ad zL}rQPJ8h6Zy4}BXE4&d@O9XFhKQ18{Y9bxcPi6eXxA|`#-)FLTuOY!`6pZThSrVUK z{Y7>^2HlVw=6(FgAS6Nj6GOX#3nx$JG{u-rE|d*ghQ$qIUzY6ArDyniO3au)MRFc3SR`E&`4Z*N#d@#XT?GDB>dJIQp^`At0Vwn<4?obElYPV zZPA3#*L=-(Y8bIw$@5lZIwT7w8uA1OrE-NAF6&ezQEa1W3YvFv^n{cU;oISX{p z$oJX$Q&CTSg78AEU~*xSI`R})nj`*;HWlTm6on(YbSNq4(UDUKb|J0_=x71^UGvhR z>cE_gzSM03I^=(q$U&U{s0$bnH-eW?#O}bF>5q#3HLtCL=iYl_7j+*-{81nKp`3L5 zn8JB@Re)30t18s|F0yJKqv}tIR?wFB+OYd)oF-`1tFevAl2>VPu=t>p2t+YS&_e^b zZz6O7>5L*Ynx!`yAc8FTw${Y*7-avqZ88OTAk%GBNy1Bf5<2VCCM^^fKXv8Wm8x)B z{;<$uC;i=M-Y}aVG@P|;gyai#DR!C2wT|~bE&N}Ub3mE}8}!r6 zX{@ z9v+8j=Ua0hB;p%F>cSnfgG*K&O<1Rvq;L7q%Y_me-nu8pUir>!KT0DJ`?tp#%JN)& zf7gJy3dlsRm5hFpo5>g`l%m0w!a|#6U($-75RDSjO2jZhN^V@W3fwU^?hjA-Q^KVk zb>aR?FW%kY0RL=+CL&fb>J3KRWfVlPHGJ@g*}2ms?*aZUR!FHB%e}TgZ(N#8O*Z1w z7Ea-e#2;07Wgfk@S#M8u{@H#LllZUWz@}6D z4O*3@(TJnaITPN$t{yb1>Evo}ti|iHjhsM$83qmE|rmtSPOwY9Y;py5YYv#5P`darC>}fjMe7WO!95 z$K9S1-#asy*PF20G2 zJ8@9hfW*%VRS3xqyh;;BqF$%r(XSStaHef)ea=odBNI==GqiMV% zmN++CeB`UdkI3i?(Wb*@G=hQ;~k-EO;Ssu6pN8f-v zVTgkHUuu7({KI&2Cadt|s^Egy2-}q@a6mFLr4#Rq9*$Ukyd=>GhLR3pNM9+Se6*kn zsc(n!lfp)$9#E{WCPrau1E*H^{Jh6&ONe50W*@%7gt^nGgB&{D*j_gryi1^{IhXl? z(i*c%-rOIghCp3*?UKttk2h=z0(Ap^993%~HY9l1u-8 z5E_NXJ#7OHJiUJj4dDJyoNXA^`(gDho)tD1cM6 z8bo-sc$cOhrc-wHF`Lg+soHZ_#QCN+>)zfTd6rVxhKO6wQ=+m1ktP=v1r%H0UXffU z3xLxt=%AASmv)pmm4k6o;ZEN-l12fq$6gxHBX=B=Id^SJj;q09{BiWfqaegRYnbYU~~^v9gfy~qW>Xh z94f8&|7eg6s%g;h-WEc`4I@M=hVBS5?Fh#Ej0wb>A_lH92j5#oq%nHdN&i5@T&`l= zO?Y=bO^ElYNfLIMGz%|??OzWTjK`_)U4O`d%yR-mJ8zDyAAd#I$3#MYXyOoSFpF02ST5rV3U=JFA76iOs^j;RW6%=VN+RzPwmkdN zS<28GtoWfvr6&0IJGC);uit8KpAs7u%J9hT;+27ROM%z3vFRF$m-HP4yQq?wJC)$} z0eom5{EFiBDZwNjQPc2J1<^f{85)uJICR0E+%oMLGy@Jbo*_Sedj0A)q^08ew*|&+ zb3)*?!4A6aT$LVZ5t5fxYyO4v@Z@d^bt=mLEEmEP9j^@-I-}p>)6hoKNrb>&Gei46 zy`zOQws=Gu0$AGl)4-Y`s0Qah+M$KTeKmq45Ae8JFiC`th}dj3wVhL@8May*A>>_I zG)W@}TZA0XBKGR@%XrV*pV_m;-^Y!ys2{cTgOFCS7 zfpdI(YGncGbU0T3;O2T4y|JU<6^jq`86f%sT+;SxWz=WFaWvw@x_(b_(tyv)z?#S~ zTzr`jMlep|V=&0nCo(`3grWpL%C47)smL(W%0+Qx2$a@|az7k7O~+Vo;!rc0&||H) z7?;-cef1Z;GH@OGqiL%ze@J8opIf6N9;^FO+Gq461mIv3_Y_cpsP6`_8*j0Nbc^%?D?8nu7PVUj`T#Htas$=|XLa>zLZM(jW z$4kT%c*R+KCuTRaqB$UP_2?J0)S8o%o98HgL7V;ivY;tNJEjt z{7=xpqSUk{a({w8E!?!tX@y|3YiTGO3;Lv>v5cZT@g37z!IYQ3VPzuf3S7AAPm^a# z`<|h%t*@sGSieVA9A#FUeIl(}fM;);Vn(2|1mEe|bl1R^0xNH{@Txj;<^I?CNiLy% z0T8*2N>gbwWU7dff&Z%(Rb)J$(O@9-(JXTqa{Cd&(Efro@1W^Ioj9=6qa-x zV{;1X&PQ%msPcRvnMuRV1i8|1N9)RDDO>!g&Q-H80_W|I}Z)-B*_ewVmyf)h)k@_Bw&wZwRjGYGF#v^2AuK=;EO z0Z1`80$pFZ@->{Ao3j!^$&UUN19l2HaH0;kUN~<@#Mx#Rf_XHW0Qo{$@)FtIK z`-TK+7UUr~C$&VE+i|Z5p=Fl4XfSwx87@^kga&}&+Q|Y z%a32lzLlEEbwWCiHMiA@9#v_{2usI3SFXcXnpe03v3tle?!f7~sA>ezA&L$gv*I-> z0zlt+3{H%7-HO3+*Rh4P$q~f0(xqNt66#KE_e(yoyEUS_2^;WsI z0VA-1Zi4kmqamn+I*{=d#ETAG!gG9qW$d|oJKw?<((4pKP6EN@Ehw1Spg?9n@cx4q zXx3c$NrlP$Ux@@c9haesM_R0kz*m%J5Pf{W4p}@mbz;Q+;C!53v%6jq`;?_>r~pK8*sSb)SKpE zj!xaKqUQI)5n9<6kaMj+OCJ;4!0Rb^77a%MUEMOaZ>jL$;(oV+V7hqrd8yz`$qXr@ zO}BS%1fAm4Zt@9xW+Lj8;#8B$PFTO2BxAK+RJOz&m3b6FTRmR2{85n6>^bd2(7 zwc>*XvK-$;!WLXqNoxRATzNQ^Vc0RdBK4NzHwc`n?p?E27l-xbdly)USn9PcWIE}) z4!hRZ>S&)nN8BNpzQ2*rBwuhy!b<61GN6h}9)h_Ml=ppKE#z(z~Hc@=5- zvWjAu<)OUm#lg^^_8TEw`m_s-!BN~gzeM}a) zjF>FwH(RPVfrmYKLQc-Qx3XO#S=21=1_9@3N=uJ(KJJZ~oK3$YJD!;RfMJETXdYG=YOK?3Qvys-Tyn zG-uE$#@7*`lOkTZlQt?MDf%oU&nWs(-@`caOp4 z`LmJJfX-15k!(}6KOox0_+4gN9=At3q8D$-8mQUM6Sp0{^cWJi%omyX*z1z>@>oer zIbyx;#JA%%=@kgOcy?=69`E;y|0c&9yiwHbq+3BZL;W=Iw=B6sOujQisL)8dH>rnP z-QD~c@gT}`ic6&50jUI5mRzbAH$H@shffJ~*9oDTH>1r;e8+cobB#p3s7560#F=xJF^R1@7vL=NEFr;b>bocxNMt^!P^Dt83dGZXG)w6* z&z4j;v(CAhVV_qzFVz#;Vu!cRk7*eAZ&P?SfEBJ72VLjqoz{>a+JD~u;u)`fZ`!WY z*_>ga<=>3g*&mJzdV{Zf*Hh7W7Bee_H1wfQOaE7Tf*dVijLbTlIkMMigDM|9F9m1T zV|v`#_)tkWD0qYt^hHFS!c&K?JJSQb!(@dLotS8~=OKjn%Fkq(*Zw>8o2feXIAC^=kA^yn zwpCL9qh$=UJzWs}_)^UrW=^+3u{~m(*<#}8=%j=DI?q*H$L)3}_JBC&kI%H$?r<<% zHKsobKXyc>>rwgyx%aEk0pSVyTA(2u(ApNNBYw+13~RoSHG@zkSxc0~Wf~&WMuyR&}_9F|k)9kO{)0ZW|509D6jrHD3J=KFIa9!2QuE+)m zu%bCh{#@k2HPO!If4`Dht68Gc#3_$4F+9{hL^r>6TBVKXSC})uw+@S259UiWgc!(iwJ9+4 z;?c2;RtztE5E?Z${vp&0DC8q;Csw2$3R3yGSdA7dm5*_-ae>_VKzJ<;RtXaKab2sC^@S#8URnXUaa)E43AuQ<@a=7R8 zvcHT>((`0(${jg#F~4V>o;O|f{R(`;Y-=fpY@9<}VDl$YGao#rg82Px=Q}*%tdgw> zTKmI_3tS2K@@|ddFlPt%{>D{tXnAKNUnVTJkS6eVi2TOnO0}@V+2Vp;4Bp;D%C!3! zQ6-vz^7i`=Sd-K#mq=tD=gW=aDuT}X_FmB1cr=|PK^q|C6^9?r_KTdmvIrMi{om|C*WFLb5_hhor--}Z1t>l~Dn+4ROFkf;CZMXIwNGqqy+n)7w)mK9NE!3$g)ShF)3~co>B|{AzrF`(R9^u(&P6+K#Utex?$6 zzHY{)xKx`dnWVJbz{*1T&80s&ToPz~{vbi_-Xo>MOWs^=r}atsbm_|q5Iqz0`H8m^NRpxWG)nx$~$KA$oB}T+Q^7x#1i9|0;r)0Ep z`=-o|x~h!EejO4_&3WT+>@-(Jr54aC9yU)blRqp(Ui{lAAxZqT^^a10lH83)1d3si zq+_v9+m}4daONBQNu$EgxHb{9NPF#eOiK^tJDQ|5RtXAP&Mzg1y9?iSvb#>+V+=(p z@vi39=mz;Bu~aOLQ{N(X3mVByN5Mor^Xk(=2-};jCSP%WKjX$db^6vMr$!g9w|ttG zNnJoCP~_*^qqyf>;o>$wwB}3d%(`vfbLS@yd0)aRUGB{|ja4N2H!Caf*!s;&5M(b| z=*Y>TT=663px!178Iyr8B8zC7Ubp)5w8(@mM#~$1((?>Gjp;phc|=d^zTAGHKWTYN zvKW)fO%bGEEfSFX9!@+>FQNH+fbMrOKCL(ePhx8-MQ?vTHWAzBkNNrsvLL@mXq4aWychS&o?VRf#rE6kC+$$+&hc{5Ne&rE zKG|$k`5GkOiPLU(lSo^{Q#V7u0_lhrk<7lbL3+cBEOOd#XAriVQ@+3@qb}HTuxDN^ zv)x~#Gl4^0lq>p%{FmcY(?u8ya3Ob@ZAm+CMJb$UAy`5y=AFaNgH_Z;QYHA=<Los^P4615`ATU{7m+Ws9*b#7eE9VF@ST`9htx%yTH(kV3I7kb02<`cmiAxi=ap zua~WEG}`!eGE}=q%y=89y43C4XRnVW=FdjNVxz7JFGwdm?bP{NF+*)u%aau!f4++P z?!4AP)CnETRq)m?R_BW^@s)du_o-^z|EMGsq5o{*a}_fvqV6DE*%tI>di|fTDWCX| z`_+7q7?x4@{q~2^*!9RR2biZSye6`b`sB(H^Zb6ovX9b@#D5(biRodW_yZvZ)tyqf z1amz!T**d2(NMWf>>o;VtSd2*^y1uA|H)@U3}I_*ncL-%gRjGvda-)jXDud|L2+jT zQbA#bKL@)*dt31@{%~_fx&6_tQ7;VV^JqRCA#iQppUi)0bkRz3Ay2#eWQvmCG#RY{ zYm$~BtG|)0h0`_~!?xoc!vOPSL?>-ebef z!i7>Tf;{u=k~zl)n!=Y5Fz!w)sV$;dzmme`^|TmmsbL%Zcu> zZ)H4KiklB{_n7KziFNl1|IClB zP%IL<_pAOBU`}y5T-Ikjvj@Y-r)eiG6>!pjOyTDVwH&{rSD75)Q2KZ-JFsaleEw3; z`cP1`%VM!O=86iIRCBvT6WU2sy9m$9AKyGQVhJnk;S--&}4|e zN literal 0 HcmV?d00001 diff --git a/code/Kotlin-Sample/kotlin-android-sample/src/main/res/values-night/themes.xml b/code/Kotlin-Sample/kotlin-android-sample/src/main/res/values-night/themes.xml new file mode 100644 index 0000000..06d5d58 --- /dev/null +++ b/code/Kotlin-Sample/kotlin-android-sample/src/main/res/values-night/themes.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/code/Kotlin-Sample/kotlin-android-sample/src/main/res/values/colors.xml b/code/Kotlin-Sample/kotlin-android-sample/src/main/res/values/colors.xml new file mode 100644 index 0000000..f8c6127 --- /dev/null +++ b/code/Kotlin-Sample/kotlin-android-sample/src/main/res/values/colors.xml @@ -0,0 +1,10 @@ + + + #FFBB86FC + #FF6200EE + #FF3700B3 + #FF03DAC5 + #FF018786 + #FF000000 + #FFFFFFFF + \ No newline at end of file diff --git a/code/Kotlin-Sample/kotlin-android-sample/src/main/res/values/strings.xml b/code/Kotlin-Sample/kotlin-android-sample/src/main/res/values/strings.xml new file mode 100644 index 0000000..f7bbc04 --- /dev/null +++ b/code/Kotlin-Sample/kotlin-android-sample/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + Kotlin-Android-Sample + \ No newline at end of file diff --git a/code/Kotlin-Sample/kotlin-android-sample/src/main/res/values/themes.xml b/code/Kotlin-Sample/kotlin-android-sample/src/main/res/values/themes.xml new file mode 100644 index 0000000..40bb80f --- /dev/null +++ b/code/Kotlin-Sample/kotlin-android-sample/src/main/res/values/themes.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/code/Kotlin-Sample/kotlin-android-sample/src/test/java/com/bennyhuo/kotlin/android/sample/ExampleUnitTest.kt b/code/Kotlin-Sample/kotlin-android-sample/src/test/java/com/bennyhuo/kotlin/android/sample/ExampleUnitTest.kt new file mode 100644 index 0000000..4680ac5 --- /dev/null +++ b/code/Kotlin-Sample/kotlin-android-sample/src/test/java/com/bennyhuo/kotlin/android/sample/ExampleUnitTest.kt @@ -0,0 +1,17 @@ +package com.bennyhuo.kotlin.android.sample + +import org.junit.Test + +import org.junit.Assert.* + +/** + * Example local unit test, which will execute on the development machine (host). + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +class ExampleUnitTest { + @Test + fun addition_isCorrect() { + assertEquals(4, 2 + 2) + } +} \ No newline at end of file diff --git a/code/Kotlin-Sample/settings.gradle.kts b/code/Kotlin-Sample/settings.gradle.kts index c16ed77..d3e81ad 100644 --- a/code/Kotlin-Sample/settings.gradle.kts +++ b/code/Kotlin-Sample/settings.gradle.kts @@ -1,3 +1,4 @@ rootProject.name = "Kotlin-Sample" -include(":opt-in-sample",":deprecated-sample") \ No newline at end of file +include(":opt-in-sample",":deprecated-sample") +include(":kotlin-android-sample") diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/UpdateApi.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/api/UpdateApi.kt similarity index 96% rename from code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/UpdateApi.kt rename to code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/api/UpdateApi.kt index 87b592a..9b2d767 100644 --- a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/UpdateApi.kt +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/api/UpdateApi.kt @@ -1,4 +1,4 @@ -package com.bennyhuo.kotlin.scheduledtask +package com.bennyhuo.kotlin.api import io.reactivex.rxjava3.core.Observable import okhttp3.Dispatcher diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/FlowUpdates.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/FlowUpdates.kt new file mode 100644 index 0000000..b5be589 --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/FlowUpdates.kt @@ -0,0 +1,129 @@ +package com.bennyhuo.kotlin.coroutinesupdate + +import android.os.Handler +import android.os.HandlerThread +import kotlinx.coroutines.* +import kotlinx.coroutines.channels.awaitClose +import kotlinx.coroutines.channels.trySendBlocking +import kotlinx.coroutines.flow.callbackFlow +import kotlinx.coroutines.flow.channelFlow +import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.flow.flow +import java.util.concurrent.CopyOnWriteArrayList +import kotlin.concurrent.thread + +suspend fun main() { + flowSamples() +} + +suspend fun flowSamples() { + flow { + emit(1) + emit(2) + }.collect { + println(it) + } + + channelFlow { + send(1) + withContext(Dispatchers.IO) { + send(2) + } + + thread { + trySendBlocking(3) + }.join() + }.collect { + println(it) + } + + callbackFlow { + send(1) + withContext(Dispatchers.IO) { + send(2) + } + + awaitClose { + // nothing to do. + println("closed") + } + }.collect { + println(it) + } +} + +suspend fun callbackFlowSample() { + val application = Application() + application.start() + + + val eventFlow = callbackFlow { + val callback = Application.Callback { + trySendBlocking(it) + } + application.registerCallback(callback) + + awaitClose { + application.unregisterCallback(callback) + } + } + + val scope = CoroutineScope(Dispatchers.IO) + scope.launch { + eventFlow.collect { + println(it) + } + } + + delay(5000) + scope.cancel() + + delay(10_000) + application.stop() +} + + +class Application { + + fun interface Callback { + fun onCallBack(value: Int) + } + + private val handlerThread = HandlerThread("App") + + private val handler by lazy { + handlerThread.start() + Handler(handlerThread.looper) + } + + private val callbacks = CopyOnWriteArrayList() + + fun registerCallback(callback: Callback) { + this.callbacks += callback + } + + fun unregisterCallback(callback: Callback) { + this.callbacks -= callback + } + + fun start() { + runApp() + } + + fun stop() { + handlerThread.quit() + } + + private var eventId = 0 + + private fun runApp() { + this.callbacks.forEach { + it.onCallBack(eventId) + } + + eventId++ + handler.postDelayed(::runApp, 1000) + } + +} + diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/widgets/Button.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/widgets/Button.kt new file mode 100644 index 0000000..ed732f3 --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/widgets/Button.kt @@ -0,0 +1,22 @@ +package com.bennyhuo.kotlin.coroutinesupdate.widgets + +fun interface OnClickListener { + fun onClick(view: View) +} + +open class View { + + private var onClickListener: OnClickListener? = null + + fun setOnClickListener(onClickListener: OnClickListener) { + this.onClickListener = onClickListener + } + + fun click() { + onClickListener?.onClick(this) + } +} + +class Button: View() { + +} \ No newline at end of file diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/CoroutineUpdateTask.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/CoroutineUpdateTask.kt index c7d8476..26c07a2 100644 --- a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/CoroutineUpdateTask.kt +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/CoroutineUpdateTask.kt @@ -1,5 +1,6 @@ package com.bennyhuo.kotlin.scheduledtask +import com.bennyhuo.kotlin.api.updateApi import kotlinx.coroutines.* class CoroutineUpdateTask : UpdateTask { diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/HandlerUpdateTask.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/HandlerUpdateTask.kt index 2e93f0d..3ae482a 100644 --- a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/HandlerUpdateTask.kt +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/HandlerUpdateTask.kt @@ -3,6 +3,8 @@ package com.bennyhuo.kotlin.scheduledtask import android.os.Handler import android.os.HandlerThread import android.os.Message +import com.bennyhuo.kotlin.api.Config +import com.bennyhuo.kotlin.api.updateApi import retrofit2.Call import retrofit2.Callback import retrofit2.Response diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/RxJavaUpdateTask.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/RxJavaUpdateTask.kt index 818eb56..65ef939 100644 --- a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/RxJavaUpdateTask.kt +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/RxJavaUpdateTask.kt @@ -1,5 +1,6 @@ package com.bennyhuo.kotlin.scheduledtask +import com.bennyhuo.kotlin.api.updateApi import io.reactivex.rxjava3.core.Observable import io.reactivex.rxjava3.disposables.Disposable import io.reactivex.rxjava3.schedulers.Schedulers diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/TimerUpdateTask.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/TimerUpdateTask.kt index 31aab65..d11ac87 100644 --- a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/TimerUpdateTask.kt +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/scheduledtask/TimerUpdateTask.kt @@ -1,5 +1,7 @@ package com.bennyhuo.kotlin.scheduledtask +import com.bennyhuo.kotlin.api.Config +import com.bennyhuo.kotlin.api.updateApi import retrofit2.Call import retrofit2.Callback import retrofit2.Response From 920008a41b151434503065dd437ea395c0bc9390 Mon Sep 17 00:00:00 2001 From: bennyhuo Date: Wed, 16 Jun 2021 08:05:55 +0800 Subject: [PATCH 36/60] callback to suspend/flow --- .../kotlin/coroutines/CallbackToCoroutines.kt | 210 ++++++++++++++++++ .../com/bennyhuo/kotlin/measuretime/Main.kt | 66 ++++++ 2 files changed, 276 insertions(+) create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutines/CallbackToCoroutines.kt create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/measuretime/Main.kt diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutines/CallbackToCoroutines.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutines/CallbackToCoroutines.kt new file mode 100644 index 0000000..93c839a --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutines/CallbackToCoroutines.kt @@ -0,0 +1,210 @@ +package com.bennyhuo.kotlin.coroutines + +import kotlinx.coroutines.* +import kotlinx.coroutines.channels.awaitClose +import kotlinx.coroutines.channels.trySendBlocking +import kotlinx.coroutines.flow.callbackFlow +import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.flow.conflate +import kotlin.concurrent.thread +import kotlin.coroutines.resume +import kotlin.coroutines.resumeWithException +import kotlin.coroutines.suspendCoroutine + +suspend fun main() { + println(runTaskSuspend()) + + try { + println(sendRequestSuspend()) + } catch (e: Exception) { + println("send request: $e") + } + + val scope = CoroutineScope(Dispatchers.Default) + scope.launch { + try { + println(sendRequestCancellableSuspend()) + } catch (e: Exception) { + println("send request cancellable: $e") + } + }.join() + + scope.launch { + startTaskAsFlow().collect { + when(it) { + OnComplete -> println("Done") + is OnError -> println("Error: ${it.t}") + is OnProgress -> println("Progress: ${it.value}") + is OnResult<*> -> println("Result: ${it.value}") + } + } + }.join() + +// delay(100) +// scope.cancel() +} + +//region single method +/** + * Delayed task, like handler.post + */ +fun interface SingleMethodCallback { + fun onCallback(value: String) +} + +fun runTask(callback: SingleMethodCallback) { + thread { + Thread.sleep(100) + callback.onCallback("runTask result") + } +} + +//region suspend +suspend fun runTaskSuspend() = suspendCoroutine { continuation -> + runTask { + continuation.resume(it) + } +} +//endregion +//endregion + +//region success or failure +/** + * Http request callback + * Dialog yes/no + */ +interface SuccessOrFailureCallback { + fun onSuccess(value: String) + + fun onError(t: Throwable) +} + +fun sendRequest(callback: SuccessOrFailureCallback) { + thread { + try { + Thread.sleep(100) + callback.onSuccess("Success") + } catch (e: Exception) { + callback.onError(e) + } + } +} + +//region suspend +suspend fun sendRequestSuspend() = suspendCoroutine { + continuation -> + sendRequest(object: SuccessOrFailureCallback { + override fun onSuccess(value: String) { + continuation.resume(value) + } + + override fun onError(t: Throwable) { + continuation.resumeWithException(t) + } + }) +} +//endregion + +fun interface Cancellable { + fun cancel() +} + +fun sendRequestCancellable(callback: SuccessOrFailureCallback):Cancellable { + val t = thread { + try { + Thread.sleep(1000) + callback.onSuccess("Success") + } catch (e: Exception) { + callback.onError(e) + } + } + return Cancellable { + t.interrupt() + } +} + +//region cancellable suspend +suspend fun sendRequestCancellableSuspend() = suspendCancellableCoroutine { + continuation -> + val cancellable = sendRequestCancellable(object: SuccessOrFailureCallback { + override fun onSuccess(value: String) { + continuation.resume(value) + } + + override fun onError(t: Throwable) { + continuation.resumeWithException(t) + } + }) + continuation.invokeOnCancellation { + cancellable.cancel() + } +} +//endregion +//endregion + +//region multi path +/** + * Download task callback + */ +interface MultiPathsCallback { + + fun onProgress(value: Int) + + fun onResult(value: T) + + fun onError(t: Throwable) + + fun onComplete() + +} + +fun startTask(callback: MultiPathsCallback): Cancellable { + val t = thread { + try { + (0..100).forEach { + Thread.sleep(10) + callback.onProgress(it) + } + callback.onResult("Done") + callback.onComplete() + } catch (e: Exception) { + callback.onError(e) + } + } + return Cancellable { + t.interrupt() + } +} + +//region suspend +sealed interface Event +class OnProgress(val value: Int): Event +class OnError(val t: Throwable): Event +class OnResult(val value: T): Event +object OnComplete: Event + +fun startTaskAsFlow() = callbackFlow { + val cancellable = startTask(object: MultiPathsCallback { + override fun onProgress(value: Int) { + trySendBlocking(OnProgress(value)) + } + + override fun onResult(value: String) { + trySendBlocking(OnResult(value)) + } + + override fun onError(t: Throwable) { + trySendBlocking(OnError(t)) + } + + override fun onComplete() { + trySendBlocking(OnComplete) + } + }) + + awaitClose { + cancellable.cancel() + } +}.conflate() +//endregion +//endregion \ No newline at end of file diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/measuretime/Main.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/measuretime/Main.kt new file mode 100644 index 0000000..58cf7e9 --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/measuretime/Main.kt @@ -0,0 +1,66 @@ +package com.bennyhuo.kotlin.measuretime + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch +import kotlin.concurrent.fixedRateTimer +import kotlin.time.* + + +inline fun timeCost(block: ()-> Unit): Long { + val startTime = System.currentTimeMillis() + block() + return System.currentTimeMillis() - startTime +} + +inline fun timeCostReturns(block: () -> T): Pair { + val startTime = System.currentTimeMillis() + val result = block() + return result to (System.currentTimeMillis() - startTime) +} + +@OptIn(ExperimentalTime::class) +suspend fun main() { + + val duration = measureTime { + Thread.sleep(100) + } + println(duration) + + val timeCost = timeCost { + Thread.sleep(100) + } + println(timeCost) + +// val (value, duration2) = measureTimedValue { +// Thread.sleep(500) +// +// 1000 +// } + + val (value, duration2) = timeCostReturns { + Thread.sleep(500) + + 1000 + } + + println(value) + println(duration2) + + val scope = CoroutineScope(Dispatchers.IO) + scope.launch { + + val duration = measureTime { + delay(1000) + } + println(duration) + + val mark = TimeSource.Monotonic.markNow() + delay(1000) + println(mark.elapsedNow()) + }.join() + + + +} \ No newline at end of file From b48ff2c87b3446d68d1378b1349a9ac6c990a631 Mon Sep 17 00:00:00 2001 From: Bennyhuo Date: Wed, 16 Jun 2021 10:02:07 +0800 Subject: [PATCH 37/60] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index a7fbbb6..467f0f7 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ Kotlin 的一些很零碎的内容,放到这个栏目下面。 - [x] [[Kotlin 杂谈] API 要谨慎使用?你可能需要 OptIn 注解!](https://www.bilibili.com/video/BV1Hh411a72d/) >>[示例代码](code\Kotlin-Sample\opt-in-sample) - [x] [[Kotlin 杂谈] 要废弃 API ?@Deprecated 你学废了吗?](https://www.bilibili.com/video/BV1Mb4y1d7nv/) >>[示例代码](code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/deprecated/DeprecatedSample.kt) - [x] [[Kotlin 协程 1.5] 越更越惨的 Channel:我 TM 就是个倒霉蛋](https://www.bilibili.com/video/BV1rb4y1d7wL/) >>[示例代码](code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/NewChannelApis.kt) +- [x] [[Kotlin 协程] 反向操作:怎么把挂起函数转成阻塞函数?](https://www.bilibili.com/video/BV17U4y157Ay/) ### [Gradle 迁移 KTS 系列视频 (2021.4 已完结)](https://github.com/bennyhuo/Kotlin-Tutorials/issues/25) From 096c0064ecf0860b4b090fe2a850d03cdd7f83dd Mon Sep 17 00:00:00 2001 From: bennyhuo Date: Wed, 16 Jun 2021 21:20:27 +0800 Subject: [PATCH 38/60] callback to suspend/flow --- .../java/com/bennyhuo/kotlin/coroutines/CallbackToCoroutines.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutines/CallbackToCoroutines.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutines/CallbackToCoroutines.kt index 93c839a..a695cb4 100644 --- a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutines/CallbackToCoroutines.kt +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutines/CallbackToCoroutines.kt @@ -199,9 +199,11 @@ fun startTaskAsFlow() = callbackFlow { override fun onComplete() { trySendBlocking(OnComplete) + close() } }) + awaitClose { cancellable.cancel() } From e6faf0bcd3e81489a840e8fb0e266ba026f5e10b Mon Sep 17 00:00:00 2001 From: bennyhuo Date: Sun, 20 Jun 2021 15:08:07 +0800 Subject: [PATCH 39/60] jvm record --- code/Kotlin-Sample/build.gradle.kts | 8 ++++- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../main/java/com/bennyhuo/kotlin/ide/Main.kt | 22 ++++++++++++++ .../java/com/bennyhuo/kotlin/ide/Sample.kt | 7 +++++ .../com/bennyhuo/kotlin/ide/SampleJava.java | 7 +++++ .../kotlin/update15/JavaRecordSample.java | 30 +++++++++++++++++++ .../kotlin/update15/JavaRecordSupport.kt | 15 ++++++++++ 7 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/ide/Main.kt create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/ide/Sample.kt create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/ide/SampleJava.java create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/JavaRecordSample.java create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/JavaRecordSupport.kt diff --git a/code/Kotlin-Sample/build.gradle.kts b/code/Kotlin-Sample/build.gradle.kts index 2628b05..60feb37 100644 --- a/code/Kotlin-Sample/build.gradle.kts +++ b/code/Kotlin-Sample/build.gradle.kts @@ -45,7 +45,13 @@ dependencies { val compileKotlin: KotlinCompile by tasks compileKotlin.kotlinOptions { - freeCompilerArgs = listOf("-Xopt-in=kotlin.RequiresOptIn") + freeCompilerArgs = listOf("-Xopt-in=kotlin.RequiresOptIn", "-Xextended-compiler-checks") + jvmTarget = "16" +} + +java { + targetCompatibility = JavaVersion.VERSION_16 + sourceCompatibility = JavaVersion.VERSION_16 } tasks.getByName("test") { diff --git a/code/Kotlin-Sample/gradle/wrapper/gradle-wrapper.properties b/code/Kotlin-Sample/gradle/wrapper/gradle-wrapper.properties index 8cf6eb5..1acc777 100644 --- a/code/Kotlin-Sample/gradle/wrapper/gradle-wrapper.properties +++ b/code/Kotlin-Sample/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.1-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/ide/Main.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/ide/Main.kt new file mode 100644 index 0000000..6cb0cf1 --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/ide/Main.kt @@ -0,0 +1,22 @@ +package com.bennyhuo.kotlin.ide + +interface Api { + val state: Int + + fun start() + + fun stop() +} + +class ApiImpl : Api { + override val state: Int + get() = 0 + + override fun start() { + } + + override fun stop() { + } + + +} \ No newline at end of file diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/ide/Sample.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/ide/Sample.kt new file mode 100644 index 0000000..f7fff2b --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/ide/Sample.kt @@ -0,0 +1,7 @@ +package com.bennyhuo.kotlin.ide + +/** + * Created by benny at 2021/6/16 21:58. + */ +class Sample { +} \ No newline at end of file diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/ide/SampleJava.java b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/ide/SampleJava.java new file mode 100644 index 0000000..bb14bbd --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/ide/SampleJava.java @@ -0,0 +1,7 @@ +package com.bennyhuo.kotlin.ide; + +/** + * Created by benny at 2021/6/16 21:59. + */ +public class SampleJava { +} diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/JavaRecordSample.java b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/JavaRecordSample.java new file mode 100644 index 0000000..2a5f056 --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/JavaRecordSample.java @@ -0,0 +1,30 @@ +package com.bennyhuo.kotlin.update15; + +/** + * Created by benny at 2021/6/18 8:06. + */ +public class JavaRecordSample { + + public record Person (String name, int age) { + + public Person { + if (name == null) throw new IllegalArgumentException("name should not be null."); + if (age < 0 || age > 100) throw new IllegalArgumentException(""); + count++; + } + + public static int count = 0; + + public static int count() { + return count; + } + + } + + public static void main(String[] args) { + var person = new Person("bennyhuo", 2); + System.out.println(person); + //var ktPerson = new KotlinPerson("bennyhuo", 10); + } + +} diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/JavaRecordSupport.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/JavaRecordSupport.kt new file mode 100644 index 0000000..0189aac --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/JavaRecordSupport.kt @@ -0,0 +1,15 @@ +package com.bennyhuo.kotlin.update15 + +/** + * Created by benny at 2021/6/20 9:35. + */ +open class Super +@JvmRecord +data class KotlinPerson(val name: String, val age: Int) { + +} + +fun main() { + val person = JavaRecordSample.Person("bennyhuo", 1) + +} \ No newline at end of file From 5c873271e00efed8fa79b639d84b4690548bdcce Mon Sep 17 00:00:00 2001 From: bennyhuo Date: Sat, 26 Jun 2021 09:51:15 +0800 Subject: [PATCH 40/60] add js sample --- .../kotlin-js-sample/build.gradle.kts | 18 ++++++++++++++++++ .../main/kotlin/com/bennyhuo/kotlin/js/Main.kt | 14 ++++++++++++++ code/Kotlin-Sample/settings.gradle.kts | 1 + 3 files changed, 33 insertions(+) create mode 100644 code/Kotlin-Sample/kotlin-js-sample/build.gradle.kts create mode 100644 code/Kotlin-Sample/kotlin-js-sample/src/main/kotlin/com/bennyhuo/kotlin/js/Main.kt diff --git a/code/Kotlin-Sample/kotlin-js-sample/build.gradle.kts b/code/Kotlin-Sample/kotlin-js-sample/build.gradle.kts new file mode 100644 index 0000000..a512484 --- /dev/null +++ b/code/Kotlin-Sample/kotlin-js-sample/build.gradle.kts @@ -0,0 +1,18 @@ +plugins { + id("org.jetbrains.kotlin.js") +} + +group = "com.bennyhuo.kotlin.hello" +version = "1.0-SNAPSHOT" + +dependencies { + implementation(kotlin("stdlib-js")) +} + +kotlin { + js(IR) { + nodejs { + } + binaries.executable() + } +} \ No newline at end of file diff --git a/code/Kotlin-Sample/kotlin-js-sample/src/main/kotlin/com/bennyhuo/kotlin/js/Main.kt b/code/Kotlin-Sample/kotlin-js-sample/src/main/kotlin/com/bennyhuo/kotlin/js/Main.kt new file mode 100644 index 0000000..68d89f6 --- /dev/null +++ b/code/Kotlin-Sample/kotlin-js-sample/src/main/kotlin/com/bennyhuo/kotlin/js/Main.kt @@ -0,0 +1,14 @@ +package com.bennyhuo.kotlin.js + +/** + * Created by benny at 2021/6/26 8:36. + */ +fun main() { + console.log("Hello Js") + + val duration = Duration(10) + println(duration) +} + +inline class Span(val value: Long) +value class Duration(val value: Long) \ No newline at end of file diff --git a/code/Kotlin-Sample/settings.gradle.kts b/code/Kotlin-Sample/settings.gradle.kts index d3e81ad..811fbc4 100644 --- a/code/Kotlin-Sample/settings.gradle.kts +++ b/code/Kotlin-Sample/settings.gradle.kts @@ -2,3 +2,4 @@ rootProject.name = "Kotlin-Sample" include(":opt-in-sample",":deprecated-sample") include(":kotlin-android-sample") +include("kotlin-js-sample") From 12e7003d87082782426579bb4091644ff997960e Mon Sep 17 00:00:00 2001 From: bennyhuo Date: Sat, 26 Jun 2021 20:45:46 +0800 Subject: [PATCH 41/60] sealed interface --- code/Kotlin-Sample/build.gradle.kts | 5 +++ .../{ => jvmrecord}/JavaRecordSample.java | 2 +- .../{ => jvmrecord}/JavaRecordSupport.kt | 2 +- .../sealedinterfaces/javasealed/Cons.java | 7 ++++ .../sealedinterfaces/javasealed/List.java | 8 +++++ .../sealedinterfaces/javasealed/Nil.java | 7 ++++ .../sealedinterfaces/since1_0/List.kt | 32 +++++++++++++++++++ .../sealedinterfaces/since1_1/List.kt | 31 ++++++++++++++++++ .../since1_5/samepackage/Cons.kt | 3 ++ .../since1_5/samepackage/List.kt | 3 ++ .../since1_5/samepackage/Main.kt | 28 ++++++++++++++++ .../since1_5/samepackage/Nil.kt | 3 ++ .../since1_5/samepackage/X.java | 7 ++++ .../since1_5/useinterface/List.kt | 30 +++++++++++++++++ 14 files changed, 166 insertions(+), 2 deletions(-) rename code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/{ => jvmrecord}/JavaRecordSample.java (93%) rename code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/{ => jvmrecord}/JavaRecordSupport.kt (81%) create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedinterfaces/javasealed/Cons.java create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedinterfaces/javasealed/List.java create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedinterfaces/javasealed/Nil.java create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedinterfaces/since1_0/List.kt create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedinterfaces/since1_1/List.kt create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedinterfaces/since1_5/samepackage/Cons.kt create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedinterfaces/since1_5/samepackage/List.kt create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedinterfaces/since1_5/samepackage/Main.kt create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedinterfaces/since1_5/samepackage/Nil.kt create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedinterfaces/since1_5/samepackage/X.java create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedinterfaces/since1_5/useinterface/List.kt diff --git a/code/Kotlin-Sample/build.gradle.kts b/code/Kotlin-Sample/build.gradle.kts index 60feb37..e3a1398 100644 --- a/code/Kotlin-Sample/build.gradle.kts +++ b/code/Kotlin-Sample/build.gradle.kts @@ -1,3 +1,4 @@ +import org.gradle.model.internal.core.ModelNodes.withType import org.jetbrains.kotlin.gradle.tasks.KotlinCompile buildscript { @@ -54,6 +55,10 @@ java { sourceCompatibility = JavaVersion.VERSION_16 } +tasks.withType().forEach { + it.options.compilerArgs.add("--enable-preview") +} + tasks.getByName("test") { useJUnitPlatform() } \ No newline at end of file diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/JavaRecordSample.java b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/jvmrecord/JavaRecordSample.java similarity index 93% rename from code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/JavaRecordSample.java rename to code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/jvmrecord/JavaRecordSample.java index 2a5f056..e5ecffe 100644 --- a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/JavaRecordSample.java +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/jvmrecord/JavaRecordSample.java @@ -1,4 +1,4 @@ -package com.bennyhuo.kotlin.update15; +package com.bennyhuo.kotlin.update15.jvmrecord; /** * Created by benny at 2021/6/18 8:06. diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/JavaRecordSupport.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/jvmrecord/JavaRecordSupport.kt similarity index 81% rename from code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/JavaRecordSupport.kt rename to code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/jvmrecord/JavaRecordSupport.kt index 0189aac..3cd27be 100644 --- a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/JavaRecordSupport.kt +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/jvmrecord/JavaRecordSupport.kt @@ -1,4 +1,4 @@ -package com.bennyhuo.kotlin.update15 +package com.bennyhuo.kotlin.update15.jvmrecord /** * Created by benny at 2021/6/20 9:35. diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedinterfaces/javasealed/Cons.java b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedinterfaces/javasealed/Cons.java new file mode 100644 index 0000000..8ff2dc5 --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedinterfaces/javasealed/Cons.java @@ -0,0 +1,7 @@ +package com.bennyhuo.kotlin.update15.sealedinterfaces.javasealed; + +/** + * Created by benny. + */ +public final class Cons implements List{ +} diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedinterfaces/javasealed/List.java b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedinterfaces/javasealed/List.java new file mode 100644 index 0000000..253f724 --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedinterfaces/javasealed/List.java @@ -0,0 +1,8 @@ +package com.bennyhuo.kotlin.update15.sealedinterfaces.javasealed; + +/** + * Created by benny. + */ +public sealed interface List permits Nil, Cons { + +} diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedinterfaces/javasealed/Nil.java b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedinterfaces/javasealed/Nil.java new file mode 100644 index 0000000..dd64d22 --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedinterfaces/javasealed/Nil.java @@ -0,0 +1,7 @@ +package com.bennyhuo.kotlin.update15.sealedinterfaces.javasealed; + +/** + * Created by benny. + */ +public final class Nil implements List { +} diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedinterfaces/since1_0/List.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedinterfaces/since1_0/List.kt new file mode 100644 index 0000000..35da11d --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedinterfaces/since1_0/List.kt @@ -0,0 +1,32 @@ +package com.bennyhuo.kotlin.update15.sealedinterfaces.since1_0 + +/** + * Created by benny. + * For Kotlin 1.0 and before. + */ +sealed class List { + object Nil: List() + class Cons(val value: T, val next: List): List() +} + +tailrec fun List.forEach(block: (T) -> Unit) { + when(this) { + List.Nil -> return + is List.Cons -> { + block(value) + next.forEach(block) + } + } +} + +fun listOf(vararg values: T): List { + return values.reversedArray().fold(List.Nil as List) { acc, t -> + List.Cons(t, acc) + } +} + +fun main() { + listOf(1,2,3,4).forEach { + println(it) + } +} \ No newline at end of file diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedinterfaces/since1_1/List.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedinterfaces/since1_1/List.kt new file mode 100644 index 0000000..c51c370 --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedinterfaces/since1_1/List.kt @@ -0,0 +1,31 @@ +package com.bennyhuo.kotlin.update15.sealedinterfaces.since1_1 + +/** + * Created by benny. + * For Kotlin 1.1 to 1.4. + */ +sealed class List +object Nil: List() +class Cons(val value: T, val next: List): List() + +tailrec fun List.forEach(block: (T) -> Unit) { + when(this) { + Nil -> return + is Cons -> { + block(value) + next.forEach(block) + } + } +} + +fun listOf(vararg values: T): List { + return values.reversedArray().fold(Nil as List) { acc, t -> + Cons(t, acc) + } +} + +fun main() { + listOf(1,2,3,4).forEach { + println(it) + } +} \ No newline at end of file diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedinterfaces/since1_5/samepackage/Cons.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedinterfaces/since1_5/samepackage/Cons.kt new file mode 100644 index 0000000..7a0ce55 --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedinterfaces/since1_5/samepackage/Cons.kt @@ -0,0 +1,3 @@ +package com.bennyhuo.kotlin.update15.sealedinterfaces.since1_5.samepackage + +class Cons(val value: T, val next: List): List diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedinterfaces/since1_5/samepackage/List.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedinterfaces/since1_5/samepackage/List.kt new file mode 100644 index 0000000..45b835d --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedinterfaces/since1_5/samepackage/List.kt @@ -0,0 +1,3 @@ +package com.bennyhuo.kotlin.update15.sealedinterfaces.since1_5.samepackage + +sealed interface List \ No newline at end of file diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedinterfaces/since1_5/samepackage/Main.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedinterfaces/since1_5/samepackage/Main.kt new file mode 100644 index 0000000..b2049b5 --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedinterfaces/since1_5/samepackage/Main.kt @@ -0,0 +1,28 @@ +package com.bennyhuo.kotlin.update15.sealedinterfaces.since1_5.samepackage + +/** + * Created by benny. + */ + + +tailrec fun List.forEach(block: (T) -> Unit) { + when(this) { + Nil -> return + is Cons -> { + block(value) + next.forEach(block) + } + } +} + +fun listOf(vararg values: T): List { + return values.reversedArray().fold(Nil as List) { acc, t -> + Cons(t, acc) + } +} + +fun main() { + listOf(1,2,3,4).forEach { + println(it) + } +} \ No newline at end of file diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedinterfaces/since1_5/samepackage/Nil.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedinterfaces/since1_5/samepackage/Nil.kt new file mode 100644 index 0000000..8bc4d5b --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedinterfaces/since1_5/samepackage/Nil.kt @@ -0,0 +1,3 @@ +package com.bennyhuo.kotlin.update15.sealedinterfaces.since1_5.samepackage + +object Nil: List diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedinterfaces/since1_5/samepackage/X.java b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedinterfaces/since1_5/samepackage/X.java new file mode 100644 index 0000000..dc6c298 --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedinterfaces/since1_5/samepackage/X.java @@ -0,0 +1,7 @@ +package com.bennyhuo.kotlin.update15.sealedinterfaces.since1_5.samepackage; + +/** + * Created by benny. + */ +//public class X implements List { +//} diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedinterfaces/since1_5/useinterface/List.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedinterfaces/since1_5/useinterface/List.kt new file mode 100644 index 0000000..fc2b0e0 --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedinterfaces/since1_5/useinterface/List.kt @@ -0,0 +1,30 @@ +package com.bennyhuo.kotlin.update15.sealedinterfaces.since1_5.useinterface + +/** + * Created by benny. + */ +sealed interface List +object Nil: List +class Cons(val value: T, val next: List): List + +tailrec fun List.forEach(block: (T) -> Unit) { + when(this) { + Nil -> return + is Cons -> { + block(value) + next.forEach(block) + } + } +} + +fun listOf(vararg values: T): List { + return values.reversedArray().fold(Nil as List) { acc, t -> + Cons(t, acc) + } +} + +fun main() { + listOf(1,2,3,4).forEach { + println(it) + } +} \ No newline at end of file From a302cb783d141ad7075ba8dc23b7eb9a3ba34056 Mon Sep 17 00:00:00 2001 From: Bennyhuo Date: Sun, 27 Jun 2021 14:23:47 +0800 Subject: [PATCH 42/60] Update README.md --- README.md | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 467f0f7..3bb4598 100644 --- a/README.md +++ b/README.md @@ -23,17 +23,30 @@ ## 视频清单 +### Kotlin 1.5 相关更新 + +Kotlin 1.5 于 2021年5月份发布,主要更新内容其实集中在编译器和工具链上,所以开发者可感知的特性并不多 —— 大概要等 IR 编译器前端稳定了之后才会集中输出一波语法特性的大改动,等吧,那时候大概就是 Kotlin 2.0 了。 + +- [x] [[Kotlin 1.5] Duration:这玩意也能实验这么久?!](https://www.bilibili.com/video/BV1Uh411a7SS/) +- [x] [[Kotlin 1.5] 支持 JvmRecord:Java 开始抄作业了?](https://www.bilibili.com/video/BV1K54y1H7NL/) +- [x] [[Kotlin 1.5] Kotlin 反手一个密封接口?谁抄谁还不一定呢!](https://www.bilibili.com/video/BV1Mw411o7sK/) +- [x] [[Kotlin 1.5] inline(×) value(√) class:换个马甲还是另有所图?](https://www.bilibili.com/video/BV1k54y1H7NT/) 待发布 + +- [x] [[Kotlin 协程 1.5] 什么?GlobalScope 竟被废弃了?](https://www.bilibili.com/video/BV1P64y1C7bF/) >>[示例代码](https://github.com/bennyhuo/Kotlin-Tutorials/blob/master/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/DelicateGlobalScope.kt) +- [x] [[Kotlin 协程 1.5] 越更越惨的 Channel:我 TM 就是个倒霉蛋](https://www.bilibili.com/video/BV1rb4y1d7wL/) >>[示例代码](code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/NewChannelApis.kt) +- [x] [[Kotlin 协程 1.5] Flow 有两个 API 转正:一个是另一个的马甲?](https://www.bilibili.com/video/BV1vg411g7X4/) +- [x] [[Kotlin 协程] 反向操作:怎么把挂起函数转成阻塞函数?](https://www.bilibili.com/video/BV17U4y157Ay/) +- [x] [[Kotlin 协程] 常规操作:怎么把回调转成挂起函数?](https://www.bilibili.com/video/BV13y4y1g7g3/) + + ### [Kotlin 杂谈 (持续更新中)](https://github.com/bennyhuo/Kotlin-Tutorials/issues/35) Kotlin 的一些很零碎的内容,放到这个栏目下面。 - [x] [[Kotlin 杂谈] SAM 转换遇到包内可见](https://www.bilibili.com/video/BV1wB4y1g79W/) >>[示例代码](code\Kotlin-Sample\src\main\java\com\bennyhuo\kotlin\samissue) - [x] [[Kotlin 杂谈] 使用协程实现轮询任务竟是这么简单](https://www.bilibili.com/video/BV11b4y1Z7sz/) >>[示例代码](code\Kotlin-Sample\src\main\java\com\bennyhuo\kotlin\scheduledtask) -- [x] [[Kotlin 协程 1.5] 什么?GlobalScope 竟被废弃了?](https://www.bilibili.com/video/BV1P64y1C7bF/) >>[示例代码](https://github.com/bennyhuo/Kotlin-Tutorials/blob/master/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/DelicateGlobalScope.kt) - [x] [[Kotlin 杂谈] API 要谨慎使用?你可能需要 OptIn 注解!](https://www.bilibili.com/video/BV1Hh411a72d/) >>[示例代码](code\Kotlin-Sample\opt-in-sample) - [x] [[Kotlin 杂谈] 要废弃 API ?@Deprecated 你学废了吗?](https://www.bilibili.com/video/BV1Mb4y1d7nv/) >>[示例代码](code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/deprecated/DeprecatedSample.kt) -- [x] [[Kotlin 协程 1.5] 越更越惨的 Channel:我 TM 就是个倒霉蛋](https://www.bilibili.com/video/BV1rb4y1d7wL/) >>[示例代码](code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/NewChannelApis.kt) -- [x] [[Kotlin 协程] 反向操作:怎么把挂起函数转成阻塞函数?](https://www.bilibili.com/video/BV17U4y157Ay/) ### [Gradle 迁移 KTS 系列视频 (2021.4 已完结)](https://github.com/bennyhuo/Kotlin-Tutorials/issues/25) From fd7358173001ba21274557f240389d1a99ede77d Mon Sep 17 00:00:00 2001 From: Bennyhuo Date: Sun, 27 Jun 2021 14:24:58 +0800 Subject: [PATCH 43/60] Update README.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 3bb4598..66a046d 100644 --- a/README.md +++ b/README.md @@ -27,11 +27,17 @@ Kotlin 1.5 于 2021年5月份发布,主要更新内容其实集中在编译器和工具链上,所以开发者可感知的特性并不多 —— 大概要等 IR 编译器前端稳定了之后才会集中输出一波语法特性的大改动,等吧,那时候大概就是 Kotlin 2.0 了。 +**Kotlin 语言特性和标准库** + - [x] [[Kotlin 1.5] Duration:这玩意也能实验这么久?!](https://www.bilibili.com/video/BV1Uh411a7SS/) - [x] [[Kotlin 1.5] 支持 JvmRecord:Java 开始抄作业了?](https://www.bilibili.com/video/BV1K54y1H7NL/) - [x] [[Kotlin 1.5] Kotlin 反手一个密封接口?谁抄谁还不一定呢!](https://www.bilibili.com/video/BV1Mw411o7sK/) - [x] [[Kotlin 1.5] inline(×) value(√) class:换个马甲还是另有所图?](https://www.bilibili.com/video/BV1k54y1H7NT/) 待发布 +------ + +**Kotlin 协程** + - [x] [[Kotlin 协程 1.5] 什么?GlobalScope 竟被废弃了?](https://www.bilibili.com/video/BV1P64y1C7bF/) >>[示例代码](https://github.com/bennyhuo/Kotlin-Tutorials/blob/master/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/DelicateGlobalScope.kt) - [x] [[Kotlin 协程 1.5] 越更越惨的 Channel:我 TM 就是个倒霉蛋](https://www.bilibili.com/video/BV1rb4y1d7wL/) >>[示例代码](code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/NewChannelApis.kt) - [x] [[Kotlin 协程 1.5] Flow 有两个 API 转正:一个是另一个的马甲?](https://www.bilibili.com/video/BV1vg411g7X4/) From 2289d02a397463a26d391aae1b88606e9a91f1fa Mon Sep 17 00:00:00 2001 From: Bennyhuo Date: Thu, 1 Jul 2021 09:54:37 +0800 Subject: [PATCH 44/60] Update README.md --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 66a046d..5347d2c 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,8 @@ Kotlin 1.5 于 2021年5月份发布,主要更新内容其实集中在编译器 - [x] [[Kotlin 1.5] Duration:这玩意也能实验这么久?!](https://www.bilibili.com/video/BV1Uh411a7SS/) - [x] [[Kotlin 1.5] 支持 JvmRecord:Java 开始抄作业了?](https://www.bilibili.com/video/BV1K54y1H7NL/) - [x] [[Kotlin 1.5] Kotlin 反手一个密封接口?谁抄谁还不一定呢!](https://www.bilibili.com/video/BV1Mw411o7sK/) -- [x] [[Kotlin 1.5] inline(×) value(√) class:换个马甲还是另有所图?](https://www.bilibili.com/video/BV1k54y1H7NT/) 待发布 +- [x] [[Kotlin 1.5] inline(×) value(√) class:换个马甲还是另有所图?](https://www.bilibili.com/video/BV1k54y1H7NT/) +- [ ] [[编程语言引战] 辣鸡 Java,看看人家 C# 的值类型!](https://www.bilibili.com/video/BV15w411o7jq/) 这期视频主要是 Kotlin value class 话题的一个延伸,所以放到这里 ------ @@ -54,6 +55,12 @@ Kotlin 的一些很零碎的内容,放到这个栏目下面。 - [x] [[Kotlin 杂谈] API 要谨慎使用?你可能需要 OptIn 注解!](https://www.bilibili.com/video/BV1Hh411a72d/) >>[示例代码](code\Kotlin-Sample\opt-in-sample) - [x] [[Kotlin 杂谈] 要废弃 API ?@Deprecated 你学废了吗?](https://www.bilibili.com/video/BV1Mb4y1d7nv/) >>[示例代码](code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/deprecated/DeprecatedSample.kt) +### [工具和技巧](https://github.com/bennyhuo/Kotlin-Tutorials/issues/28) + +- [x] [[一周一个小技巧] 查看字节码,你们都用什么工具?](https://www.bilibili.com/video/BV1jv411H7pX/) +- [x] [httpreq 介绍](https://www.bilibili.com/video/BV1bv41157xH/),该工具可以方便地对接口进行测试 https://httpreq.com/ 制作中 +- [x] [Pipedream 介绍](https://www.bilibili.com/video/BV13h411v7Fr/),该工具实现更复杂的接口调试场景,可以自定义请求结果,还可以把请求数据存起来。 +- [x] [Android Studio 技巧之快捷键](https://www.bilibili.com/video/BV1g64y1279B/) ### [Gradle 迁移 KTS 系列视频 (2021.4 已完结)](https://github.com/bennyhuo/Kotlin-Tutorials/issues/25) From 420e82aec306d64b80e24a8a9d82dd65e2e515e2 Mon Sep 17 00:00:00 2001 From: bennyhuo Date: Sun, 11 Jul 2021 14:05:36 +0800 Subject: [PATCH 45/60] back ticks --- .../Kotlin-mpp-sample/build.gradle.kts | 39 +++++++++++++++++ .../kotlin/com/bennyhuo/kotlin/sample/Main.kt | 24 +++++++++++ code/Kotlin-Sample/build.gradle.kts | 5 +++ .../kclass-issue/build.gradle.kts | 18 ++++++++ .../com/bennyhuo/kotlin/kclassvalue/Main.kt | 38 +++++++++++++++++ .../kotlin-js-sample/build.gradle.kts | 12 ++++-- .../kotlin/com/bennyhuo/kotlin/js/Main.kt | 42 +++++++++++++++++++ .../kotlin/js/deepcopy/TestDeepCopy.kt | 22 ++++++++++ .../kotlin/js/kclassvalue/KClassIssue.kt | 17 ++++++++ code/Kotlin-Sample/settings.gradle.kts | 2 + .../com/bennyhuo/kotlin/basics/BackTicks.kt | 31 ++++++++++++++ .../com/bennyhuo/kotlin/basics/History.java | 23 ++++++++++ .../java/com/bennyhuo/kotlin/basics/Main.java | 12 ++++++ .../kotlin/update15/valueclass/ValueClass.kt | 10 +++++ 14 files changed, 292 insertions(+), 3 deletions(-) create mode 100644 code/Kotlin-Sample/Kotlin-mpp-sample/build.gradle.kts create mode 100644 code/Kotlin-Sample/Kotlin-mpp-sample/src/mingwX64Main/kotlin/com/bennyhuo/kotlin/sample/Main.kt create mode 100644 code/Kotlin-Sample/kclass-issue/build.gradle.kts create mode 100644 code/Kotlin-Sample/kclass-issue/src/main/java/com/bennyhuo/kotlin/kclassvalue/Main.kt create mode 100644 code/Kotlin-Sample/kotlin-js-sample/src/main/kotlin/com/bennyhuo/kotlin/js/deepcopy/TestDeepCopy.kt create mode 100644 code/Kotlin-Sample/kotlin-js-sample/src/main/kotlin/com/bennyhuo/kotlin/js/kclassvalue/KClassIssue.kt create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/basics/BackTicks.kt create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/basics/History.java create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/basics/Main.java create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/valueclass/ValueClass.kt diff --git a/code/Kotlin-Sample/Kotlin-mpp-sample/build.gradle.kts b/code/Kotlin-Sample/Kotlin-mpp-sample/build.gradle.kts new file mode 100644 index 0000000..0ce2de7 --- /dev/null +++ b/code/Kotlin-Sample/Kotlin-mpp-sample/build.gradle.kts @@ -0,0 +1,39 @@ +plugins { + kotlin("multiplatform") +} + +group = "com.bennyhuo.kotlin.hello" +version = "1.0-SNAPSHOT" + +kotlin { + /* Targets configuration omitted. + * To find out how to configure the targets, please follow the link: + * https://kotlinlang.org/docs/reference/building-mpp-with-gradle.html#setting-up-targets */ + + sourceSets { + val commonMain by getting { + dependencies { + implementation(kotlin("stdlib-common")) + } + } + val commonTest by getting { + dependencies { + implementation(kotlin("test-common")) + implementation(kotlin("test-annotations-common")) + } + } + + jvm() + js{ + nodejs() + } + mingwX64 { + binaries { + executable { + // Binary configuration. + entryPoint = "com.bennyhuo.kotlin.sample.main" + } + } + } + } +} \ No newline at end of file diff --git a/code/Kotlin-Sample/Kotlin-mpp-sample/src/mingwX64Main/kotlin/com/bennyhuo/kotlin/sample/Main.kt b/code/Kotlin-Sample/Kotlin-mpp-sample/src/mingwX64Main/kotlin/com/bennyhuo/kotlin/sample/Main.kt new file mode 100644 index 0000000..c60dc56 --- /dev/null +++ b/code/Kotlin-Sample/Kotlin-mpp-sample/src/mingwX64Main/kotlin/com/bennyhuo/kotlin/sample/Main.kt @@ -0,0 +1,24 @@ +package com.bennyhuo.kotlin.sample + +/** + * Created by benny. + */ + +interface DeepCopyable + +data class District(var name: String) + +data class Location(var lat: Double, var lng: Double) + +data class Company(var name: String, var location: Location, var district: District): DeepCopyable + +data class Speaker(var name: String, var age: Int, var company: Company): DeepCopyable + +data class Talk(var name: String, var speaker: Speaker): DeepCopyable + + +fun main() { + println("Hello") + + val district = District("x") +} \ No newline at end of file diff --git a/code/Kotlin-Sample/build.gradle.kts b/code/Kotlin-Sample/build.gradle.kts index e3a1398..eca181b 100644 --- a/code/Kotlin-Sample/build.gradle.kts +++ b/code/Kotlin-Sample/build.gradle.kts @@ -28,9 +28,13 @@ allprojects { dependencies { implementation(kotlin("stdlib")) + implementation(kotlin("reflect")) + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.5.0") + implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.2.1") + implementation("com.squareup.retrofit2:retrofit:2.9.0") implementation("com.squareup.retrofit2:adapter-rxjava3:2.9.0") implementation("com.squareup.retrofit2:converter-gson:2.9.0") @@ -48,6 +52,7 @@ val compileKotlin: KotlinCompile by tasks compileKotlin.kotlinOptions { freeCompilerArgs = listOf("-Xopt-in=kotlin.RequiresOptIn", "-Xextended-compiler-checks") jvmTarget = "16" + useIR = true } java { diff --git a/code/Kotlin-Sample/kclass-issue/build.gradle.kts b/code/Kotlin-Sample/kclass-issue/build.gradle.kts new file mode 100644 index 0000000..4bf1f04 --- /dev/null +++ b/code/Kotlin-Sample/kclass-issue/build.gradle.kts @@ -0,0 +1,18 @@ +plugins { + java + kotlin("jvm") +} + +group = "com.bennyhuo.kotlin.hello" +version = "1.0-SNAPSHOT" + +dependencies { + implementation(kotlin("stdlib")) + implementation(kotlin("reflect")) + testImplementation("org.junit.jupiter:junit-jupiter-api:5.6.0") + testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine") +} + +tasks.getByName("test") { + useJUnitPlatform() +} \ No newline at end of file diff --git a/code/Kotlin-Sample/kclass-issue/src/main/java/com/bennyhuo/kotlin/kclassvalue/Main.kt b/code/Kotlin-Sample/kclass-issue/src/main/java/com/bennyhuo/kotlin/kclassvalue/Main.kt new file mode 100644 index 0000000..7a58b3b --- /dev/null +++ b/code/Kotlin-Sample/kclass-issue/src/main/java/com/bennyhuo/kotlin/kclassvalue/Main.kt @@ -0,0 +1,38 @@ +package com.bennyhuo.kotlin.kclassvalue + +import kotlin.concurrent.thread + +/** + * Created by benny. + */ +fun main() { +// val anyClass = Any::class +// val anyClass2 = Any::class +// println(anyClass == anyClass2) +// println(anyClass === anyClass2) + + testConcurrentIssue() +} + +//region concurrent issue. +var concurrentValue = 0 + +fun safeIncrement() { + synchronized(Any::class) { + concurrentValue++ + } +} + +fun testConcurrentIssue() { + List(100) { + thread(start = false) { + for (i in 0 until 1000) { + safeIncrement() + } + } + }.onEach(Thread::start) + .forEach(Thread::join) + + println(concurrentValue) +} +//endregion \ No newline at end of file diff --git a/code/Kotlin-Sample/kotlin-js-sample/build.gradle.kts b/code/Kotlin-Sample/kotlin-js-sample/build.gradle.kts index a512484..4c612e4 100644 --- a/code/Kotlin-Sample/kotlin-js-sample/build.gradle.kts +++ b/code/Kotlin-Sample/kotlin-js-sample/build.gradle.kts @@ -10,9 +10,15 @@ dependencies { } kotlin { - js(IR) { - nodejs { - } +// js(IR) { +// moduleName = "kotlin-js-ir" +// binaries.executable() +// nodejs() +// } + + js { + moduleName = "kotlin-js-legacy" binaries.executable() + nodejs() } } \ No newline at end of file diff --git a/code/Kotlin-Sample/kotlin-js-sample/src/main/kotlin/com/bennyhuo/kotlin/js/Main.kt b/code/Kotlin-Sample/kotlin-js-sample/src/main/kotlin/com/bennyhuo/kotlin/js/Main.kt index 68d89f6..1ac2f52 100644 --- a/code/Kotlin-Sample/kotlin-js-sample/src/main/kotlin/com/bennyhuo/kotlin/js/Main.kt +++ b/code/Kotlin-Sample/kotlin-js-sample/src/main/kotlin/com/bennyhuo/kotlin/js/Main.kt @@ -1,5 +1,9 @@ package com.bennyhuo.kotlin.js +import com.bennyhuo.kotlin.js.deepcopy.DeepCopyable +import com.bennyhuo.kotlin.js.deepcopy.deepCopy +import com.bennyhuo.kotlin.js.kclassvalue.testKClass + /** * Created by benny at 2021/6/26 8:36. */ @@ -8,7 +12,45 @@ fun main() { val duration = Duration(10) println(duration) + + testKClass() + + val talk = Talk( + "如何优雅地使用数据类", + Speaker( + "bennyhuo 不是算命的", + 1, + Company( + "猿辅导", + Location(39.9, 116.3), + District("北京郊区") + ) + ) + ) + + val copiedTalk = talk.deepCopy() +// copiedTalk.name = "Kotlin 编译器插件:我们不期待" +// copiedTalk.speaker.company = Company( +// "猿辅导", +// Location(39.9, 116.3), +// District("华鼎世家对面") +// ) + + println(talk.speaker !== copiedTalk.speaker) + println(talk.speaker.company !== copiedTalk.speaker.company) + println(talk.speaker.company.location === copiedTalk.speaker.company.location) } +data class District(var name: String) + +data class Location(var lat: Double, var lng: Double) + +data class Company(var name: String, var location: Location, var district: District): DeepCopyable + +data class Speaker(var name: String, var age: Int, var company: Company): DeepCopyable + +data class Talk(var name: String, var speaker: Speaker): DeepCopyable + + inline class Span(val value: Long) value class Duration(val value: Long) \ No newline at end of file diff --git a/code/Kotlin-Sample/kotlin-js-sample/src/main/kotlin/com/bennyhuo/kotlin/js/deepcopy/TestDeepCopy.kt b/code/Kotlin-Sample/kotlin-js-sample/src/main/kotlin/com/bennyhuo/kotlin/js/deepcopy/TestDeepCopy.kt new file mode 100644 index 0000000..153db4b --- /dev/null +++ b/code/Kotlin-Sample/kotlin-js-sample/src/main/kotlin/com/bennyhuo/kotlin/js/deepcopy/TestDeepCopy.kt @@ -0,0 +1,22 @@ +package com.bennyhuo.kotlin.js.deepcopy + +/** + * Created by benny. + */ +interface DeepCopyable + +fun T.deepCopy(): T { + val constructor = this::class.js.asDynamic() + val newInstance = js("{}") + newInstance.__proto__ = constructor.prototype + val parameters = (1..Int.MAX_VALUE).takeWhile { + constructor.prototype["component$it"] !== undefined + }.map { + constructor.prototype["component$it"].call(this).unsafeCast() + .let { + (it as? DeepCopyable)?.deepCopy() ?: it + } + }.toTypedArray() + constructor.apply(newInstance, parameters) + return newInstance as T +} \ No newline at end of file diff --git a/code/Kotlin-Sample/kotlin-js-sample/src/main/kotlin/com/bennyhuo/kotlin/js/kclassvalue/KClassIssue.kt b/code/Kotlin-Sample/kotlin-js-sample/src/main/kotlin/com/bennyhuo/kotlin/js/kclassvalue/KClassIssue.kt new file mode 100644 index 0000000..f84567e --- /dev/null +++ b/code/Kotlin-Sample/kotlin-js-sample/src/main/kotlin/com/bennyhuo/kotlin/js/kclassvalue/KClassIssue.kt @@ -0,0 +1,17 @@ +package com.bennyhuo.kotlin.js.kclassvalue + +/** + * Created by benny. + */ +fun testKClass() { + val anyClass = Any::class + val anyClass2 = Any::class + + println(anyClass === anyClass2) + + val personClass = Person::class + val personClass2 = Person::class + println(personClass === personClass2) +} + +class Person \ No newline at end of file diff --git a/code/Kotlin-Sample/settings.gradle.kts b/code/Kotlin-Sample/settings.gradle.kts index 811fbc4..5dc3e5e 100644 --- a/code/Kotlin-Sample/settings.gradle.kts +++ b/code/Kotlin-Sample/settings.gradle.kts @@ -3,3 +3,5 @@ rootProject.name = "Kotlin-Sample" include(":opt-in-sample",":deprecated-sample") include(":kotlin-android-sample") include("kotlin-js-sample") +include("kclass-issue") +include("Kotlin-mpp-sample") diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/basics/BackTicks.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/basics/BackTicks.kt new file mode 100644 index 0000000..726dc71 --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/basics/BackTicks.kt @@ -0,0 +1,31 @@ +package com.bennyhuo.kotlin.basics + +import kotlinx.datetime.toInstant + +/** + * Created by benny. + */ +fun main() { + val result = 2 `**` 3 + println(result) + val history = History("2016-02-19T00:00:00.000Z".toInstant().toEpochMilliseconds(), "Kotlin 1.0 release!") + println(history.`when`()) +} + +fun `fun`() { + +} + +@JvmName("classInJava") +fun `class`() { + +} + +@JvmName("This_is_a_test") +fun `This is a test`() { + +} + +infix fun Number.`**`(power: Number): Double { + return Math.pow(this.toDouble(), power.toDouble()) +} \ No newline at end of file diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/basics/History.java b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/basics/History.java new file mode 100644 index 0000000..3a53ffe --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/basics/History.java @@ -0,0 +1,23 @@ +package com.bennyhuo.kotlin.basics; + +/** + * Created by benny. + */ +public class History { + + private long when; + private String eventName; + + public History(long when, String eventName) { + this.when = when; + this.eventName = eventName; + } + + public long when() { + return when; + } + + public String eventName() { + return eventName; + } +} diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/basics/Main.java b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/basics/Main.java new file mode 100644 index 0000000..adf1298 --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/basics/Main.java @@ -0,0 +1,12 @@ +package com.bennyhuo.kotlin.basics; + +/** + * Created by benny. + */ +public class Main { + public static void main(String[] args) { + BackTicksKt.fun(); + BackTicksKt.classInJava(); + BackTicksKt.This_is_a_test(); + } +} diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/valueclass/ValueClass.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/valueclass/ValueClass.kt new file mode 100644 index 0000000..10caba0 --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/valueclass/ValueClass.kt @@ -0,0 +1,10 @@ +package com.bennyhuo.kotlin.update15.valueclass + +/** + * Created by benny. + */ + +inline class DurationForLegacy(val value: Long) + +@JvmInline +value class DurationForNew(val value: Long) \ No newline at end of file From 2177e28d15098ace8cda9664ade95295dba279ff Mon Sep 17 00:00:00 2001 From: bennyhuo Date: Wed, 14 Jul 2021 08:07:11 +0800 Subject: [PATCH 46/60] kotlin-dsl --- code/Kotlin-Sample/build.gradle.kts | 4 +++- code/Kotlin-Sample/buildSrc/build.gradle.kts | 12 ++++++++++++ .../buildSrc/src/main/kotlin/TestPlugin.kt | 11 +++++++++++ .../buildSrc/src/main/kotlin/test-plugin.gradle.kts | 7 +++++++ 4 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 code/Kotlin-Sample/buildSrc/src/main/kotlin/TestPlugin.kt create mode 100644 code/Kotlin-Sample/buildSrc/src/main/kotlin/test-plugin.gradle.kts diff --git a/code/Kotlin-Sample/build.gradle.kts b/code/Kotlin-Sample/build.gradle.kts index eca181b..6f4e86d 100644 --- a/code/Kotlin-Sample/build.gradle.kts +++ b/code/Kotlin-Sample/build.gradle.kts @@ -8,13 +8,15 @@ buildscript { } dependencies { classpath("com.android.tools.build:gradle:4.1.3") - classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version") + classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion") } } plugins { java kotlin("jvm") version "1.5.10" + id("test-plugin") + id("com.bennyhuo.test-plugin") } group = "com.bennyhuo.kotlin.hello" diff --git a/code/Kotlin-Sample/buildSrc/build.gradle.kts b/code/Kotlin-Sample/buildSrc/build.gradle.kts index 3917f98..28c68a8 100644 --- a/code/Kotlin-Sample/buildSrc/build.gradle.kts +++ b/code/Kotlin-Sample/buildSrc/build.gradle.kts @@ -1,7 +1,19 @@ plugins { `kotlin-dsl` + //region + //id("org.gradle.kotlin.kotlin-dsl") version "2.1.4" + //endregion } repositories { maven("https://mirrors.tencent.com/nexus/repository/maven-public/") +} + +gradlePlugin { + plugins { + create("TestPlugin") { + id = "com.bennyhuo.test-plugin" + implementationClass = "TestPlugin" + } + } } \ No newline at end of file diff --git a/code/Kotlin-Sample/buildSrc/src/main/kotlin/TestPlugin.kt b/code/Kotlin-Sample/buildSrc/src/main/kotlin/TestPlugin.kt new file mode 100644 index 0000000..f29dcdc --- /dev/null +++ b/code/Kotlin-Sample/buildSrc/src/main/kotlin/TestPlugin.kt @@ -0,0 +1,11 @@ +import org.gradle.api.Plugin +import org.gradle.api.Project + +/** + * Created by benny. + */ +class TestPlugin: Plugin { + override fun apply(target: Project) { + println("Test Plugin applied!") + } +} \ No newline at end of file diff --git a/code/Kotlin-Sample/buildSrc/src/main/kotlin/test-plugin.gradle.kts b/code/Kotlin-Sample/buildSrc/src/main/kotlin/test-plugin.gradle.kts new file mode 100644 index 0000000..ee9fa3c --- /dev/null +++ b/code/Kotlin-Sample/buildSrc/src/main/kotlin/test-plugin.gradle.kts @@ -0,0 +1,7 @@ +tasks.register("hello") { + println("Register task hello.") + group = "test" + doLast { + println("Hello Task from precompiled task.") + } +} \ No newline at end of file From fe102367733706291e3423c01eab7c5b2dfbc496 Mon Sep 17 00:00:00 2001 From: bennyhuo Date: Sun, 8 Aug 2021 11:51:03 +0800 Subject: [PATCH 47/60] Update. --- code/Kotlin-Sample/build.gradle.kts | 3 +- .../bennyhuo/kotlin/deprecatedsample/Api.kt | 2 +- .../kotlin/deprecatedsample/v2/NewApi.kt | 2 +- .../kotlin-android-sample/build.gradle.kts | 1 + .../kotlin/android/sample/KaeTestActivity.kt | 29 +++++ .../kotlin/android/sample/MainActivity.kt | 1 - code/Kotlin-Sample/settings.gradle.kts | 2 +- .../coroutines/HowSuspendFunctionWork.kt | 110 ++++++++++++++++++ .../kotlin/coroutines/Interceptors.kt | 75 ++++++++++++ .../kotlin/coroutinesupdate/NewChannelApis.kt | 4 + .../kotlin/deprecated/DeprecatedSample.kt | 4 +- .../java/com/bennyhuo/kotlin/tailrec/Main.kt | 109 +++++++++++++++++ 12 files changed, 334 insertions(+), 8 deletions(-) create mode 100644 code/Kotlin-Sample/kotlin-android-sample/src/main/java/com/bennyhuo/kotlin/android/sample/KaeTestActivity.kt create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutines/HowSuspendFunctionWork.kt create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutines/Interceptors.kt create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/tailrec/Main.kt diff --git a/code/Kotlin-Sample/build.gradle.kts b/code/Kotlin-Sample/build.gradle.kts index 6f4e86d..3a763da 100644 --- a/code/Kotlin-Sample/build.gradle.kts +++ b/code/Kotlin-Sample/build.gradle.kts @@ -1,4 +1,3 @@ -import org.gradle.model.internal.core.ModelNodes.withType import org.jetbrains.kotlin.gradle.tasks.KotlinCompile buildscript { @@ -7,7 +6,7 @@ buildscript { maven("https://mirrors.tencent.com/nexus/repository/maven-public/") } dependencies { - classpath("com.android.tools.build:gradle:4.1.3") + //classpath("com.android.tools.build:gradle:4.1.3") classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion") } } diff --git a/code/Kotlin-Sample/deprecated-sample/src/main/java/com/bennyhuo/kotlin/deprecatedsample/Api.kt b/code/Kotlin-Sample/deprecated-sample/src/main/java/com/bennyhuo/kotlin/deprecatedsample/Api.kt index 337d9e1..7691b53 100644 --- a/code/Kotlin-Sample/deprecated-sample/src/main/java/com/bennyhuo/kotlin/deprecatedsample/Api.kt +++ b/code/Kotlin-Sample/deprecated-sample/src/main/java/com/bennyhuo/kotlin/deprecatedsample/Api.kt @@ -9,7 +9,7 @@ object Api { @Deprecated( message = "Use newApiForDeprecated instead.", replaceWith = ReplaceWith( - expression = "NewApi.newApiForDeprecated(key, value)", + expression = "NewApi.newApiForDeprecated(key, value, default)", imports = ["com.bennyhuo.kotlin.deprecatedsample.v2.NewApi"] ) ) diff --git a/code/Kotlin-Sample/deprecated-sample/src/main/java/com/bennyhuo/kotlin/deprecatedsample/v2/NewApi.kt b/code/Kotlin-Sample/deprecated-sample/src/main/java/com/bennyhuo/kotlin/deprecatedsample/v2/NewApi.kt index 6bf9e99..fe71f2e 100644 --- a/code/Kotlin-Sample/deprecated-sample/src/main/java/com/bennyhuo/kotlin/deprecatedsample/v2/NewApi.kt +++ b/code/Kotlin-Sample/deprecated-sample/src/main/java/com/bennyhuo/kotlin/deprecatedsample/v2/NewApi.kt @@ -2,7 +2,7 @@ package com.bennyhuo.kotlin.deprecatedsample.v2 object NewApi { - fun newApiForDeprecated(key: String, value: String) { + fun newApiForDeprecated(key: String, value: String, default: String) { } diff --git a/code/Kotlin-Sample/kotlin-android-sample/build.gradle.kts b/code/Kotlin-Sample/kotlin-android-sample/build.gradle.kts index 6e20a19..108e17c 100644 --- a/code/Kotlin-Sample/kotlin-android-sample/build.gradle.kts +++ b/code/Kotlin-Sample/kotlin-android-sample/build.gradle.kts @@ -30,6 +30,7 @@ android { } kotlinOptions { jvmTarget = "1.8" + useOldBackend = true } } diff --git a/code/Kotlin-Sample/kotlin-android-sample/src/main/java/com/bennyhuo/kotlin/android/sample/KaeTestActivity.kt b/code/Kotlin-Sample/kotlin-android-sample/src/main/java/com/bennyhuo/kotlin/android/sample/KaeTestActivity.kt new file mode 100644 index 0000000..b9bdd07 --- /dev/null +++ b/code/Kotlin-Sample/kotlin-android-sample/src/main/java/com/bennyhuo/kotlin/android/sample/KaeTestActivity.kt @@ -0,0 +1,29 @@ +package com.bennyhuo.kotlin.android.sample + +import android.animation.ObjectAnimator +import android.os.Bundle +import android.view.View +import androidx.appcompat.app.AppCompatActivity +import androidx.lifecycle.lifecycleScope +import kotlinx.android.synthetic.main.activity_main.* +import kotlinx.coroutines.channels.awaitClose +import kotlinx.coroutines.channels.trySendBlocking +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.callbackFlow +import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.launch +import org.slf4j.LoggerFactory + +class KaeTestActivity : AppCompatActivity() { + private val logger = LoggerFactory.getLogger(KaeTestActivity::class.java) + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_main) + + textView.text = "hello" + textView.setOnClickListener { + logger.debug("clicked.") + } + } +} \ No newline at end of file diff --git a/code/Kotlin-Sample/kotlin-android-sample/src/main/java/com/bennyhuo/kotlin/android/sample/MainActivity.kt b/code/Kotlin-Sample/kotlin-android-sample/src/main/java/com/bennyhuo/kotlin/android/sample/MainActivity.kt index 1f5ba4b..48e7f35 100644 --- a/code/Kotlin-Sample/kotlin-android-sample/src/main/java/com/bennyhuo/kotlin/android/sample/MainActivity.kt +++ b/code/Kotlin-Sample/kotlin-android-sample/src/main/java/com/bennyhuo/kotlin/android/sample/MainActivity.kt @@ -3,7 +3,6 @@ package com.bennyhuo.kotlin.android.sample import android.animation.ObjectAnimator import android.os.Bundle import android.view.View -import android.view.ViewPropertyAnimator import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.lifecycleScope import kotlinx.android.synthetic.main.activity_main.* diff --git a/code/Kotlin-Sample/settings.gradle.kts b/code/Kotlin-Sample/settings.gradle.kts index 5dc3e5e..1ab542f 100644 --- a/code/Kotlin-Sample/settings.gradle.kts +++ b/code/Kotlin-Sample/settings.gradle.kts @@ -1,7 +1,7 @@ rootProject.name = "Kotlin-Sample" include(":opt-in-sample",":deprecated-sample") -include(":kotlin-android-sample") +//include(":kotlin-android-sample") include("kotlin-js-sample") include("kclass-issue") include("Kotlin-mpp-sample") diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutines/HowSuspendFunctionWork.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutines/HowSuspendFunctionWork.kt new file mode 100644 index 0000000..ee10d3d --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutines/HowSuspendFunctionWork.kt @@ -0,0 +1,110 @@ +package com.bennyhuo.kotlin.coroutines + +import kotlinx.coroutines.asCoroutineDispatcher +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch +import java.util.concurrent.Executors +import kotlin.concurrent.thread +import kotlin.coroutines.Continuation +import kotlin.coroutines.resume +import kotlin.coroutines.suspendCoroutine +import kotlin.reflect.KMutableProperty0 + +/** + * Created by benny. + */ +suspend fun main() { + eatGame() +} + +suspend fun noSuspend() { + println("noSuspend called.") +} + +suspend fun suspended() { + delay(100) + println("resumed after 100ms") +} + +suspend fun fakeSuspend() = suspendCoroutine { + it.resume(1) +} + +suspend fun fakeSuspend2() = suspendCoroutine { + Thread.sleep(100) + it.resume(1) +} + +suspend fun realSuspend() = suspendCoroutine { + thread { + Thread.sleep(100) + it.resume(1) + } +} + +class EatGame { + private var feedContinuation: Continuation? = null + private var eatContinuation: Continuation? = null + private var eatAttempts = 0 + + var isActive: Boolean = true + private set + + suspend fun eat(): String { + return if (isActive) suspendCoroutine { + this.eatContinuation = it + resumeContinuation(this::feedContinuation, eatAttempts++) + } else "" + } + + suspend fun feed(food: String): Int { + return if (isActive) suspendCoroutine { + this.feedContinuation = it + resumeContinuation(this::eatContinuation, food) + } else -1 + } + + fun timeout() { + isActive = false + resumeContinuation(this::feedContinuation, eatAttempts) + resumeContinuation(this::eatContinuation, "") + } + + private fun resumeContinuation( + continuationRef: KMutableProperty0?>, + value: T + ) { + val continuation = continuationRef.get() + continuationRef.set(null) + continuation?.resume(value) + } +} + +suspend fun eatGame() { + coroutineScope { + val dispatcher = Executors.newSingleThreadExecutor().asCoroutineDispatcher() + val game = EatGame() + launch(dispatcher) { + println("Ready Go!") + delay(1000) + game.timeout() + println("Timeout!") + } + launch(dispatcher) { + while (game.isActive) { + delay(60) + val food = Math.random() + println("[${Thread.currentThread().name} #1] Feed $food >>>") + println("[${Thread.currentThread().name} #1] Complete: ${game.feed("$food")}") + } + } + + launch(dispatcher) { + while (game.isActive) { + delay(50) + println("[${Thread.currentThread().name} #2] Eat ${game.eat()} <<<") + } + } + } +} \ No newline at end of file diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutines/Interceptors.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutines/Interceptors.kt new file mode 100644 index 0000000..be8af23 --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutines/Interceptors.kt @@ -0,0 +1,75 @@ +package com.bennyhuo.kotlin.coroutines + +import kotlinx.coroutines.* +import kotlin.concurrent.thread +import kotlin.coroutines.Continuation +import kotlin.coroutines.ContinuationInterceptor +import kotlin.coroutines.CoroutineContext + +/** + * Created by benny. + */ +suspend fun main() { + + log(1) + + val job = GlobalScope.launch( + context = CoroutineName("Hello") + MyNewContinuationInterceptor2() + MyNewContinuationInterceptor1(), + start = CoroutineStart.UNDISPATCHED + ) { + log(2) + delay(1000) + log(3) + log(coroutineContext[ContinuationInterceptor]) + } + + log(4) + + job.join() + + log(5) +} + +private class MyNewContinuationInterceptor1 : ContinuationInterceptor { + + companion object Key : CoroutineContext.Key + + override val key: CoroutineContext.Key<*> = MyNewContinuationInterceptor1 + + override fun interceptContinuation(continuation: Continuation): Continuation { + return object : Continuation { + override val context: CoroutineContext = continuation.context + + override fun resumeWith(result: Result) { + log(" $result") + thread(name = "MyMain1") { + continuation.resumeWith(result) + } + } + } + } +} + +private class MyNewContinuationInterceptor2 : ContinuationInterceptor { + + companion object Key : CoroutineContext.Key + + override val key: CoroutineContext.Key<*> = MyNewContinuationInterceptor2 + + override fun interceptContinuation(continuation: Continuation): Continuation { + return object : Continuation { + override val context: CoroutineContext = continuation.context + + override fun resumeWith(result: Result) { + log(" $result") + thread(name = "MyMain2") { + continuation.resumeWith(result) + } + } + } + } +} + +fun log(message: Any?) { + println("[${Thread.currentThread().name}] $message") +} \ No newline at end of file diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/NewChannelApis.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/NewChannelApis.kt index 7ca8191..c145b72 100644 --- a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/NewChannelApis.kt +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/NewChannelApis.kt @@ -35,6 +35,10 @@ suspend fun main() { } } + select { + consumer.onJoin + } + val consumer1 = produce { diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/deprecated/DeprecatedSample.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/deprecated/DeprecatedSample.kt index ab34d63..4005d20 100644 --- a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/deprecated/DeprecatedSample.kt +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/deprecated/DeprecatedSample.kt @@ -1,7 +1,7 @@ package com.bennyhuo.kotlin.deprecated -import com.bennyhuo.kotlin.deprecatedsample.v2.NewApi +import com.bennyhuo.kotlin.deprecatedsample.Api fun main() { - NewApi.newApiForDeprecated("name", "bennyhuo 不是算命的") + Api.deprecatedDontUse("name", "bennyhuo 不是算命的") } \ No newline at end of file diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/tailrec/Main.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/tailrec/Main.kt new file mode 100644 index 0000000..f336715 --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/tailrec/Main.kt @@ -0,0 +1,109 @@ +package com.bennyhuo.kotlin.tailrec + +import kotlin.time.ExperimentalTime +import kotlin.time.measureTime + + +/** + * Created by benny. + */ +@OptIn(ExperimentalTime::class) +fun main() { +// timeCost { factorial(10u) } +// timeCost { factorialTR(10u) } +// timeCost { factorialLoop(10u) } +// +// timeCost { fibonacciTR(1000u) } +// timeCost { fibonacciLoop(1000u) } + timeCost { fibonacci(50u) } +} + +@OptIn(ExperimentalTime::class) +inline fun timeCost(block: () -> Unit) { + measureTime { + block() + }.let { + println(it.inWholeMilliseconds) + } +} + +//region factorial +fun factorial(n: UInt): UInt { + if (n == 0u) return 1u + return n * factorial(n - 1u) +} + +fun factorialTR(n: UInt): UInt { + tailrec fun factorialInner(n: UInt, result: UInt): UInt { + if (n <= 1u) return result + return factorialInner(n - 1u, result * n) + } + return factorialInner(n, 1u) +} + +fun factorialLoop(n: UInt): UInt { + var result = 1u + for (i in 1u..n) { + result *= i + } + return result +} +//endregion + +//region fibonacci +fun fibonacci(n: UInt): UInt { + if (n < 2u) return n + return fibonacci(n - 1u) + fibonacci(n - 2u) +} + +fun fibonacciTR(n: UInt): UInt { + if (n < 2u) return n + + tailrec fun fibonacciInner(n: UInt, a: UInt, b: UInt): UInt { + if (n < 2u) return b + return fibonacciInner(n - 1u, b, a + b) + } + return fibonacciInner(n, 0u, 1u) +} + +fun fibonacciLoop(n: UInt): UInt { + if (n < 2u) return n + + var a = 0u + var b = 1u + for (i in 2u..n) { + val tmp = b + b = a + b + a = tmp + + //region same but confusing + // b = a + b + // a = b - a + //endregion + } + return b +} +//endregion + +//region List +sealed class List { + object Nil : List() + class Cons(val value: T, val next: List) : List() +} + +tailrec fun List.forEach(block: (T) -> Unit) { + when (this) { + List.Nil -> return + is List.Cons -> { + block(value) + next.forEach(block) + } + } +} + +fun listOf(vararg values: T): List { + return values.reversedArray().fold(List.Nil as List) { acc, t -> + List.Cons(t, acc) + } +} +//endregion \ No newline at end of file From 6dbd85b4fd50cc68fab5fe547febc8acb635edd3 Mon Sep 17 00:00:00 2001 From: bennyhuo Date: Mon, 23 Aug 2021 06:39:53 +0800 Subject: [PATCH 48/60] Update. --- code/Kotlin-Sample/build.gradle.kts | 2 +- .../kotlin/android/sample/KaeTestActivity.kt | 13 ++++--------- code/Kotlin-Sample/settings.gradle.kts | 2 +- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/code/Kotlin-Sample/build.gradle.kts b/code/Kotlin-Sample/build.gradle.kts index 3a763da..7e1b108 100644 --- a/code/Kotlin-Sample/build.gradle.kts +++ b/code/Kotlin-Sample/build.gradle.kts @@ -6,7 +6,7 @@ buildscript { maven("https://mirrors.tencent.com/nexus/repository/maven-public/") } dependencies { - //classpath("com.android.tools.build:gradle:4.1.3") + classpath("com.android.tools.build:gradle:4.1.3") classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion") } } diff --git a/code/Kotlin-Sample/kotlin-android-sample/src/main/java/com/bennyhuo/kotlin/android/sample/KaeTestActivity.kt b/code/Kotlin-Sample/kotlin-android-sample/src/main/java/com/bennyhuo/kotlin/android/sample/KaeTestActivity.kt index b9bdd07..c986184 100644 --- a/code/Kotlin-Sample/kotlin-android-sample/src/main/java/com/bennyhuo/kotlin/android/sample/KaeTestActivity.kt +++ b/code/Kotlin-Sample/kotlin-android-sample/src/main/java/com/bennyhuo/kotlin/android/sample/KaeTestActivity.kt @@ -1,17 +1,8 @@ package com.bennyhuo.kotlin.android.sample -import android.animation.ObjectAnimator import android.os.Bundle -import android.view.View import androidx.appcompat.app.AppCompatActivity -import androidx.lifecycle.lifecycleScope import kotlinx.android.synthetic.main.activity_main.* -import kotlinx.coroutines.channels.awaitClose -import kotlinx.coroutines.channels.trySendBlocking -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.callbackFlow -import kotlinx.coroutines.flow.collect -import kotlinx.coroutines.launch import org.slf4j.LoggerFactory class KaeTestActivity : AppCompatActivity() { @@ -25,5 +16,9 @@ class KaeTestActivity : AppCompatActivity() { textView.setOnClickListener { logger.debug("clicked.") } + + textView?.setOnClickListener { + + } } } \ No newline at end of file diff --git a/code/Kotlin-Sample/settings.gradle.kts b/code/Kotlin-Sample/settings.gradle.kts index 1ab542f..5dc3e5e 100644 --- a/code/Kotlin-Sample/settings.gradle.kts +++ b/code/Kotlin-Sample/settings.gradle.kts @@ -1,7 +1,7 @@ rootProject.name = "Kotlin-Sample" include(":opt-in-sample",":deprecated-sample") -//include(":kotlin-android-sample") +include(":kotlin-android-sample") include("kotlin-js-sample") include("kclass-issue") include("Kotlin-mpp-sample") From b876302fcf77bcd5b538a917fcf5fc41b2dbfff1 Mon Sep 17 00:00:00 2001 From: bennyhuo Date: Wed, 29 Sep 2021 06:55:05 +0800 Subject: [PATCH 49/60] Update. --- code/Kotlin-Sample/build.gradle.kts | 3 +- .../buildSrc/src/main/kotlin/Versions.kt | 2 +- .../kotlin/update15/sealedwhen/Main.kt | 39 +++++++++++++++++++ 3 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedwhen/Main.kt diff --git a/code/Kotlin-Sample/build.gradle.kts b/code/Kotlin-Sample/build.gradle.kts index 7e1b108..37a2a3d 100644 --- a/code/Kotlin-Sample/build.gradle.kts +++ b/code/Kotlin-Sample/build.gradle.kts @@ -1,7 +1,6 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile buildscript { - val kotlin_version by extra("1.5.10") repositories { maven("https://mirrors.tencent.com/nexus/repository/maven-public/") } @@ -13,7 +12,7 @@ buildscript { plugins { java - kotlin("jvm") version "1.5.10" + kotlin("jvm") version kotlinVersion id("test-plugin") id("com.bennyhuo.test-plugin") } diff --git a/code/Kotlin-Sample/buildSrc/src/main/kotlin/Versions.kt b/code/Kotlin-Sample/buildSrc/src/main/kotlin/Versions.kt index 4f99bd2..32ab965 100644 --- a/code/Kotlin-Sample/buildSrc/src/main/kotlin/Versions.kt +++ b/code/Kotlin-Sample/buildSrc/src/main/kotlin/Versions.kt @@ -1,2 +1,2 @@ -val kotlinVersion = "1.5.10" +val kotlinVersion = "1.5.30" val kotlinCoroutineVersion = "1.5.0" \ No newline at end of file diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedwhen/Main.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedwhen/Main.kt new file mode 100644 index 0000000..8a9e088 --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update15/sealedwhen/Main.kt @@ -0,0 +1,39 @@ +package com.bennyhuo.kotlin.update15.sealedwhen + +/** + * Created by benny. + */ + +enum class State { + Idle, Playing, Error +} + +class Song + +sealed interface PlayState { + object Idle: PlayState + class Playing(val song: Song): PlayState + class Error(val throwable: Throwable): PlayState +} + +fun main() { + val state = State.Idle + when (state) { + State.Idle -> { + + } + + State.Playing -> { + + } + } + + val playState: PlayState = PlayState.Idle + when (playState) { + PlayState.Idle -> { + + } + } + + +} \ No newline at end of file From dea14862091e398acedd72615cc0744a51236c04 Mon Sep 17 00:00:00 2001 From: bennyhuo Date: Tue, 5 Oct 2021 12:22:17 +0800 Subject: [PATCH 50/60] Update. --- .../bennyhuo/kotlin/nonfinalfunction/Base.kt | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/nonfinalfunction/Base.kt diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/nonfinalfunction/Base.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/nonfinalfunction/Base.kt new file mode 100644 index 0000000..4860aa5 --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/nonfinalfunction/Base.kt @@ -0,0 +1,45 @@ +package com.bennyhuo.kotlin.nonfinalfunction + +import kotlin.random.Random + +/** + * Created by benny. + */ +open class Base { + + open val name = "Base" + + val id = generateId() + + init { + println("Base: id: $id, name: ${xyz()}") + } + + open fun generateId(): Int { + return Random(System.currentTimeMillis()).nextInt(10000000) + } + + fun xyz(): String { + generateId() + return this.name + } + +} + +class Derived: Base() { + + override val name = "Derived" + + init { + println("Derived: id: $id, name: $name") + } + + override fun generateId(): Int { + return 1 + } + +} + +fun main() { + val d = Derived() +} From a473f8d03596aaea42e6d37d748e8939a167cde2 Mon Sep 17 00:00:00 2001 From: bennyhuo Date: Sun, 24 Oct 2021 22:03:25 +0800 Subject: [PATCH 51/60] Update. --- .../kotlin/other/currying/CurryingSample.kt | 22 ++ .../other/currying/tursomcurrying/currying.kt | 230 ++++++++++++++++++ .../currying/tursomcurrying/curyingMethod.kt | 21 ++ .../currying/tursomcurrying/uncurrying.kt | 21 ++ 4 files changed, 294 insertions(+) create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/other/currying/CurryingSample.kt create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/other/currying/tursomcurrying/currying.kt create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/other/currying/tursomcurrying/curyingMethod.kt create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/other/currying/tursomcurrying/uncurrying.kt diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/other/currying/CurryingSample.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/other/currying/CurryingSample.kt new file mode 100644 index 0000000..d4df742 --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/other/currying/CurryingSample.kt @@ -0,0 +1,22 @@ +package com.bennyhuo.kotlin.other.currying + +import cn.tursom.core.curry.currying + +/** + * Created by benny. + */ + +enum class LoggerLevel { + DEBUG, + INFO, + WARN, + ERROR +} + +fun log(context: Any?, level: LoggerLevel, message: Any?) { + println("$level - [$context]: $message") +} + +fun main() { + ::log.currying()(1234)(LoggerLevel.DEBUG)("Hello Curried from Kotlin !!!!!!!!!!") +} \ No newline at end of file diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/other/currying/tursomcurrying/currying.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/other/currying/tursomcurrying/currying.kt new file mode 100644 index 0000000..a5f0b5c --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/other/currying/tursomcurrying/currying.kt @@ -0,0 +1,230 @@ +package cn.tursom.core.curry + +operator fun ((T1, T2) -> R).invoke() = this +operator fun ((T1, T2) -> R).invoke(a1: T1) = { a2: T2 -> this(a1, a2) } + +operator fun ((T1, T2, T3) -> R).invoke() = this +operator fun ((T1, T2, T3) -> R).invoke(a1: T1) = { a2: T2, a3: T3 -> this(a1, a2, a3) } +operator fun ((T1, T2, T3) -> R).invoke(a1: T1, a2: T2) = { a3: T3 -> this(a1, a2, a3) } + +operator fun ((T1, T2, T3, T4) -> R).invoke() = this +operator fun ((T1, T2, T3, T4) -> R).invoke(a1: T1) = { a2: T2, a3: T3, a4: T4 -> this(a1, a2, a3, a4) } +operator fun ((T1, T2, T3, T4) -> R).invoke(a1: T1, a2: T2) = { a3: T3, a4: T4 -> this(a1, a2, a3, a4) } +operator fun ((T1, T2, T3, T4) -> R).invoke(a1: T1, a2: T2, a3: T3) = { a4: T4 -> this(a1, a2, a3, a4) } + +operator fun ((T1, T2, T3, T4, T5) -> R).invoke() = this +operator fun ((T1, T2, T3, T4, T5) -> R).invoke(a1: T1) = { a2: T2, a3: T3, a4: T4, a5: T5 -> this(a1, a2, a3, a4, a5) } +operator fun ((T1, T2, T3, T4, T5) -> R).invoke(a1: T1, a2: T2) = { a3: T3, a4: T4, a5: T5 -> this(a1, a2, a3, a4, a5) } +operator fun ((T1, T2, T3, T4, T5) -> R).invoke(a1: T1, a2: T2, a3: T3) = { a4: T4, a5: T5 -> this(a1, a2, a3, a4, a5) } +operator fun ((T1, T2, T3, T4, T5) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4) = { a5: T5 -> this(a1, a2, a3, a4, a5) } + +operator fun ((T1, T2, T3, T4, T5, T6) -> R).invoke() = this +operator fun ((T1, T2, T3, T4, T5, T6) -> R).invoke(a1: T1) = { a2: T2, a3: T3, a4: T4, a5: T5, a6: T6 -> this(a1, a2, a3, a4, a5, a6) } +operator fun ((T1, T2, T3, T4, T5, T6) -> R).invoke(a1: T1, a2: T2) = { a3: T3, a4: T4, a5: T5, a6: T6 -> this(a1, a2, a3, a4, a5, a6) } +operator fun ((T1, T2, T3, T4, T5, T6) -> R).invoke(a1: T1, a2: T2, a3: T3) = { a4: T4, a5: T5, a6: T6 -> this(a1, a2, a3, a4, a5, a6) } +operator fun ((T1, T2, T3, T4, T5, T6) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4) = { a5: T5, a6: T6 -> this(a1, a2, a3, a4, a5, a6) } +operator fun ((T1, T2, T3, T4, T5, T6) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5) = { a6: T6 -> this(a1, a2, a3, a4, a5, a6) } + +operator fun ((T1, T2, T3, T4, T5, T6, T7) -> R).invoke() = this +operator fun ((T1, T2, T3, T4, T5, T6, T7) -> R).invoke(a1: T1) = { a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7 -> this(a1, a2, a3, a4, a5, a6, a7) } +operator fun ((T1, T2, T3, T4, T5, T6, T7) -> R).invoke(a1: T1, a2: T2) = { a3: T3, a4: T4, a5: T5, a6: T6, a7: T7 -> this(a1, a2, a3, a4, a5, a6, a7) } +operator fun ((T1, T2, T3, T4, T5, T6, T7) -> R).invoke(a1: T1, a2: T2, a3: T3) = { a4: T4, a5: T5, a6: T6, a7: T7 -> this(a1, a2, a3, a4, a5, a6, a7) } +operator fun ((T1, T2, T3, T4, T5, T6, T7) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4) = { a5: T5, a6: T6, a7: T7 -> this(a1, a2, a3, a4, a5, a6, a7) } +operator fun ((T1, T2, T3, T4, T5, T6, T7) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5) = { a6: T6, a7: T7 -> this(a1, a2, a3, a4, a5, a6, a7) } +operator fun ((T1, T2, T3, T4, T5, T6, T7) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6) = { a7: T7 -> this(a1, a2, a3, a4, a5, a6, a7) } + +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8) -> R).invoke() = this +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8) -> R).invoke(a1: T1) = { a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8 -> this(a1, a2, a3, a4, a5, a6, a7, a8) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8) -> R).invoke(a1: T1, a2: T2) = { a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8 -> this(a1, a2, a3, a4, a5, a6, a7, a8) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8) -> R).invoke(a1: T1, a2: T2, a3: T3) = { a4: T4, a5: T5, a6: T6, a7: T7, a8: T8 -> this(a1, a2, a3, a4, a5, a6, a7, a8) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4) = { a5: T5, a6: T6, a7: T7, a8: T8 -> this(a1, a2, a3, a4, a5, a6, a7, a8) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5) = { a6: T6, a7: T7, a8: T8 -> this(a1, a2, a3, a4, a5, a6, a7, a8) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6) = { a7: T7, a8: T8 -> this(a1, a2, a3, a4, a5, a6, a7, a8) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7) = { a8: T8 -> this(a1, a2, a3, a4, a5, a6, a7, a8) } + +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9) -> R).invoke() = this +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9) -> R).invoke(a1: T1) = { a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9) -> R).invoke(a1: T1, a2: T2) = { a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9) -> R).invoke(a1: T1, a2: T2, a3: T3) = { a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4) = { a5: T5, a6: T6, a7: T7, a8: T8, a9: T9 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5) = { a6: T6, a7: T7, a8: T8, a9: T9 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6) = { a7: T7, a8: T8, a9: T9 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7) = { a8: T8, a9: T9 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8) = { a9: T9 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9) } + +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) -> R).invoke() = this +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) -> R).invoke(a1: T1) = { a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) -> R).invoke(a1: T1, a2: T2) = { a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) -> R).invoke(a1: T1, a2: T2, a3: T3) = { a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4) = { a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5) = { a6: T6, a7: T7, a8: T8, a9: T9, a10: T10 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6) = { a7: T7, a8: T8, a9: T9, a10: T10 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7) = { a8: T8, a9: T9, a10: T10 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8) = { a9: T9, a10: T10 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9) = { a10: T10 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) } + +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) -> R).invoke() = this +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) -> R).invoke(a1: T1) = { a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) -> R).invoke(a1: T1, a2: T2) = { a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) -> R).invoke(a1: T1, a2: T2, a3: T3) = { a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4) = { a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5) = { a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6) = { a7: T7, a8: T8, a9: T9, a10: T10, a11: T11 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7) = { a8: T8, a9: T9, a10: T10, a11: T11 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8) = { a9: T9, a10: T10, a11: T11 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9) = { a10: T10, a11: T11 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10) = { a11: T11 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) } + +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) -> R).invoke() = this +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) -> R).invoke(a1: T1) = { a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) -> R).invoke(a1: T1, a2: T2) = { a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) -> R).invoke(a1: T1, a2: T2, a3: T3) = { a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4) = { a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5) = { a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6) = { a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7) = { a8: T8, a9: T9, a10: T10, a11: T11, a12: T12 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8) = { a9: T9, a10: T10, a11: T11, a12: T12 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9) = { a10: T10, a11: T11, a12: T12 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10) = { a11: T11, a12: T12 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11) = { a12: T12 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) } + +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) -> R).invoke() = this +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) -> R).invoke(a1: T1) = { a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) -> R).invoke(a1: T1, a2: T2) = { a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) -> R).invoke(a1: T1, a2: T2, a3: T3) = { a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4) = { a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5) = { a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6) = { a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7) = { a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8) = { a9: T9, a10: T10, a11: T11, a12: T12, a13: T13 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9) = { a10: T10, a11: T11, a12: T12, a13: T13 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10) = { a11: T11, a12: T12, a13: T13 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11) = { a12: T12, a13: T13 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12) = { a13: T13 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) } + +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) -> R).invoke() = this +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) -> R).invoke(a1: T1) = { a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) -> R).invoke(a1: T1, a2: T2) = { a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) -> R).invoke(a1: T1, a2: T2, a3: T3) = { a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4) = { a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5) = { a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6) = { a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7) = { a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8) = { a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9) = { a10: T10, a11: T11, a12: T12, a13: T13, a14: T14 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10) = { a11: T11, a12: T12, a13: T13, a14: T14 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11) = { a12: T12, a13: T13, a14: T14 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12) = { a13: T13, a14: T14 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13) = { a14: T14 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) } + +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) -> R).invoke() = this +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) -> R).invoke(a1: T1) = { a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) -> R).invoke(a1: T1, a2: T2) = { a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) -> R).invoke(a1: T1, a2: T2, a3: T3) = { a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4) = { a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5) = { a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6) = { a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7) = { a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8) = { a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9) = { a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10) = { a11: T11, a12: T12, a13: T13, a14: T14, a15: T15 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11) = { a12: T12, a13: T13, a14: T14, a15: T15 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12) = { a13: T13, a14: T14, a15: T15 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13) = { a14: T14, a15: T15 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14) = { a15: T15 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) } + +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16) -> R).invoke() = this +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16) -> R).invoke(a1: T1) = { a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16) -> R).invoke(a1: T1, a2: T2) = { a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16) -> R).invoke(a1: T1, a2: T2, a3: T3) = { a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4) = { a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5) = { a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6) = { a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7) = { a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8) = { a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9) = { a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10) = { a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11) = { a12: T12, a13: T13, a14: T14, a15: T15, a16: T16 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12) = { a13: T13, a14: T14, a15: T15, a16: T16 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13) = { a14: T14, a15: T15, a16: T16 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14) = { a15: T15, a16: T16 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15) = { a16: T16 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16) } + +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17) -> R).invoke() = this +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17) -> R).invoke(a1: T1) = { a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17) -> R).invoke(a1: T1, a2: T2) = { a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17) -> R).invoke(a1: T1, a2: T2, a3: T3) = { a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4) = { a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5) = { a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6) = { a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7) = { a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8) = { a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9) = { a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10) = { a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11) = { a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12) = { a13: T13, a14: T14, a15: T15, a16: T16, a17: T17 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13) = { a14: T14, a15: T15, a16: T16, a17: T17 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14) = { a15: T15, a16: T16, a17: T17 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15) = { a16: T16, a17: T17 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16) = { a17: T17 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17) } + +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18) -> R).invoke() = this +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18) -> R).invoke(a1: T1) = { a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17, a18: T18 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18) -> R).invoke(a1: T1, a2: T2) = { a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17, a18: T18 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18) -> R).invoke(a1: T1, a2: T2, a3: T3) = { a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17, a18: T18 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4) = { a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17, a18: T18 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5) = { a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17, a18: T18 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6) = { a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17, a18: T18 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7) = { a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17, a18: T18 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8) = { a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17, a18: T18 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9) = { a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17, a18: T18 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10) = { a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17, a18: T18 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11) = { a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17, a18: T18 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12) = { a13: T13, a14: T14, a15: T15, a16: T16, a17: T17, a18: T18 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13) = { a14: T14, a15: T15, a16: T16, a17: T17, a18: T18 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14) = { a15: T15, a16: T16, a17: T17, a18: T18 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15) = { a16: T16, a17: T17, a18: T18 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16) = { a17: T17, a18: T18 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17) = { a18: T18 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18) } + +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19) -> R).invoke() = this +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19) -> R).invoke(a1: T1) = { a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17, a18: T18, a19: T19 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19) -> R).invoke(a1: T1, a2: T2) = { a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17, a18: T18, a19: T19 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19) -> R).invoke(a1: T1, a2: T2, a3: T3) = { a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17, a18: T18, a19: T19 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4) = { a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17, a18: T18, a19: T19 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5) = { a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17, a18: T18, a19: T19 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6) = { a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17, a18: T18, a19: T19 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7) = { a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17, a18: T18, a19: T19 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8) = { a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17, a18: T18, a19: T19 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9) = { a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17, a18: T18, a19: T19 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10) = { a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17, a18: T18, a19: T19 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11) = { a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17, a18: T18, a19: T19 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12) = { a13: T13, a14: T14, a15: T15, a16: T16, a17: T17, a18: T18, a19: T19 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13) = { a14: T14, a15: T15, a16: T16, a17: T17, a18: T18, a19: T19 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14) = { a15: T15, a16: T16, a17: T17, a18: T18, a19: T19 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15) = { a16: T16, a17: T17, a18: T18, a19: T19 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16) = { a17: T17, a18: T18, a19: T19 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17) = { a18: T18, a19: T19 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17, a18: T18) = { a19: T19 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19) } + +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) -> R).invoke() = this +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) -> R).invoke(a1: T1) = { a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17, a18: T18, a19: T19, a20: T20 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) -> R).invoke(a1: T1, a2: T2) = { a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17, a18: T18, a19: T19, a20: T20 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) -> R).invoke(a1: T1, a2: T2, a3: T3) = { a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17, a18: T18, a19: T19, a20: T20 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4) = { a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17, a18: T18, a19: T19, a20: T20 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5) = { a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17, a18: T18, a19: T19, a20: T20 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6) = { a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17, a18: T18, a19: T19, a20: T20 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7) = { a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17, a18: T18, a19: T19, a20: T20 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8) = { a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17, a18: T18, a19: T19, a20: T20 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9) = { a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17, a18: T18, a19: T19, a20: T20 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10) = { a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17, a18: T18, a19: T19, a20: T20 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11) = { a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17, a18: T18, a19: T19, a20: T20 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12) = { a13: T13, a14: T14, a15: T15, a16: T16, a17: T17, a18: T18, a19: T19, a20: T20 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13) = { a14: T14, a15: T15, a16: T16, a17: T17, a18: T18, a19: T19, a20: T20 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14) = { a15: T15, a16: T16, a17: T17, a18: T18, a19: T19, a20: T20 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15) = { a16: T16, a17: T17, a18: T18, a19: T19, a20: T20 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16) = { a17: T17, a18: T18, a19: T19, a20: T20 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17) = { a18: T18, a19: T19, a20: T20 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17, a18: T18) = { a19: T19, a20: T20 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) } +operator fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17, a18: T18, a19: T19) = { a20: T20 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) } + diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/other/currying/tursomcurrying/curyingMethod.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/other/currying/tursomcurrying/curyingMethod.kt new file mode 100644 index 0000000..cec1ffa --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/other/currying/tursomcurrying/curyingMethod.kt @@ -0,0 +1,21 @@ +package cn.tursom.core.curry + +fun ((T1, T2) -> R).currying() = { a1: T1 -> { a2: T2 -> this(a1, a2) } } +fun ((T1, T2, T3) -> R).currying() = { a1: T1 -> { a2: T2 -> { a3: T3 -> this(a1, a2, a3) } } } +fun ((T1, T2, T3, T4) -> R).currying() = { a1: T1 -> { a2: T2 -> { a3: T3 -> { a4: T4 -> this(a1, a2, a3, a4) } } } } +fun ((T1, T2, T3, T4, T5) -> R).currying() = { a1: T1 -> { a2: T2 -> { a3: T3 -> { a4: T4 -> { a5: T5 -> this(a1, a2, a3, a4, a5) } } } } } +fun ((T1, T2, T3, T4, T5, T6) -> R).currying() = { a1: T1 -> { a2: T2 -> { a3: T3 -> { a4: T4 -> { a5: T5 -> { a6: T6 -> this(a1, a2, a3, a4, a5, a6) } } } } } } +fun ((T1, T2, T3, T4, T5, T6, T7) -> R).currying() = { a1: T1 -> { a2: T2 -> { a3: T3 -> { a4: T4 -> { a5: T5 -> { a6: T6 -> { a7: T7 -> this(a1, a2, a3, a4, a5, a6, a7) } } } } } } } +fun ((T1, T2, T3, T4, T5, T6, T7, T8) -> R).currying() = { a1: T1 -> { a2: T2 -> { a3: T3 -> { a4: T4 -> { a5: T5 -> { a6: T6 -> { a7: T7 -> { a8: T8 -> this(a1, a2, a3, a4, a5, a6, a7, a8) } } } } } } } } +fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9) -> R).currying() = { a1: T1 -> { a2: T2 -> { a3: T3 -> { a4: T4 -> { a5: T5 -> { a6: T6 -> { a7: T7 -> { a8: T8 -> { a9: T9 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9) } } } } } } } } } +fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) -> R).currying() = { a1: T1 -> { a2: T2 -> { a3: T3 -> { a4: T4 -> { a5: T5 -> { a6: T6 -> { a7: T7 -> { a8: T8 -> { a9: T9 -> { a10: T10 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) } } } } } } } } } } +fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) -> R).currying() = { a1: T1 -> { a2: T2 -> { a3: T3 -> { a4: T4 -> { a5: T5 -> { a6: T6 -> { a7: T7 -> { a8: T8 -> { a9: T9 -> { a10: T10 -> { a11: T11 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) } } } } } } } } } } } +fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) -> R).currying() = { a1: T1 -> { a2: T2 -> { a3: T3 -> { a4: T4 -> { a5: T5 -> { a6: T6 -> { a7: T7 -> { a8: T8 -> { a9: T9 -> { a10: T10 -> { a11: T11 -> { a12: T12 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) } } } } } } } } } } } } +fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) -> R).currying() = { a1: T1 -> { a2: T2 -> { a3: T3 -> { a4: T4 -> { a5: T5 -> { a6: T6 -> { a7: T7 -> { a8: T8 -> { a9: T9 -> { a10: T10 -> { a11: T11 -> { a12: T12 -> { a13: T13 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) } } } } } } } } } } } } } +fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) -> R).currying() = { a1: T1 -> { a2: T2 -> { a3: T3 -> { a4: T4 -> { a5: T5 -> { a6: T6 -> { a7: T7 -> { a8: T8 -> { a9: T9 -> { a10: T10 -> { a11: T11 -> { a12: T12 -> { a13: T13 -> { a14: T14 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) } } } } } } } } } } } } } } +fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) -> R).currying() = { a1: T1 -> { a2: T2 -> { a3: T3 -> { a4: T4 -> { a5: T5 -> { a6: T6 -> { a7: T7 -> { a8: T8 -> { a9: T9 -> { a10: T10 -> { a11: T11 -> { a12: T12 -> { a13: T13 -> { a14: T14 -> { a15: T15 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) } } } } } } } } } } } } } } } +fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16) -> R).currying() = { a1: T1 -> { a2: T2 -> { a3: T3 -> { a4: T4 -> { a5: T5 -> { a6: T6 -> { a7: T7 -> { a8: T8 -> { a9: T9 -> { a10: T10 -> { a11: T11 -> { a12: T12 -> { a13: T13 -> { a14: T14 -> { a15: T15 -> { a16: T16 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16) } } } } } } } } } } } } } } } } +fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17) -> R).currying() = { a1: T1 -> { a2: T2 -> { a3: T3 -> { a4: T4 -> { a5: T5 -> { a6: T6 -> { a7: T7 -> { a8: T8 -> { a9: T9 -> { a10: T10 -> { a11: T11 -> { a12: T12 -> { a13: T13 -> { a14: T14 -> { a15: T15 -> { a16: T16 -> { a17: T17 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17) } } } } } } } } } } } } } } } } } +fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18) -> R).currying() = { a1: T1 -> { a2: T2 -> { a3: T3 -> { a4: T4 -> { a5: T5 -> { a6: T6 -> { a7: T7 -> { a8: T8 -> { a9: T9 -> { a10: T10 -> { a11: T11 -> { a12: T12 -> { a13: T13 -> { a14: T14 -> { a15: T15 -> { a16: T16 -> { a17: T17 -> { a18: T18 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18) } } } } } } } } } } } } } } } } } } +fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19) -> R).currying() = { a1: T1 -> { a2: T2 -> { a3: T3 -> { a4: T4 -> { a5: T5 -> { a6: T6 -> { a7: T7 -> { a8: T8 -> { a9: T9 -> { a10: T10 -> { a11: T11 -> { a12: T12 -> { a13: T13 -> { a14: T14 -> { a15: T15 -> { a16: T16 -> { a17: T17 -> { a18: T18 -> { a19: T19 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19) } } } } } } } } } } } } } } } } } } } +fun ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) -> R).currying() = { a1: T1 -> { a2: T2 -> { a3: T3 -> { a4: T4 -> { a5: T5 -> { a6: T6 -> { a7: T7 -> { a8: T8 -> { a9: T9 -> { a10: T10 -> { a11: T11 -> { a12: T12 -> { a13: T13 -> { a14: T14 -> { a15: T15 -> { a16: T16 -> { a17: T17 -> { a18: T18 -> { a19: T19 -> { a20: T20 -> this(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) } } } } } } } } } } } } } } } } } } } } diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/other/currying/tursomcurrying/uncurrying.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/other/currying/tursomcurrying/uncurrying.kt new file mode 100644 index 0000000..54b8fc4 --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/other/currying/tursomcurrying/uncurrying.kt @@ -0,0 +1,21 @@ +package cn.tursom.core.curry + +operator fun ((T1) -> (T2) -> R).invoke(a1: T1, a2: T2) = this(a1)(a2) +operator fun ((T1) -> (T2) -> (T3) -> R).invoke(a1: T1, a2: T2, a3: T3) = this(a1)(a2)(a3) +operator fun ((T1) -> (T2) -> (T3) -> (T4) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4) = this(a1)(a2)(a3)(a4) +operator fun ((T1) -> (T2) -> (T3) -> (T4) -> (T5) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5) = this(a1)(a2)(a3)(a4)(a5) +operator fun ((T1) -> (T2) -> (T3) -> (T4) -> (T5) -> (T6) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6) = this(a1)(a2)(a3)(a4)(a5)(a6) +operator fun ((T1) -> (T2) -> (T3) -> (T4) -> (T5) -> (T6) -> (T7) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7) = this(a1)(a2)(a3)(a4)(a5)(a6)(a7) +operator fun ((T1) -> (T2) -> (T3) -> (T4) -> (T5) -> (T6) -> (T7) -> (T8) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8) = this(a1)(a2)(a3)(a4)(a5)(a6)(a7)(a8) +operator fun ((T1) -> (T2) -> (T3) -> (T4) -> (T5) -> (T6) -> (T7) -> (T8) -> (T9) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9) = this(a1)(a2)(a3)(a4)(a5)(a6)(a7)(a8)(a9) +operator fun ((T1) -> (T2) -> (T3) -> (T4) -> (T5) -> (T6) -> (T7) -> (T8) -> (T9) -> (T10) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10) = this(a1)(a2)(a3)(a4)(a5)(a6)(a7)(a8)(a9)(a10) +operator fun ((T1) -> (T2) -> (T3) -> (T4) -> (T5) -> (T6) -> (T7) -> (T8) -> (T9) -> (T10) -> (T11) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11) = this(a1)(a2)(a3)(a4)(a5)(a6)(a7)(a8)(a9)(a10)(a11) +operator fun ((T1) -> (T2) -> (T3) -> (T4) -> (T5) -> (T6) -> (T7) -> (T8) -> (T9) -> (T10) -> (T11) -> (T12) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12) = this(a1)(a2)(a3)(a4)(a5)(a6)(a7)(a8)(a9)(a10)(a11)(a12) +operator fun ((T1) -> (T2) -> (T3) -> (T4) -> (T5) -> (T6) -> (T7) -> (T8) -> (T9) -> (T10) -> (T11) -> (T12) -> (T13) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13) = this(a1)(a2)(a3)(a4)(a5)(a6)(a7)(a8)(a9)(a10)(a11)(a12)(a13) +operator fun ((T1) -> (T2) -> (T3) -> (T4) -> (T5) -> (T6) -> (T7) -> (T8) -> (T9) -> (T10) -> (T11) -> (T12) -> (T13) -> (T14) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14) = this(a1)(a2)(a3)(a4)(a5)(a6)(a7)(a8)(a9)(a10)(a11)(a12)(a13)(a14) +operator fun ((T1) -> (T2) -> (T3) -> (T4) -> (T5) -> (T6) -> (T7) -> (T8) -> (T9) -> (T10) -> (T11) -> (T12) -> (T13) -> (T14) -> (T15) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15) = this(a1)(a2)(a3)(a4)(a5)(a6)(a7)(a8)(a9)(a10)(a11)(a12)(a13)(a14)(a15) +operator fun ((T1) -> (T2) -> (T3) -> (T4) -> (T5) -> (T6) -> (T7) -> (T8) -> (T9) -> (T10) -> (T11) -> (T12) -> (T13) -> (T14) -> (T15) -> (T16) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16) = this(a1)(a2)(a3)(a4)(a5)(a6)(a7)(a8)(a9)(a10)(a11)(a12)(a13)(a14)(a15)(a16) +operator fun ((T1) -> (T2) -> (T3) -> (T4) -> (T5) -> (T6) -> (T7) -> (T8) -> (T9) -> (T10) -> (T11) -> (T12) -> (T13) -> (T14) -> (T15) -> (T16) -> (T17) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17) = this(a1)(a2)(a3)(a4)(a5)(a6)(a7)(a8)(a9)(a10)(a11)(a12)(a13)(a14)(a15)(a16)(a17) +operator fun ((T1) -> (T2) -> (T3) -> (T4) -> (T5) -> (T6) -> (T7) -> (T8) -> (T9) -> (T10) -> (T11) -> (T12) -> (T13) -> (T14) -> (T15) -> (T16) -> (T17) -> (T18) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17, a18: T18) = this(a1)(a2)(a3)(a4)(a5)(a6)(a7)(a8)(a9)(a10)(a11)(a12)(a13)(a14)(a15)(a16)(a17)(a18) +operator fun ((T1) -> (T2) -> (T3) -> (T4) -> (T5) -> (T6) -> (T7) -> (T8) -> (T9) -> (T10) -> (T11) -> (T12) -> (T13) -> (T14) -> (T15) -> (T16) -> (T17) -> (T18) -> (T19) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17, a18: T18, a19: T19) = this(a1)(a2)(a3)(a4)(a5)(a6)(a7)(a8)(a9)(a10)(a11)(a12)(a13)(a14)(a15)(a16)(a17)(a18)(a19) +operator fun ((T1) -> (T2) -> (T3) -> (T4) -> (T5) -> (T6) -> (T7) -> (T8) -> (T9) -> (T10) -> (T11) -> (T12) -> (T13) -> (T14) -> (T15) -> (T16) -> (T17) -> (T18) -> (T19) -> (T20) -> R).invoke(a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6, a7: T7, a8: T8, a9: T9, a10: T10, a11: T11, a12: T12, a13: T13, a14: T14, a15: T15, a16: T16, a17: T17, a18: T18, a19: T19, a20: T20) = this(a1)(a2)(a3)(a4)(a5)(a6)(a7)(a8)(a9)(a10)(a11)(a12)(a13)(a14)(a15)(a16)(a17)(a18)(a19)(a20) From 5e02093d75ec535d20954ee15ac55bf2eea04632 Mon Sep 17 00:00:00 2001 From: bennyhuo Date: Mon, 15 Nov 2021 22:06:12 +0800 Subject: [PATCH 52/60] Update. --- .../bennyhuo/kotlin/basics/FunctionType.kt | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/basics/FunctionType.kt diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/basics/FunctionType.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/basics/FunctionType.kt new file mode 100644 index 0000000..ce2008f --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/basics/FunctionType.kt @@ -0,0 +1,70 @@ +package com.bennyhuo.kotlin.coroutines + +import kotlinx.coroutines.runBlocking + +/** + * Created by benny. + */ +fun a0() { + +} + +suspend fun a1() { + +} + +fun b0(): Int { + TODO() +} + +suspend fun b1(): Int { + TODO() +} + +fun Int.c0(block: (Int) -> String): String { + TODO() +} + +fun c00(i: Int, block: (Int) -> String): String { + TODO() +} + +suspend fun Int.c1(block: (Int) -> String): String { + TODO() +} + +suspend fun c11(i: Int, block: (Int) -> String): String { + TODO() +} + +fun x(block: suspend Int.((Int) -> String) -> String) { + runBlocking { + block(1) { + it.toString() + } + } +} + +fun Int.println() { + +} + +fun main() { + val typeA0 = ::a0 // () -> Unit + val typeA1 = ::a1 // suspend () -> Unit + + val typeB0 = ::b0 // () -> Int + val typeB1 = ::b1 // suspend () -> Int + + val typeC0 = Int::c0 // Int.((Int) -> String) -> String + val typeC0x = 1::c0 // ((Int) -> String) -> String + val typeC00 = ::c00 // (Int, (Int) -> String) -> String + val typeC1 = Int::c1 // suspend Int.((Int) -> String) -> String + val typeC11 = ::c11 // suspend (Int, (Int) -> String) -> String + + x(typeC1) + x(typeC11) + + listOf(1,2,3).forEach(Int::println) + listOf(1,2,3).forEach(::println) +} \ No newline at end of file From 8c2804083e3b25ba6bd19d1d12c83a82a75102df Mon Sep 17 00:00:00 2001 From: bennyhuo Date: Sat, 27 Nov 2021 08:11:15 +0800 Subject: [PATCH 53/60] Update Kotlin 1.6 --- code/Kotlin-Sample/build.gradle.kts | 28 ++++++---- .../buildSrc/src/main/kotlin/Versions.kt | 5 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../update16/annotations/Annotations.kt | 36 ++++++++++++ .../annotations/JavaAnnotationSample.java | 56 +++++++++++++++++++ .../kotlin/update16/builderinterfaces/Main.kt | 40 +++++++++++++ .../kotlin/update16/sealedwhen/Sample.kt | 29 ++++++++++ .../suspendingtype/SuspendingFunctionType.kt | 52 +++++++++++++++++ .../kotlin/update16/typeinferring/Main.kt | 40 +++++++++++++ 9 files changed, 274 insertions(+), 14 deletions(-) create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update16/annotations/Annotations.kt create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update16/annotations/JavaAnnotationSample.java create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update16/builderinterfaces/Main.kt create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update16/sealedwhen/Sample.kt create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update16/suspendingtype/SuspendingFunctionType.kt create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update16/typeinferring/Main.kt diff --git a/code/Kotlin-Sample/build.gradle.kts b/code/Kotlin-Sample/build.gradle.kts index 37a2a3d..5e00a50 100644 --- a/code/Kotlin-Sample/build.gradle.kts +++ b/code/Kotlin-Sample/build.gradle.kts @@ -30,16 +30,19 @@ dependencies { implementation(kotlin("stdlib")) implementation(kotlin("reflect")) - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0") - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.5.0") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlinCoroutineVersion") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:$kotlinCoroutineVersion") - implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.2.1") + implementation("org.jetbrains.kotlinx:kotlinx-datetime:$kotlinDateTimeVersion") implementation("com.squareup.retrofit2:retrofit:2.9.0") implementation("com.squareup.retrofit2:adapter-rxjava3:2.9.0") implementation("com.squareup.retrofit2:converter-gson:2.9.0") implementation("com.bennyhuo:portable-android-handler:1.0") implementation("io.reactivex.rxjava3:rxjava:3.0.13") + + implementation("org.apache.logging.log4j:log4j-core:2.14.1") + implementation("org.apache.logging.log4j:log4j-api:2.14.1") implementation(project(":opt-in-sample")) implementation(project(":deprecated-sample")) @@ -50,19 +53,22 @@ dependencies { val compileKotlin: KotlinCompile by tasks compileKotlin.kotlinOptions { - freeCompilerArgs = listOf("-Xopt-in=kotlin.RequiresOptIn", "-Xextended-compiler-checks") - jvmTarget = "16" - useIR = true + freeCompilerArgs = listOf( + "-Xopt-in=kotlin.RequiresOptIn", + "-Xextended-compiler-checks", + "-Xenable-builder-inference" + ) + jvmTarget = "17" } java { - targetCompatibility = JavaVersion.VERSION_16 - sourceCompatibility = JavaVersion.VERSION_16 + targetCompatibility = JavaVersion.VERSION_17 + sourceCompatibility = JavaVersion.VERSION_17 } -tasks.withType().forEach { - it.options.compilerArgs.add("--enable-preview") -} +//tasks.withType().forEach { +// it.options.compilerArgs.add("--enable-preview") +//} tasks.getByName("test") { useJUnitPlatform() diff --git a/code/Kotlin-Sample/buildSrc/src/main/kotlin/Versions.kt b/code/Kotlin-Sample/buildSrc/src/main/kotlin/Versions.kt index 32ab965..d1ec443 100644 --- a/code/Kotlin-Sample/buildSrc/src/main/kotlin/Versions.kt +++ b/code/Kotlin-Sample/buildSrc/src/main/kotlin/Versions.kt @@ -1,2 +1,3 @@ -val kotlinVersion = "1.5.30" -val kotlinCoroutineVersion = "1.5.0" \ No newline at end of file +val kotlinVersion = "1.6.0" +val kotlinCoroutineVersion = "1.6.0-RC" +val kotlinDateTimeVersion = "0.3.1" \ No newline at end of file diff --git a/code/Kotlin-Sample/gradle/wrapper/gradle-wrapper.properties b/code/Kotlin-Sample/gradle/wrapper/gradle-wrapper.properties index 1acc777..fbce071 100644 --- a/code/Kotlin-Sample/gradle/wrapper/gradle-wrapper.properties +++ b/code/Kotlin-Sample/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update16/annotations/Annotations.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update16/annotations/Annotations.kt new file mode 100644 index 0000000..55835e8 --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update16/annotations/Annotations.kt @@ -0,0 +1,36 @@ +package com.bennyhuo.kotlin.update16.annotations + +import kotlin.reflect.full.findAnnotations + +/** + * Created by benny. + */ +annotation class X + +@Target(AnnotationTarget.TYPE_PARAMETER) +annotation class BoxContent + +class Box<@BoxContent T> {} + +@Repeatable +annotation class Tag(val value: String) + +annotation class TagContainer(val value: Array) + +@JvmRepeatable(TagContainer::class) +annotation class Tag1(val value: String) + +@Tag("hello") +@Tag("world") +@Tag("world") +@Tag("world") +@Tag("world") +@Tag("world") +class Abc + +@OptIn(ExperimentalStdlibApi::class) +fun main() { + val x = X() + + Abc::class.findAnnotations(Tag::class).forEach { println(it.value) } +} \ No newline at end of file diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update16/annotations/JavaAnnotationSample.java b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update16/annotations/JavaAnnotationSample.java new file mode 100644 index 0000000..3579ed1 --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update16/annotations/JavaAnnotationSample.java @@ -0,0 +1,56 @@ +package com.bennyhuo.kotlin.update16.annotations; + +import java.lang.annotation.Annotation; +import java.lang.annotation.Repeatable; + +/** + * Created by benny. + */ +public class JavaAnnotationSample { + + public static void main(String[] args) { + SuperAnnotation annotation = new SubAnnotation("HelloWorld"); + System.out.println(annotation.value()[0]); + } + + public @interface SuperAnnotation { + String[] value(); + } + + static class SubAnnotation implements SuperAnnotation { + private String value; + + public SubAnnotation(String value) { + this.value = value; + } + + @Override + public String[] value() { + return new String[]{value}; + } + + @Override + public Class annotationType() { + return SuperAnnotation.class; + } + } + + @Repeatable(Container.class) + public @interface Tag { + String value(); + } + + + public @interface Container { + Tag[] value(); + } + + @Tag("hello") + @Tag("world") + class Abc { + } + + @Container({@Tag("hello"), @Tag("world")}) + class Acb { + } +} diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update16/builderinterfaces/Main.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update16/builderinterfaces/Main.kt new file mode 100644 index 0000000..a2f0c46 --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update16/builderinterfaces/Main.kt @@ -0,0 +1,40 @@ +package com.bennyhuo.kotlin.update16.builderinterfaces + +/** + * Created by benny. + */ +class Container { + fun setValue(value: T) { + + } + + fun getValue(): T = TODO() +} + +fun buildContainer(builder: Container.() -> Unit) { + +} + +fun main() { + buildContainer { + setValue(1) + } + + buildList { + add("Hello") + add("World") + set(1, "World 1") + } + + buildMap { + put("Hello", 1) + } + + buildSet { + add(1) + } + + sequence { + yield(1) + } +} \ No newline at end of file diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update16/sealedwhen/Sample.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update16/sealedwhen/Sample.kt new file mode 100644 index 0000000..00fc575 --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update16/sealedwhen/Sample.kt @@ -0,0 +1,29 @@ +package com.bennyhuo.kotlin.update16.sealedwhen + +/** + * Created by benny. + */ +sealed class Contact { + data class PhoneCall(val number: String) : Contact() + data class TextMessage(val number: String) : Contact() +} + +//fun Contact.messageCost(): Int = +// when (this) { // Error: 'when' expression must be exhaustive +// is Contact.PhoneCall -> 42 +// } + +fun sendMessage(contact: Contact, message: String) { + // Starting with 1.6.0 + + // Warning: Non exhaustive 'when' statements on Boolean will be + // prohibited in 1.7, add 'false' branch or 'else' branch instead + when (message.isEmpty()) { + true -> return + } + // Warning: Non exhaustive 'when' statements on sealed class/interface will be + // prohibited in 1.7, add 'is TextMessage' branch or 'else' branch instead + when (contact) { + is Contact.PhoneCall -> TODO() + } +} \ No newline at end of file diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update16/suspendingtype/SuspendingFunctionType.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update16/suspendingtype/SuspendingFunctionType.kt new file mode 100644 index 0000000..a4086a9 --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update16/suspendingtype/SuspendingFunctionType.kt @@ -0,0 +1,52 @@ +package com.bennyhuo.kotlin.update16.suspendingtype + +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch + +/** + * Created by benny. + */ +class MyClickAction0 : () -> Unit { + override fun invoke() { + } + +} + +class MyClickAction1 : suspend () -> Unit { + override suspend fun invoke() { + TODO() + } +} + +fun launchOnClick(action: suspend () -> Unit) {} + +fun getSuspending(suspending: suspend () -> Unit) {} + +fun suspending() {} + +fun test(regular: () -> Unit) { + getSuspending { } // OK + getSuspending(::suspending) // 1.4 OK + getSuspending(regular) // 1.6 OK + + val x: () -> Unit = { } + val y: suspend () -> Unit = { } + + GlobalScope.launch { + + } + + suspend { + + } +} + +fun main() { + launchOnClick(MyClickAction0()) + launchOnClick(MyClickAction1()) + + val clickAction1: suspend () -> Unit = MyClickAction1() + // val clickAction0: suspend () -> Unit = MyClickAction0() + + val x: suspend () -> Unit = { } +} \ No newline at end of file diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update16/typeinferring/Main.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update16/typeinferring/Main.kt new file mode 100644 index 0000000..c47cddb --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/update16/typeinferring/Main.kt @@ -0,0 +1,40 @@ +package com.bennyhuo.kotlin.update16.typeinferring + +/** + * Created by benny. + */ +abstract class AbsBuilder> { + val self: B = this as B + + private var id: Int? = null + + fun setId(id: Int): B { + this.id = id + return self + } +} + +open class MyBuilder1> : AbsBuilder() { + + private var name: String? = null + + fun setName(name: String): B { + this.name = name + return self + } +} + +class MyBuilder2 : MyBuilder1() { + private var age: Int? = null + + fun setAge(age: Int): MyBuilder2 { + this.age = age + return this + } +} + +fun main() { + MyBuilder1().setId(1).setName("Hello") // error < 1.6 + + MyBuilder2().setId(2).setAge(10) +} \ No newline at end of file From 8d09dd77bb1e41d8fb9b722fb53a52a18d84a116 Mon Sep 17 00:00:00 2001 From: bennyhuo Date: Thu, 10 Feb 2022 22:12:57 +0800 Subject: [PATCH 54/60] 2 --- .../main/java/com/bennyhuo/kotlin/url/Main.kt | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/url/Main.kt diff --git a/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/url/Main.kt b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/url/Main.kt new file mode 100644 index 0000000..673cfe2 --- /dev/null +++ b/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/url/Main.kt @@ -0,0 +1,27 @@ +package com.bennyhuo.kotlin.url + +import okhttp3.HttpUrl + +/** + * Created by benny. + */ +fun appendQuery(url: String, name: String, value: String): String { + val httpUrl = HttpUrl.parse(url)!! + println(httpUrl.fragment()) + if (httpUrl.queryParameter(name) == null) { + return httpUrl.newBuilder().addQueryParameter(name, value) + .build().toString() + } else { + return url + } +} + +fun getUrl(): String { + return "http://local.bennyhuo.com:8000/#/index?c=4" +} + +fun main() { + println(appendQuery("http://www.baidu.com", "a", "1")) + println(appendQuery(getUrl(), "c", "3")) +} + From 5ffd29ffbe906c2c94b183a48488fae5a1269ee2 Mon Sep 17 00:00:00 2001 From: Bennyhuo Date: Fri, 11 Feb 2022 11:37:22 +0800 Subject: [PATCH 55/60] Update README.md --- README.md | 51 ++------------------------------------------------- 1 file changed, 2 insertions(+), 49 deletions(-) diff --git a/README.md b/README.md index 5347d2c..512b51e 100644 --- a/README.md +++ b/README.md @@ -23,56 +23,9 @@ ## 视频清单 -### Kotlin 1.5 相关更新 +为方便编辑,现迁移至 [wolai](https://www.wolai.com/) 页面维护: -Kotlin 1.5 于 2021年5月份发布,主要更新内容其实集中在编译器和工具链上,所以开发者可感知的特性并不多 —— 大概要等 IR 编译器前端稳定了之后才会集中输出一波语法特性的大改动,等吧,那时候大概就是 Kotlin 2.0 了。 - -**Kotlin 语言特性和标准库** - -- [x] [[Kotlin 1.5] Duration:这玩意也能实验这么久?!](https://www.bilibili.com/video/BV1Uh411a7SS/) -- [x] [[Kotlin 1.5] 支持 JvmRecord:Java 开始抄作业了?](https://www.bilibili.com/video/BV1K54y1H7NL/) -- [x] [[Kotlin 1.5] Kotlin 反手一个密封接口?谁抄谁还不一定呢!](https://www.bilibili.com/video/BV1Mw411o7sK/) -- [x] [[Kotlin 1.5] inline(×) value(√) class:换个马甲还是另有所图?](https://www.bilibili.com/video/BV1k54y1H7NT/) -- [ ] [[编程语言引战] 辣鸡 Java,看看人家 C# 的值类型!](https://www.bilibili.com/video/BV15w411o7jq/) 这期视频主要是 Kotlin value class 话题的一个延伸,所以放到这里 - ------- - -**Kotlin 协程** - -- [x] [[Kotlin 协程 1.5] 什么?GlobalScope 竟被废弃了?](https://www.bilibili.com/video/BV1P64y1C7bF/) >>[示例代码](https://github.com/bennyhuo/Kotlin-Tutorials/blob/master/code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/DelicateGlobalScope.kt) -- [x] [[Kotlin 协程 1.5] 越更越惨的 Channel:我 TM 就是个倒霉蛋](https://www.bilibili.com/video/BV1rb4y1d7wL/) >>[示例代码](code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/coroutinesupdate/NewChannelApis.kt) -- [x] [[Kotlin 协程 1.5] Flow 有两个 API 转正:一个是另一个的马甲?](https://www.bilibili.com/video/BV1vg411g7X4/) -- [x] [[Kotlin 协程] 反向操作:怎么把挂起函数转成阻塞函数?](https://www.bilibili.com/video/BV17U4y157Ay/) -- [x] [[Kotlin 协程] 常规操作:怎么把回调转成挂起函数?](https://www.bilibili.com/video/BV13y4y1g7g3/) - - -### [Kotlin 杂谈 (持续更新中)](https://github.com/bennyhuo/Kotlin-Tutorials/issues/35) - -Kotlin 的一些很零碎的内容,放到这个栏目下面。 - -- [x] [[Kotlin 杂谈] SAM 转换遇到包内可见](https://www.bilibili.com/video/BV1wB4y1g79W/) >>[示例代码](code\Kotlin-Sample\src\main\java\com\bennyhuo\kotlin\samissue) -- [x] [[Kotlin 杂谈] 使用协程实现轮询任务竟是这么简单](https://www.bilibili.com/video/BV11b4y1Z7sz/) >>[示例代码](code\Kotlin-Sample\src\main\java\com\bennyhuo\kotlin\scheduledtask) -- [x] [[Kotlin 杂谈] API 要谨慎使用?你可能需要 OptIn 注解!](https://www.bilibili.com/video/BV1Hh411a72d/) >>[示例代码](code\Kotlin-Sample\opt-in-sample) -- [x] [[Kotlin 杂谈] 要废弃 API ?@Deprecated 你学废了吗?](https://www.bilibili.com/video/BV1Mb4y1d7nv/) >>[示例代码](code/Kotlin-Sample/src/main/java/com/bennyhuo/kotlin/deprecated/DeprecatedSample.kt) - -### [工具和技巧](https://github.com/bennyhuo/Kotlin-Tutorials/issues/28) - -- [x] [[一周一个小技巧] 查看字节码,你们都用什么工具?](https://www.bilibili.com/video/BV1jv411H7pX/) -- [x] [httpreq 介绍](https://www.bilibili.com/video/BV1bv41157xH/),该工具可以方便地对接口进行测试 https://httpreq.com/ 制作中 -- [x] [Pipedream 介绍](https://www.bilibili.com/video/BV13h411v7Fr/),该工具实现更复杂的接口调试场景,可以自定义请求结果,还可以把请求数据存起来。 -- [x] [Android Studio 技巧之快捷键](https://www.bilibili.com/video/BV1g64y1279B/) - -### [Gradle 迁移 KTS 系列视频 (2021.4 已完结)](https://github.com/bennyhuo/Kotlin-Tutorials/issues/25) - -前不久开源了一个小项目 [Android-LuaJavax](https://github.com/bennyhuo/Android-LuaJavax),在改造 Gradle 脚本的时候也同时看到群里有不少小伙伴在问 KTS 编写 Gradle 脚本的问题,于是想要做几个视频来介绍下 Gradle 脚本从 Groovy 到 Kotlin 需要掌握哪些内容。 - -- [x] [你的 Gradle脚本究竟是什么?](https://www.bilibili.com/video/BV18K4y1D7Yb/) -- [x] [你的 Gradle 脚本是怎么运行起来的?](https://www.bilibili.com/video/BV1ep4y1h7qU/) -- [x] [Gradle Project 的属性都是哪里来的?](https://www.bilibili.com/video/BV16h411D77Q/) -- [x] [Gradle Task 创建的特殊语法](https://www.bilibili.com/video/BV1ib4y1D74X/) -- [x] [快速迁移 Gradle 脚本至 KTS](https://www.bilibili.com/video/BV1Kf4y1p7zq/) -- [x] [番外:如何调试 Gradle 源码](https://www.bilibili.com/video/BV1m54y1L7vK) -- [x] [如何为 Gradle 的 KTS 脚本添加扩展?](https://www.bilibili.com/video/BV1BU4y1b7Wk/) +* [Kotlin 视频清单](https://www.wolai.com/2uvNjQzPVDiApxKXQJdpSv) ## 联系我 From 6cbf69508097ef10dde97788469aab7083c02113 Mon Sep 17 00:00:00 2001 From: Bennyhuo Date: Mon, 4 Apr 2022 06:46:33 +0800 Subject: [PATCH 56/60] Update README.md --- README.md | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 512b51e..eed69d8 100644 --- a/README.md +++ b/README.md @@ -15,32 +15,19 @@ 所以,作为“布道者”,过去我们总是想着怎么让更多的开发者知道 Kotlin,现在我们则需要提供更多的 Kotlin 的学习材料,来帮助大家更好的使用 Kotlin。 -我目前主要的想法就是做一些视频放到 B 站上(账号:[**bennyhuo 不是算命的**](https://space.bilibili.com/28615855)),当然视频的内容也不限于 Kotlin 本身。这个计划已经开始尝试实施了,内容的规划在这个仓库的 [issue](https://github.com/bennyhuo/Kotlin-Tutorials/issues) 当中跟进,例如前不久刚刚录制的几个 [Gradle 迁移 KTS 的视频](https://github.com/bennyhuo/Kotlin-Tutorials/issues/25)。 +我目前主要的想法就是做一些视频放到 B 站上(账号:[**bennyhuo 不是算命的**](https://space.bilibili.com/28615855)),当然视频的内容也不限于 Kotlin 本身。 -还有一个相对长期的规划是做一套电子书,后面会在这个 [issue](https://github.com/bennyhuo/Kotlin-Tutorials/issues/36) 当中跟进,电子书的主体内容与我之前的课程 [Kotlin 从入门到精通 视频教程](http://coding.imooc.com/class/398.html) 会有一定程度上的重叠,但电子书的好处就是更新维护方便,相比之下视频教程制作成本太高且不易维护。 +有想法的小伙伴欢迎与我交流,也欢迎加入**催更群:619509258**一起讨论。 -有想法的小伙伴欢迎与我交流,也欢迎加入**催更群:966752510**一起讨论。 +## 内容清单 -## 视频清单 - -为方便编辑,现迁移至 [wolai](https://www.wolai.com/) 页面维护: - -* [Kotlin 视频清单](https://www.wolai.com/2uvNjQzPVDiApxKXQJdpSv) +内容清单已迁移至我的个人主页:[Benny Huo 的专栏](https://www.bennyhuo.com/book/)。 ## 联系我 * 邮箱: [bennyhuo@kotliner.cn](mailto:bennyhuo@kotliner.cn) * B 站账号:[**bennyhuo 不是算命的**](https://space.bilibili.com/28615855),我的个人视频会优先在 B 站发布 -* 微信公众号 **Kotlin**,公众号主要用来发布 Kotlin 以及移动端开发相关的内容。 - - -* 加入社区 QQ 群 - * Kotlin 中文社区群 大群:162452394 (已满) - * Kotlin 中文社区群 ① 群:603441485 (已满) - * Kotlin 中文社区群 ② 群:751395597 - -* 当然,**北京猿辅导**的小伙伴也可以找我面聊 :) - +* 微信公众号 **bennyhuo** --- 以下是过去几年我的一些积累和产出,有兴趣可以关注。 From 0d63cd4bd0f94c251a184957d1df572e069ee7c9 Mon Sep 17 00:00:00 2001 From: Bennyhuo Date: Mon, 4 Apr 2022 07:34:28 +0800 Subject: [PATCH 57/60] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index eed69d8..22a5bc5 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ 我目前主要的想法就是做一些视频放到 B 站上(账号:[**bennyhuo 不是算命的**](https://space.bilibili.com/28615855)),当然视频的内容也不限于 Kotlin 本身。 -有想法的小伙伴欢迎与我交流,也欢迎加入**催更群:619509258**一起讨论。 +有想法的小伙伴欢迎与我交流,也欢迎加入**催更 QQ 群:619509258** 一起讨论,或者也可以加微信群,请先添加微信好友 **bennyhuo007**,暗号“**好家伙**”,我拉你进群 ## 内容清单 From d9f47578d95b5fa30b8c75d4190da17c2b53fe0c Mon Sep 17 00:00:00 2001 From: Benny Huo Date: Thu, 12 Oct 2023 15:36:09 +0800 Subject: [PATCH 58/60] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 22a5bc5..06a164f 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ 我目前主要的想法就是做一些视频放到 B 站上(账号:[**bennyhuo 不是算命的**](https://space.bilibili.com/28615855)),当然视频的内容也不限于 Kotlin 本身。 -有想法的小伙伴欢迎与我交流,也欢迎加入**催更 QQ 群:619509258** 一起讨论,或者也可以加微信群,请先添加微信好友 **bennyhuo007**,暗号“**好家伙**”,我拉你进群 +有想法的小伙伴欢迎与我交流,也欢迎加微信群,请先添加微信好友 **bennyhuo007**,暗号“**好家伙**”,我拉你进群 ## 内容清单 From 03dec3fd0aa7de430e5dec15b6326a644b0e57f6 Mon Sep 17 00:00:00 2001 From: Benny Huo Date: Thu, 12 Oct 2023 15:37:43 +0800 Subject: [PATCH 59/60] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 06a164f..c32c4d8 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ * [蓝鲸 CI 平台](https://github.com/Tencent/bk-ci),这是一个后端项目,在腾讯内部已经成为公司主推的 CI 平台,之前我在上面做持续集成时需要做插件开发,惊喜地发现打印出来的调用堆栈居然有 Kotlin 身影。 * 内部还有团队使用 KMM 做跨平台的 UI 控件渲染,这可以说是非常有挑战的工作了,不仅要在移动端支持 Android、iOS,还要同时支持桌面版。基于这个框架所属产品的体量,我们大概率已经是这套技术方案的用户了。 -今年初我因个人原因离开了鹅厂,去了[北京猿力教育科技有限公司(猿辅导)](https://www.yuanfudao.com/),不出所料,在这家号称**小而美**且**有技术追求**的公司当中,Kotlin 在项目上的应用已经相当广泛了,新代码很少能见到 Java 的身影(有需要内推的小伙伴可以找我)。 +今年初我因个人原因离开了鹅厂,去了[北京猿力科技有限公司(猿辅导/看云集团)](https://www.kanyun.com/),不出所料,在这家号称**小而美**且**有技术追求**的公司当中,Kotlin 在项目上的应用已经相当广泛了,新代码很少能见到 Java 的身影(有需要内推的小伙伴可以找我)。 所以,作为“布道者”,过去我们总是想着怎么让更多的开发者知道 Kotlin,现在我们则需要提供更多的 Kotlin 的学习材料,来帮助大家更好的使用 Kotlin。 From b5fde39a472a7a2ddcc3f4d6e2ae5dc6c48bad07 Mon Sep 17 00:00:00 2001 From: Benny Huo Date: Fri, 3 Nov 2023 16:45:12 +0800 Subject: [PATCH 60/60] Update README.md --- README.md | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c32c4d8..b58db0c 100644 --- a/README.md +++ b/README.md @@ -32,22 +32,37 @@ 以下是过去几年我的一些积累和产出,有兴趣可以关注。 +## [《深入实践 Kotlin 元编程》](https://www.bennyhuo.com/project/kotlin-metaprogramming.html) 2023.9 出版 + +这是一本从基础知识、设计思想、技术方案、应用方法、实践技巧5个维度系统讲解Kotlin元编程,并以此大幅提升Kotlin工程师开发水平、研发效率和开发体验的著作。 + +本书的出版打破了元编程技术资料少、门槛高的行业现状。本书包含大量案例,这些案例大多来自真实的生产实践,相对成熟和完善,可以作为元编程项目的范本。同时,本书提供大量的代码,为了提升阅读体验,在注释、书写和排版等方面对代码做了精心的优化。 + +## 随书源码 + +本书**源码地址**:[《深入实践 Kotlin 元编程》源码](https://github.com/bennyhuo/KotlinMetaProgrammingInAction-Sources) + +## 购买途径 + +* 京东自营:[深入实践 Kotlin 元编程](https://item.jd.com/14097194.html) +* 当当自营:[深入实践 Kotlin 元编程](https://product.dangdang.com/29613442.html) + ## [《深入理解 Kotlin 协程》](https://www.bennyhuo.com/project/kotlin-coroutines.html) 2020.6 出版 Kotlin 协程可以说是截止目前为止 Kotlin 中最让人困惑的一部分内容了,官方文档也比较简略,对于初学者不够友好。今年我把过去在公众号和博客发布的协程相关的文章进行了整理和扩充,进一步完善了诸多细节编写了本书,有兴趣可以留意一下。 ### 随书源码 -本书**源码地址**:[《深入理解 Kotlin 协程》源码](https://github.com/enbandari/DiveIntoKotlinCoroutines-Sources) +本书**源码地址**:[《深入理解 Kotlin 协程》源码](https://github.com/bennyhuo/DiveIntoKotlinCoroutines-Sources) ### 购买途径 * 京东自营:[深入理解Kotlin协程](https://item.jd.com/12898592.html) * 当当自营:[深入理解Kotlin协程](http://product.dangdang.com/28973005.html) -## [注解处理器开发教程](https://github.com/enbandari/Apt-Tutorials) +## [注解处理器开发教程](https://github.com/bennyhuo/Apt-Tutorials) -我在做 [基于 GitHub App 业务深度讲解 Kotlin1.2高级特性与框架设计](https://coding.imooc.com/class/232.html)(目前已经下线) 这门课的时候,顺便做了一个注解处理器的框架,叫 [Tieguanyin(铁观音)](https://github.com/enbandari/TieGuanYin),这个框架主要是用来解决 Activity 跳转时传参的问题,我们知道 Activity 如果需要参数,那么我们只能非常繁琐的使用 `Intent` 来传递,有了这个框架我们就可以省去这个麻烦的步骤。 +我在做 [基于 GitHub App 业务深度讲解 Kotlin1.2高级特性与框架设计](https://coding.imooc.com/class/232.html)(目前已经下线) 这门课的时候,顺便做了一个注解处理器的框架,叫 [Tieguanyin(铁观音)](https://github.com/bennyhuo/TieGuanYin),这个框架主要是用来解决 Activity 跳转时传参的问题,我们知道 Activity 如果需要参数,那么我们只能非常繁琐的使用 `Intent` 来传递,有了这个框架我们就可以省去这个麻烦的步骤。 在这里,框架的内容其实不是重点,重点是,它是一个注解处理器的项目。为了让它的作用尽可能的放大,我对原框架做了简化,做了这套课程。