├── .gitignore ├── README.md ├── articles ├── 2016.12.26 Kotlin 如何优雅的实现『多继承』.md ├── 2016.12.26.jpg ├── 2017.1.16 │ ├── cover.jpg │ └── 用 Kotlin 写 Android 01 难道只有环境搭建这么简单?.md ├── 2017.1.2 │ ├── 17.1.2.jpg │ ├── 17.1.2b.jpg │ ├── Kotlin 1.0.6.md │ ├── args.gif │ ├── try.gif │ └── 像写文章一样使用 Kotlin.md ├── 2017.1.21 │ ├── 1.1-Beta-Banner-2-01.png │ ├── check.png │ ├── choose.png │ ├── houzi.png │ └── 喜大普奔!Kotlin 1.1 Beta 降临~.md ├── 2017.1.23 │ ├── [用 Kotlin 写 Android] 02 说说 Anko.md │ ├── cover.jpg │ ├── linear.png │ └── relative.png ├── 2017.1.30 │ ├── coroutine_cover.jpg │ ├── coroutine_lua.png │ ├── cr0.png │ ├── cr1.png │ ├── cr2.png │ ├── mdhere.gif │ ├── 勘误:15 Kotlin 与 Java 共存 (2) .md │ ├── 如何优雅的在微信公众号中编辑代码.jpg │ ├── 如何优雅的在微信公众号中编辑代码.md │ └── 深入理解 Kotlin Coroutine.md ├── 2017.1.9 │ ├── action.gif │ ├── array.jpg │ ├── comment.gif │ ├── comment2.gif │ ├── comment3.gif │ ├── enter.gif │ ├── findaction.png │ ├── intellij.jpg │ ├── iter_smart.gif │ ├── iter_stupid.gif │ ├── livetemplate.png │ ├── lt10.png │ ├── lt11.png │ ├── lt12.png │ ├── lt13.png │ ├── lt14.png │ ├── lt15.png │ ├── lt2.png │ ├── lt3.png │ ├── lt4.png │ ├── lt5.png │ ├── lt6.png │ ├── lt8.png │ ├── lt9.png │ ├── main.gif │ ├── multiline.gif │ ├── multiline2.gif │ ├── multiline_action.png │ ├── newline.gif │ ├── newline2.gif │ ├── newline3.gif │ ├── newline_action.png │ ├── posix.png │ ├── search.png │ ├── search2.png │ ├── swap_action.png │ ├── swap_fun.gif │ ├── swap_smart.gif │ ├── swap_stupid.gif │ ├── tab.gif │ ├── 为什么不直接使用 Array 而是 IntArray ?.md │ └── 高效地使用你的 IntelliJ.md ├── 2017.2.13 │ ├── lambda.jpg │ └── 细说 Lambda 表达式.md ├── 2017.2.20 │ ├── 11RC-01.png │ ├── Kotlin 1.1:我们都路上.md │ ├── cover.jpg │ ├── embarassed.png │ ├── growup.png │ ├── high_order_fun.jpg │ ├── right.jpg │ ├── road.JPG │ ├── wangzhe.jpg │ ├── zhiyin.jpg │ └── 高阶函数(一).md ├── 2017.2.27 │ └── 高阶函数(二).md ├── 2017.2.6 │ ├── Kotlin 1.1 Beta 2 发布~.jpg │ ├── Kotlin 1.1 Beta 2 发布~.md │ └── 深入理解 Kotlin coroutine (二).md ├── 2017.3.13 │ ├── Kotlin Script 介绍.jpg │ ├── Kotlin Script 介绍.md │ ├── 快速上手 Kotlin 11招.jpg │ └── 快速上手 Kotlin 11招.md ├── 2017.3.20 │ ├── cover.jpg │ └── wechat_group.jpg ├── 2017.3.27 │ ├── Kotlin 遇到 MyBatis:到底是 Int 的错,还是 data class 的错?.md │ └── cover.jpg ├── 2017.3.4 │ ├── Kotlin 1.1.md │ └── Kotlin11blogbanner1.jpg └── 2017.4.3 │ └── Kotlin 兼容 Java 遇到的最大的坑 .md ├── arts ├── Kotlin-logo.png ├── Kotlin.jpg ├── contributes.jpg ├── e_group.png └── kotlin扫码关注.png ├── code ├── Kt01 │ └── src │ │ └── net │ │ └── println │ │ └── kt01 │ │ └── Main.kt ├── Kt02 │ └── src │ │ └── net │ │ └── println │ │ └── kt02 │ │ └── Main.kt ├── Kt03 │ ├── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle │ └── src │ │ └── main │ │ ├── java │ │ └── net │ │ │ └── println │ │ │ └── kt03 │ │ │ ├── Hello.java │ │ │ ├── HelloJava.kt │ │ │ └── HelloKotlin.kt │ │ └── kotlin │ │ └── net │ │ └── println │ │ └── kt03 │ │ └── User.kt ├── Kt04 │ ├── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle │ └── src │ │ └── main │ │ └── java │ │ └── net │ │ └── println │ │ └── kt04 │ │ ├── ConsoleParam.kt │ │ └── ConsoleParamInJava.java ├── Kt05 │ ├── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle │ └── src │ │ └── main │ │ └── java │ │ └── net │ │ └── println │ │ └── kt05 │ │ ├── ConsoleParam2.kt │ │ └── ConsoleParamInJava.java ├── Kt06 │ ├── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle │ └── src │ │ └── main │ │ └── java │ │ └── net │ │ └── println │ │ └── kt06 │ │ ├── EnumInJava.java │ │ ├── Main.java │ │ └── SayHello.kt ├── Kt08 │ ├── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle │ └── src │ │ └── main │ │ └── java │ │ └── net │ │ └── println │ │ └── kt08 │ │ ├── Service.kt │ │ └── User.kt ├── Kt09 │ ├── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ └── src │ │ └── main │ │ └── java │ │ └── net │ │ └── println │ │ └── kt09 │ │ └── Tailrec.kt ├── Kt10 │ ├── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle │ └── src │ │ └── main │ │ ├── java │ │ └── net │ │ │ └── println │ │ │ └── kt10 │ │ │ └── java │ │ │ ├── LazyNotThreadSafe.java │ │ │ ├── LazyThreadSafeDoubleCheck.java │ │ │ ├── LazyThreadSafeStaticInnerClass.java │ │ │ ├── LazyThreadSafeSynchronized.java │ │ │ └── PlainOldSingleton.java │ │ └── kotlin │ │ └── net │ │ └── println │ │ └── kt10 │ │ └── kotlin │ │ ├── LazyNotThreadSafe.kt │ │ ├── LazyThreadSafeDoubleCheck.kt │ │ ├── LazyThreadSafeStaticInnerObject.kt │ │ ├── LazyThreadSafeSynchronized.kt │ │ └── PlainOldSingleton.kt ├── Kt11 │ ├── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle │ └── src │ │ └── main │ │ └── kotlin │ │ └── net │ │ └── println │ │ └── kt11 │ │ ├── Main.kt │ │ ├── Player.kt │ │ ├── PlayerCmd.kt │ │ └── State.kt ├── Kt12 │ ├── Program.cs │ ├── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── result_singer.json │ ├── result_singer_field_loss.json │ ├── result_songs.json │ ├── settings.gradle │ ├── singer.json │ └── src │ │ └── main │ │ ├── java │ │ └── net │ │ │ └── println │ │ │ └── kt12 │ │ │ └── Main.java │ │ └── kotlin │ │ └── net │ │ └── println │ │ └── kt12 │ │ ├── Api.kt │ │ ├── Data.kt │ │ ├── GsonExt.kt │ │ └── Main.kt ├── Kt13 │ ├── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle │ └── src │ │ └── main │ │ └── kotlin │ │ └── net │ │ └── println │ │ └── kt13 │ │ ├── RESTFulComponent.kt │ │ ├── Service.kt │ │ ├── User.kt │ │ ├── config │ │ └── Settings.kt │ │ └── module │ │ ├── BaseUrlModule.kt │ │ ├── CacheModule.kt │ │ ├── GsonConverterModule.kt │ │ ├── GsonModule.kt │ │ ├── OkHttpClientModule.kt │ │ ├── RetrofitModule.kt │ │ └── RxAdapterModule.kt ├── Kt14 │ ├── Kt14 │ │ ├── build.gradle │ │ └── src │ │ │ └── main │ │ │ ├── java │ │ │ └── net │ │ │ │ └── println │ │ │ │ └── kt14 │ │ │ │ ├── AccessToObject.java │ │ │ │ ├── AccessToOverloads.java │ │ │ │ ├── CallExtenstionMethod.java │ │ │ │ ├── CallInternalClass.java │ │ │ │ ├── CallPackageMethod.java │ │ │ │ └── PersonMain.java │ │ │ └── kotlin │ │ │ └── net │ │ │ └── println │ │ │ └── kt14 │ │ │ ├── CallInternalClass.kt │ │ │ ├── ExtensionMethod.kt │ │ │ ├── InternalClass.kt │ │ │ ├── Overloads.kt │ │ │ ├── Package.kt │ │ │ ├── Person.kt │ │ │ └── Singleton.kt │ ├── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── kt14internal │ │ ├── build.gradle │ │ └── src │ │ │ └── main │ │ │ ├── java │ │ │ └── net │ │ │ │ └── println │ │ │ │ └── kt14internal │ │ │ │ └── CallInternalClass.java │ │ │ └── kotlin │ │ │ └── net │ │ │ └── println │ │ │ └── kt14internal │ │ │ └── CallInternalClassKt.kt │ └── settings.gradle ├── Kt15 │ ├── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle │ └── src │ │ └── main │ │ ├── java │ │ └── net │ │ │ └── println │ │ │ └── kt15 │ │ │ ├── DataClass.java │ │ │ ├── Generics.java │ │ │ ├── NullSafetyAbsClass.java │ │ │ ├── NullSafetyJava.java │ │ │ └── SAMInJava.java │ │ └── kotlin │ │ └── net │ │ └── println │ │ └── kt15 │ │ ├── AccessDataClass.kt │ │ ├── ConcurrentRelated.kt │ │ ├── GenericsInKt.kt │ │ ├── NullSafety.kt │ │ ├── NullSafetySubClass.kt │ │ └── SAMConversion.kt ├── MyBatisIssue │ ├── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── libs │ │ └── mysql-connector-java-5.1.40-bin.jar │ ├── settings.gradle │ └── src │ │ └── main │ │ ├── kotlin │ │ └── net │ │ │ └── println │ │ │ └── kotlin │ │ │ └── mybatis │ │ │ ├── Main.java │ │ │ ├── Main.kt │ │ │ ├── TestUnsafe.kt │ │ │ ├── User.kt │ │ │ ├── UserMapper.java │ │ │ └── annotations │ │ │ └── PoKo.kt │ │ └── resources │ │ └── net │ │ └── println │ │ └── kotlin │ │ └── mybatis │ │ ├── UserMapper.xml │ │ ├── config.xml │ │ ├── db.properties │ │ └── userinfo.sql ├── RealmIssue │ ├── .gitignore │ ├── app │ │ ├── .gitignore │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ └── src │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ └── net │ │ │ │ └── println │ │ │ │ └── kotlin │ │ │ │ └── realm │ │ │ │ ├── App.kt │ │ │ │ ├── MainActivity.kt │ │ │ │ ├── PoKo.kt │ │ │ │ └── User.kt │ │ │ └── res │ │ │ ├── layout │ │ │ └── activity_main.xml │ │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ └── values │ │ │ ├── colors.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ └── settings.gradle └── kt07 │ ├── build.gradle │ ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle │ └── src │ └── main │ ├── Resources │ └── input │ └── java │ └── net │ └── println │ └── kt07 │ └── Lambda.kt └── script ├── 14 Kotlin 与 Java 共存(1).md ├── 15 Kotlin 与 Java 共存 (2).md ├── Kt01 简介.pptx ├── Kt12 解析Json数据.key ├── Kt12 面向对象的几个概念.key └── Kt14 Kotlin 与 Java 共存(一).potx /.gitignore: -------------------------------------------------------------------------------- 1 | videos 2 | build 3 | .gradle 4 | *.iml 5 | .idea 6 | out 7 | raw 8 | cache 9 | beta -------------------------------------------------------------------------------- /articles/2016.12.26 Kotlin 如何优雅的实现『多继承』.md: -------------------------------------------------------------------------------- 1 | Hi,Kotliners,尽管视频完结了,不过每周一我还是会给大家推送一些 Kotlin 的有意思的话题,如果大家对视频有兴趣,直接点击阅读原文就可以找到~ 2 | 3 | [Kotlin 从入门到『放弃』视频教程](https://github.com/enbandari/Kotlin-Tutorials) 4 | 5 | -- 6 | 7 | 这一期给大家讲一个有意思的东西。我们都知道 Java 当年高调的调戏 C++ 的时候,除了最爱说的内存自动回收之外,还有一个著名的单继承,任何 Java 类都是 Object 的子类,任何 Java 类有且只有一个父类,不过,它们可以有多个接口,就像这样: 8 | 9 | ```java 10 | public class Java extends Language implements JVMRunnable{ 11 | ... 12 | } 13 | 14 | public class Kotlin extends Language implements JVMRunnable, FERunnable{ 15 | ... 16 | } 17 | 18 | ``` 19 | 20 | 这样用起来真的比 C++ 要简单得多,不过有时候也会有些麻烦:Java 和 Kotlin 都可以运行在 JVM 上面,我们用一个接口 JVMRunnable 来标识它们的这一身份;现在我们假设这二者对于 JVMRunnable 接口的实现都是一样的,所以我们将会在 Java 和 Kotlin 当中写下两段重复的代码: 21 | 22 | ```java 23 | public class Java extends Language implements JVMRunnable{ 24 | public void runOnJVM(){ 25 | ... 26 | } 27 | } 28 | 29 | public class Kotlin extends Language implements JVMRunnable, FERunnable{ 30 | public void runOnJVM(){ 31 | ... 32 | } 33 | public void runOnFE(){ 34 | ... 35 | } 36 | } 37 | ``` 38 | 39 | 重复代码使我们最不愿意看到的,所以我们决定创建一个 JVMLanguage 作为 Java 和 Kotlin 的父类,它提供默认的 runOnJVM 的实现。看上去挺不错。 40 | 41 | ```java 42 | public abstract class JVMLanguage{ 43 | public void runOnJVM(){ 44 | ... 45 | } 46 | } 47 | 48 | public class Java extends JVMLanguage{ 49 | 50 | } 51 | 52 | public class Kotlin extends JVMLanguage implements FERunnable{ 53 | public void runOnFE(){ 54 | ... 55 | } 56 | } 57 | ``` 58 | 59 | 当然,我们还知道 Kotlin 可以编译成 Js 运行,那我们硬生生的把 Kotlin 称作 JVMLanguage 就有些牵强了,而刚刚我们觉得很完美的写法呢,其实是不合适的。 60 | 61 | 简单的说,继承和实现接口的区别就是:继承描述的是这个类『是什么』的问题,而实现的接口则描述的是这个类『能做什么』的问题。 62 | 63 | Kotlin 与 Java 在能够运行在 JVM 这个问题上是一致的,可 Java 却不能像 Kotlin 那样去运行在前端,Kotlin 和 Java 运行在 JVM 上这个点只能算作一种能力,而不能对其本质定性。 64 | 65 | 于是我们在 Java 8 当中看到了接口默认实现的 Feature,于是我们的代码可以改改了: 66 | 67 | ```java 68 | public interface JVMRunnable{ 69 | default void runOnJVM(){ 70 | ... 71 | } 72 | } 73 | 74 | public class Java extends Language implements JVMRunnable{ 75 | 76 | } 77 | 78 | public class Kotlin extends Language implements JVMRunnable, FERunnable{ 79 | public void runOnFE(){ 80 | ... 81 | } 82 | } 83 | ``` 84 | 85 | 这样很好,不过,由于接口无法保存状态,runOnJVM 这个方法的接口级默认实现仍然非常受限制。 86 | 87 | 那么 Kotlin 给我们带来什么呢?大家请看下面的代码: 88 | 89 | ```kotlin 90 | abstract class Language 91 | 92 | interface JVMRunnable{ 93 | fun runOnJVM() 94 | } 95 | 96 | class DefaultJVMRunnable : JVMRunnable { 97 | override fun runOnJVM() { 98 | println("running on JVM!") 99 | } 100 | } 101 | 102 | class Java(jvmRunnable: JVMRunnable) : Language(), JVMRunnable by jvmRunnable 103 | class Kotlin(jvmRunnable: JVMRunnable) : Language(), JVMRunnable by jvmRunnable, FERunnable{ 104 | fun runOnFE(){ 105 | ... 106 | } 107 | } 108 | ``` 109 | 通过接口代理的方式,我们把 JVMRunnable 的具体实现代理给了 jvmRunnable 这个实例,这个实例当然是可以保存状态的,它一方面可以很好地解决我们前面提到的接口默认实现的问题,另一方面也能在提供能力的同时不影响原有类的『本质』。 110 | -------------------------------------------------------------------------------- /articles/2016.12.26.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2016.12.26.jpg -------------------------------------------------------------------------------- /articles/2017.1.16/cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.16/cover.jpg -------------------------------------------------------------------------------- /articles/2017.1.2/17.1.2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.2/17.1.2.jpg -------------------------------------------------------------------------------- /articles/2017.1.2/17.1.2b.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.2/17.1.2b.jpg -------------------------------------------------------------------------------- /articles/2017.1.2/Kotlin 1.0.6.md: -------------------------------------------------------------------------------- 1 | # Kotlin 1.0.6 2 | 3 | > 我把所有文章和视频都放到了 [Github](https://github.com/enbandari/Kotlin-Tutorials) 上 ,如果你喜欢,请给个 Star,谢谢~ 4 | 5 | 在上周二,Kotlin 1.0.6 发布啦!这次更新主要是工具更新和bug修复。本文的内容主要来自[官方博客](https://blog.jetbrains.com/kotlin/)。 6 | 7 | ## IDE 插件的更新 8 | 9 | * 1. try-finally 转换为 use() 10 | 11 | 通常我们在进行 IO 操作的时候,我们并不希望异常影响我们程序的执行,所以我们需要对异常进行捕获,但捕获的话我们也没有必要处理,所以写下来的就是下面的形式: 12 | 13 | ```kotlin 14 | try{ 15 | ... do something with "reader" ... 16 | }finally{ 17 | reader.close() 18 | } 19 | ``` 20 | 但这样写起来是不是非常的不流畅?如果用 use() 的话,简直一气呵成: 21 | 22 | ```kotlin 23 | reader.use{ 24 | reader -> ... do something with "reader" ... 25 | } 26 | ``` 27 | 28 | 所以,这次更新 Kotlin 的插件为我们带来了这样的自动转换功能: 29 | 30 | ![](try.gif) 31 | 32 | * 2. 补全具名参数 33 | 34 | 通常我们在编写代码的时候,函数入参都会按照顺序一个一个传入,不过随着代码量的增加,特别是对于参数较多的函数,一长串的代码看上去会让我们感到非常的头疼。所以,这次更新 Kotlin 还为我们带来了自动补全具名参数的功能。 35 | 36 | ![](args.gif) 37 | 38 | * 3. 删除空构造方法的声明 39 | * 4. 合并声明和赋值 40 | * 5. inline 函数的问题修复和调试工具的优化 41 | * 6. 提示、KDoc 和 Quick Doc 相关的较多问题的修复 42 | 43 | ## Android 相关更新 44 | 45 | * 支持 Android Studio 2.3 beta 1 和 Android Gradle Plugin 2.3.0-alpha3及更新的版本 46 | * 增加 “Create XML resource” 的提示 47 | * Android Extensions support 这个功能可以让我们很方便的引用 XML 布局的 View,不过这需要我们主动启用 'kotlin-android-extensions' 才行。在过去,即使不启用这个插件,IDE 也会允许我们直接引用 XML 布局的 View,但这并不能正常编译,所以这次更新修复了这个问题:只有启用了这个插件,IDE 才会允许我们引用对应的 View。 48 | * Android Lint 相关的问题修复。 49 | * 增加 Suppress Lint 提示。 50 | 51 | ## Kapt 优化 52 | 53 | 尽管还不能完全支持增量编译,相比 1.0.4,这次更新较大的提升了 Kapt 的性能。如果需要启用 Kapt,请在 gradle 当中启动它:```apply plugin: 'kotlin-kapt'``` 54 | 55 | ## All-open 插件 56 | 57 | 我们知道 Kotlin 的所有类及其成员默认情况下都是 final 的,也就是说你想要继承一个类,就要不断得写各种 open。刚开始看到这一特性的时候,觉得很赞,它对培养良好的编码意识非常有帮助,不过它也在某些情况下给我们带来麻烦,比如在一些大量依赖继承和覆写的 Java 框架的使用中。 58 | 59 | 这一次 Kotlin 提供了一个妥协的办法,主要某个类被某一个特定注解标注,那么这个类就默认所有成员通通 open,省得一个一个写了。有关 allopen 的讨论,大家可以参考这里 [KEEP](https://github.com/Kotlin/KEEP/pull/40)。 60 | 61 | 那么 allopen 如何使用呢? 62 | 63 | ```groovy 64 | buildscript { 65 | dependencies { 66 | classpath "org.jetbrains.kotlin:kotlin-allopen:$kotlin_version" 67 | } 68 | } 69 | 70 | apply plugin: "kotlin-allopen" 71 | 72 | allOpen { 73 | annotation("com.your.Annotation") 74 | } 75 | 76 | buildscript { 77 | dependencies { 78 | classpath "org.jetbrains.kotlin:kotlin-allopen:$kotlin_version" 79 | } 80 | } 81 | 82 | apply plugin: "kotlin-allopen" 83 | 84 | allOpen { 85 | annotation("com.your.Annotation") 86 | } 87 | ``` 88 | 89 | 那么所有被 com.your.Annotation 这个注解标注的类成员都会默认 open。除此之外,它还可以作为元注解使用: 90 | 91 | ```groovy 92 | @com.your.Annotation 93 | annotation class MyFrameworkAnnotation 94 | 95 | @MyFrameworkAnnotation 96 | class MyClass // will be all-open 97 | ``` 98 | 99 | Kotlin 还提供了 "kotlin-spring" 插件,其中包含了 spring 相关的所有注解,这样免得我们一个一个在 allopen 的配置中声明了。 100 | 101 | ## No-arg 插件 102 | 103 | 如果大家看过我的视频,一定对我之前提到的“毁三观”的实例化有印象吧,附上[视频连接:12 Json数据引发的血案](https://github.com/enbandari/Kotlin-Tutorials),其中我们提到对于没有无参构造方法的 Kotlin 类,Gson 反序列化它们的时候,不知道如何实例化它们,只好用到了 ```Unsafe``` 这个类。听说 Java 9 要移除这个略显黑科技的类,如果是这样,Gson 是不是会被削弱呢?Java 的心我们还是不操了,从 Kotlin 1.0.6 开始,这个问题将得到一个比较好的解决。 104 | 105 | ```groovy 106 | buildscript { 107 | dependencies { 108 | classpath "org.jetbrains.kotlin:kotlin-noarg:$kotlin_version" 109 | } 110 | } 111 | 112 | // Or "kotlin-jpa" for the Java Persistence API support 113 | apply plugin: "kotlin-noarg" 114 | 115 | noArg { 116 | annotation("com.your.Annotation") 117 | } 118 | ``` 119 | 120 | 类似于 allopen 的使用方法,如果某个类需要无参默认构造方法,你只需要用上面声明好的注解 com.your.Annotation 标注即可。当然,这个生成的默认构造方法只能通过反射调用。 121 | 122 | ## 如何更新 123 | 124 | 我一直觉得虽然我们出生就被选择了 Hard 模式,但我们没啥感觉啊。可是最近一直访问国外的网站,感觉真的好困难,宽带换成了电信 100M,下载 Kotlin 的插件仍然跟小水管一样,真也是没谁了。为了方便大家我把我下载的几个版本的插件放到[百度网盘](https://pan.baidu.com/s/1pLbb2fp),供大家使用,请大家点击阅读原文获取下载地址。 125 | 126 | ## 小结 127 | 128 | 目前 Kotlin 1.0.x 的版本更新更侧重于稳定性和易用性,因此语言上的特性基本不会更新,主要集中于 IDE 插件和编译器插件。如果大家期待语言特性的更新,那我们就去关注一下 1.1 吧! 129 | 130 | -------------------------------------------------------------------------------- /articles/2017.1.2/args.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.2/args.gif -------------------------------------------------------------------------------- /articles/2017.1.2/try.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.2/try.gif -------------------------------------------------------------------------------- /articles/2017.1.2/像写文章一样使用 Kotlin.md: -------------------------------------------------------------------------------- 1 | # 像写文章一样使用 Kotlin 2 | 3 | > 我把所有文章和视频都放到了 [Github](https://github.com/enbandari/Kotlin-Tutorials) 上 ,如果你喜欢,请给个 Star,谢谢~ 4 | 5 | ## 运算符重载 6 | 7 | 不知道大家有没有看到过下面的函数调用: 8 | 9 | ``` python 10 | print "Hello World" 11 | ``` 12 | 13 | 这样的感觉就好像在写文章,没有括号,让语言的表现力进一步增强。Groovy 和 Scala 就有这样的特性,那么 Kotlin 呢? 14 | 15 | ```kotlin 16 | for(i in 0..10){ 17 | ... 18 | } 19 | ``` 20 | 21 | 如果你在 Kotlin 中写下了这样的代码,你可能觉得很自然,不过你有没有想过 0..10 究竟是个什么? 22 | 23 | “是个 IntRange 啊,这你都不知道。”你一脸嫌弃的回答道。 24 | 25 | 是啊,确实是个 IntRange,不过为什么是 0..10 返回个 IntRange,而不是 0->10 呢? 26 | 27 | “我靠。。这是出厂设定,懂不懂。。”你开始变得更嫌弃了。。 28 | 29 | 额,其实我想说的是,你知不知道这其实是个运算符重载?! 30 | 31 | ```kotlin 32 | public final operator 33 | fun rangeTo(other: kotlin.Int) 34 | : kotlin.ranges.IntRange { 35 | ... 36 | } 37 | ``` 38 | 没错,Kotlin 允许我们对运算符进行重载,所以你甚至可以给 String 定义 rangeTo 方法。 39 | 40 | ## 去掉方法的括号 41 | 42 | “毕竟运算符是有限的吧?如果说我想给 Person 增加个 say 方法,不带括号那种,怎么办?” 你不以为然地说。 43 | 44 | 这个嘛。。当然也是可以哒! 45 | 46 | ```kotlin 47 | class Person(val name: String){ 48 | infix fun 说(word: String){ 49 | println("\"$name 说 $word\"") 50 | } 51 | } 52 | 53 | fun main(args: Array) { 54 | val 老张 = Person("老张") 55 | 老张 说 "小伙砸,你咋又调皮捏!" 56 | } 57 | ``` 58 | 59 | 这段代码执行结果是: 60 | 61 | ``` 62 | 老张 说 "小伙砸,你咋又调皮捏!" 63 | ``` 64 | 65 | 这个看上去有有点儿意思不?代码跟输出是一样滴!有人会说,中文变量和函数名真的大丈夫?是滴,全然大丈夫,这是因为 Java、Kotlin 的字节码都采用 Unicode,中文确实是可以的——不过,Java 还支持中文包名和文件名,这在 Kotlin 当中还是有些问题的。 66 | 67 | 接着说,通常我们的方法传参是需要括号的,为什么这里不需要了呢?因为 infix 这个关键字!这里跟 Scala 和 Groovy 不同,Kotlin 只有显示的声明为 infix 的只有一个参数的方法才可以这么玩,如果你不显示声明,想去括号门儿都没有。 68 | 69 | ## 聊聊 DSL 70 | 71 | 好,抛开老张的例子不谈,毕竟真正生产环境下,谁会去用中文呢。什么情况下我们需要 infix?当然是 DSL 中。我们看一段 Gradle 配置: 72 | 73 | ```groovy 74 | apply plugin: 'kotlin' 75 | ``` 76 | 看上去很有表现力是吧,即使你不懂 groovy 语法,也能直接看懂这句话就是使用 kotlin 插件。可它本质上还是句 groovy 代码,所以它的结构是怎样的呢? 77 | 78 | ```java 79 | void apply(Map config); 80 | ``` 81 | 82 | 实际上,apply 是 PluginAware 的一个方法,后面的 plugin 呢? 那不过是一个 k-v 对而已,在 groovy 当中, K:V 的形式可以表示一个键值对。那既然参数是 Map,那我要是多传几个参数是不是也可以呢? 83 | 84 | ```groovy 85 | apply ([plugin: 'kotlin', 宝宝: "不开心"]) 86 | ``` 87 | 88 | 不过这样虽然多传了一个键值对,不过由于 gradle 并不关心 “宝宝”,所以 “宝宝:不开心”那也没有办法了,说了也白说。哈哈。 89 | 90 | 前面的 DSL 是 groovy 版本的,再回到 Kotlin 当中,如果我们编写 DSL 代码,据说 Kotlin 版本的 gradle 也已经在开发中了,那么我们猜猜它会长成啥样? 91 | 92 | ```kotlin 93 | apply mapOf("plugin" to "kotlin") 94 | ``` 95 | 96 | 用 Kotlin 的 K to V 的方式传入一个 Pair。这里的 apply 的声明就应该是: 97 | 98 | ```kotlin 99 | infix fun apply(config: Map) 100 | ``` 101 | 102 | 很丑?没关系,我们为什么不直接搞一个方法叫做 applyPlugin 呢? 103 | 104 | ```kotlin 105 | infix fun applyPlugin(pluginName: String) 106 | ``` 107 | 于是: 108 | 109 | ```kotlin 110 | applyPlugin "kotlin" 111 | ``` 112 | 113 | 当然,作为静态语言,与 groovy 当然不能照搬了,所以最理想的实现肯定是强类型约束,比如 114 | 115 | ```kotlin 116 | apply() 117 | ``` 118 | 不过,这个我们就不谈了,跑题了。 119 | 120 | ## 小结 121 | 122 | infix 是一个非常有用的关键字,让你的代码看起来像一篇文章一样,你不比再为前后括号匹配着慌,每一个单词其实都是方法调用。 -------------------------------------------------------------------------------- /articles/2017.1.21/1.1-Beta-Banner-2-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.21/1.1-Beta-Banner-2-01.png -------------------------------------------------------------------------------- /articles/2017.1.21/check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.21/check.png -------------------------------------------------------------------------------- /articles/2017.1.21/choose.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.21/choose.png -------------------------------------------------------------------------------- /articles/2017.1.21/houzi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.21/houzi.png -------------------------------------------------------------------------------- /articles/2017.1.21/喜大普奔!Kotlin 1.1 Beta 降临~.md: -------------------------------------------------------------------------------- 1 | 昨天 Kotlin 官方公布了一则消息:1.1 Beta 登场咯~用官方的原话就是说,这意味着正式版已经不再遥远,大家可以踊跃的试一试了~ 2 | 3 | 这么好的消息,我自然不能藏着掖着,要赶紧给大家发一篇文章先介绍介绍。当然啦,我还没有来得及去仔仔细细尝试其中的各种特性,所以以下内容主要来自官网原文内容和 KEEP(也就是 Kotlin Evolution and Enhancement Process)的讨论。 4 | 5 | 嗯,以后每周我们也可以考虑附加一篇 1.1 的尝鲜日志,有螃蟹就让我先吃吧,大家看着我吃哇咔咔咔! 6 | 7 | # 0、注意事项 8 | 9 | 虽然官网没有提到,不过我还是想要强调一下,本文讨论的是 1.1 Beta!1.1 Beta !!1.1 Beta!!!所以如果你装的是稳定版的 IDE 插件,并且在 gradle 当中配置的也是 1.0.6,就不要问『为什么我这个会报错』这样的问题了哦~~另外,如果真的会有这样的问题,我也不太建议大家去尝试 Bata 版,因为。。因为那样会比较打击人,你能忍受除了你自己写出bug之外还会有一些bug是因为语言本身有问题? 10 | 11 | # 1、特性概览 12 | 13 | ## 1.1 协程 14 | 15 | 不得不说,1.1 还是给我们带来了不少的惊。。喜的,额,虽然我们一直都知道,最重要的就是 协程(Coroutines),话说我最早听说这个概念的时候还是在 Lua 和 Golang 当中,这个 Java 并不支持的特性,一直与我忽远忽近,后来听说 Kotlin 1.1M 还是考虑支持协程,我着实兴奋了一把。好吧,现在终于又近了一步。 16 | 17 | 协程实际上是一个处理并发调度的概念,非阻塞的异步调用对于有过动态语言开发经历的朋友可能已是司空见惯,而对于我们这些深山老林中的 Java 程序员来说,还真是一个新鲜玩意儿。是不是厌倦了你的 new Thread 和 callback?我们看看异步加载数据的代码在 Kotlin 1.1 下要怎么写: 18 | 19 | ```kotlin 20 | future { 21 | val original = asyncLoadImage("...original...") // creates a Future 22 | val overlay = asyncLoadImage("...overlay...") // creates a Future 23 | ... 24 | // suspend while awaiting the loading of the images 25 | // then run `applyOverlay(...)` when they are both loaded 26 | return applyOverlay(original.await(), overlay.await()) 27 | } 28 | ``` 29 | 30 | 看上去好像没什么特别的,不过请注意,orginal 和 overlay 可都是异步加载的,applyOverlay 方法的调用会等到二者都准备好之后。 31 | 32 | 看上去非常符合人的思维,你不用再去过分 care 调用时序的问题,这些都交给虚拟机好了。有关协程的详细介绍,大家也可以看一下这里[Coroutines for Kotlin (Revision 3)](https://github.com/Kotlin/kotlin-coroutines/blob/master/kotlin-coroutines-informal.md),我后续的推送当中也会逐渐推送相关内容。 33 | 34 | ## 1.2 类型别名 35 | 36 | 其实很多时候我们都需要一个类型来表示多种不同的含义,比如对于一个音乐播放器来说,在随机模式下,一首歌在播放列表的位置就有两种:实际位置,播放位置。这两种位置其实都是可以用一个 int 来表示的,于是我们的代码就会写成: 37 | 38 | ```kotlin 39 | fun getPosition(): Int{ 40 | ... 41 | } 42 | ``` 43 | 44 | 不知道大家发现什么没有,这个方法这么看上去我们根本搞不清楚它要返回的是那种类型的位置。如果有了类型别名呢? 45 | 46 | ```kotlin 47 | typealias ListPosition = Int 48 | 49 | fun getPosition(): ListPosition{ 50 | ... 51 | } 52 | ``` 53 | 54 | 虽然返回的仍然是整型,不过含义却明确了许多。 55 | 56 | 当然,除了这个用途之外,对于 Lambda 表达式的表示也会简洁直接许多。 57 | 58 | ```kotlin 59 | typealias Callable = ()->Unit 60 | ``` 61 | ## 1.3 Bound callable references 62 | 63 | 说这个之前,我们先看个例子: 64 | 65 | ```kotlin 66 | array.map(::println) 67 | ``` 68 | 这个很显然是遍历 array,并调用函数 println 打印每一个元素。 69 | 70 | 那么问题来了,假设,现在我不用控制台打印了,我要将元素打印到 PDF 上面,于是: 71 | 72 | ```kotlin 73 | array.map{ 74 | pdfPrinter.println(it) 75 | } 76 | ``` 77 | 那么可不可以简化呢? 78 | 79 | ```kotlin 80 | array.map(pdfPrinter::println) 81 | ``` 82 | 83 | 也就是说函数引用进一步支持了绑定调用者(或者 receiver)的情况。 84 | 85 | ## 1.4 Data class 可以有爸爸啦 86 | 87 | 以前,data class 是不允许继承其他类的。不要问我为什么,没有父类这种事儿我更建议你去问问猴子。 88 | 89 | ![](houzi.png) 90 | 91 | > 你丫再瞎说小心我削你啊 92 | 93 | 不过,1.1 开始,Kotlin 的创造者们终于良心发现,允许 data class 有个爸爸,这种事儿嘛,终归是一幅令人感动的画面啦。 94 | 95 | ```kotlin 96 | data class Complex(...) : Something() 97 | ``` 98 | 99 | 不过嘛,data class 这个家伙还是有点儿悲剧的,1.1 也没有允许他有子嗣,虽然可以认爹,不过没爹的时候就继续自己孤苦着吧。 100 | 101 | ## 1.5 放宽 sealed class 的子类定义限制 102 | 103 | sealed class 的子类必须同时也是它的内部类,这即将成为过去。从 1.1 开始,只要跟 sealed class 定义在同一个文件内即可,嗯。。这个功能没有什么逻辑上的变化,不过写起来倒是省力一些。 104 | 105 | ## 1.6 万金油下划线 106 | 107 | 不知道大家有没有注意过 Golang 当中的下划线, 108 | 109 | ```go 110 | _,err := func() 111 | ``` 112 | 其实就是个占位符,如果我们对它不是很关心,那么还用得着费尽心思给它想个名字吗?当然不,Kotlin 1.1 也允许你这么干: 113 | 114 | ```kotlin 115 | val (_, x, _, z) = listOf(1, 2, 3, 4) 116 | print(x + z) 117 | ``` 118 | 119 | 上面这个例子,我们只关心第2、4个值,1、3就直接忽视好了。 120 | 121 | ```kotlin 122 | var name: String by Delegates.observable("no name") { 123 | _, oldValue, _ -> println("$oldValue") 124 | } 125 | ``` 126 | 这个例子则是说,三个形参我只关心第二个,那么其他两个退下吧~ 127 | 128 | 哈哈,如果不需要我思考给变量起什么名字的话,我会不会轻松很多! 129 | 130 | ## 1.7 provideDelegate 131 | 132 | 不知道大家有没有想过,一旦给一个成员加了 Delegate,那么我就把这个成员的控制权交给了 Delegate,如果我想要监听一下这个成员的读写,我只能在 Delegate 当中做了。 133 | 134 | ```kotlin 135 | class ResourceLoader(id: ResourceID) { 136 | operator fun provideDelegate(thisRef: MyUI, property: KProperty<*>) 137 | : ReadOnlyProperty { 138 | checkProperty(thisRef, property.name) 139 | ... // property creation 140 | } 141 | 142 | private fun checkProperty(thisRef: MyUI, name: String) { ... } 143 | } 144 | 145 | fun bindResource(id: ResourceID): ResourceLoader { ... } 146 | 147 | class MyUI { 148 | val image by bindResource(ResourceID.image_id) 149 | val text by bindResource(ResourceID.text_id) 150 | } 151 | ``` 152 | 153 | provideDelegate 可以允许我们在配置了 Delegate 之后也可以做一些织入代码的工作,这就为 Delegate 带来了更多的灵活性。 154 | 155 | ## 1.8 其他特性 156 | 157 | 当然,1.1 这么大的版本,特性肯定不止这些了,还有一些特性比如 DSL 作用域控制、为 Kotlin 集合增加 Java 8 方法的支持等等,我这里就不一一介绍了,大家也可以直接到[官博](https://blog.jetbrains.com/kotlin/2017/01/kotlin-1-1-beta-is-here)一探究竟。 158 | 159 | 160 | # 2 如何配置 1.1 的环境 161 | 162 | 如果你也想吃螃蟹,那你必须更新你的 Kotlin 插件版本: 163 | 164 | ![](check.png) 165 | 166 | ![](choose.png) 167 | 168 | 选中 1.1 之后点击 check for update 就可以了。 169 | 170 | 如果你用 gradle 或者 maven 构建自己的工程,那么你需要添加插件仓库:http://dl.bintray.com/kotlin/kotlin-eap-1.1,选择 Kotlin 的版本为 1.1.0-beta-17 即可。 171 | 172 | 下面是 gradle 的配置: 173 | 174 | ```groovy 175 | buildscript { 176 | ext.kotlin_version = '1.1.0-beta-17' 177 | 178 | repositories { 179 | jcenter() 180 | 181 | maven{ 182 | url "http://dl.bintray.com/kotlin/kotlin-eap-1.1" 183 | } 184 | } 185 | dependencies { 186 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 187 | } 188 | } 189 | ``` 190 | 191 | # 3 小结 192 | 193 | Kotlin 的迭代速度还是非常快的,稳定版本基本上每两个月更新一次,1.1 版的开发工作从年初正式版发布就逐渐为人所知,终于 Beta 来了,相信 1.1 正式版也不会让我们等太久。 194 | 195 | 后续我也会陆续推送一些文章介绍 1.1 的新特性,希望大家多多关注~ -------------------------------------------------------------------------------- /articles/2017.1.23/cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.23/cover.jpg -------------------------------------------------------------------------------- /articles/2017.1.23/linear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.23/linear.png -------------------------------------------------------------------------------- /articles/2017.1.23/relative.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.23/relative.png -------------------------------------------------------------------------------- /articles/2017.1.30/coroutine_cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.30/coroutine_cover.jpg -------------------------------------------------------------------------------- /articles/2017.1.30/coroutine_lua.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.30/coroutine_lua.png -------------------------------------------------------------------------------- /articles/2017.1.30/cr0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.30/cr0.png -------------------------------------------------------------------------------- /articles/2017.1.30/cr1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.30/cr1.png -------------------------------------------------------------------------------- /articles/2017.1.30/cr2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.30/cr2.png -------------------------------------------------------------------------------- /articles/2017.1.30/mdhere.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.30/mdhere.gif -------------------------------------------------------------------------------- /articles/2017.1.30/勘误:15 Kotlin 与 Java 共存 (2) .md: -------------------------------------------------------------------------------- 1 | # 勘误:15 Kotlin 与 Java 共存 (2) 2 | 3 | 在过去推送过的第15期视频中,涉及到一个泛型对比的点,当时文中提到“对于循环引用泛型参数的情况,Kotlin 无法实现”的结论是有问题的。感谢 @zhangdatou 指正,对应部分的内容修改如下: 4 | 5 | ## 3 泛型 6 | 7 | 整体上来讲,Kotlin 的泛型与 Java 的没什么大的差别,Java 的 ? 在 Kotlin 中变成了 *,毕竟 ? 在 Kotlin 当中用处大着呢。另外,Java 泛型的上限下限的表示法在 Kotlin 当中变成了 out 和 in。 8 | 9 | 不过,由于 Java 1.5 之前并没有泛型的概念,为了兼容旧版本,1.5 之后的 Java 仍然允许下面的写法存在: 10 | 11 | ```java 12 | List list = new ArrayList(); 13 | list.add("Hello"); 14 | list.add(1); 15 | for (Object o : list) { 16 | System.out.println(o); 17 | } 18 | ``` 19 | 而对应的,在 Kotlin 当中要用 List<*> 来表示 Java 中的 List —— 这本身没什么问题。那么我们现在再看一段代码: 20 | 21 | ```java 22 | public abstract class View

{ 23 | protected P presenter; 24 | } 25 | 26 | public abstract class Presenter{ 27 | protected V view; 28 | } 29 | ``` 30 | 这个其实是现在比较流行的 MVP 设计模式的一个简单的接口,我希望通过泛型来绑定 V-P,并且我可以通过泛型参数在运行时直接反射实例化一个 presenter 完成 V-P 的实例注入,这在 Java 当中是没有问题的。 31 | 32 | 那么在 Kotlin 当中呢? 因为我们知道 View 和 Presenter 都有泛型参数的,所以我们在 Kotlin 当中就要这么写: 33 | 34 | ```kotlin 35 | abstract class View

>{ 36 | protected abstract val presenter: P 37 | } 38 | 39 | abstract class Presenter>>>{ 40 | protected abstract val view: V 41 | } 42 | ``` 43 | 一直写下去,最终陷入了死循环。编译器给出的解释是: 44 | 45 | >This type parameter violates the Finite Bound Restriction. 46 | 47 | 在 @zhangdatou 给我发邮件之前,我曾一直对此耿耿于怀,Kotlin 这么优秀的语言怎么还会有做不到的事情呢。原来不是做不到,而是我没有想到: 48 | 49 | ```kotlin 50 | abstract class View>> 51 | abstract class Presenter>> 52 | 53 | class MyView: View() 54 | class MyPresenter: Presenter() 55 | ``` 56 | 实际上我们需要 View 的泛型参数 P 只要是 Presenter 的子类即可,并且要求这个泛型参数 P 本身对应的泛型参数也需要是 View 的子类,而这个 View 其实就是最初的那个 View,那么这个 View 的泛型参数当然就是 P 了。有点儿绕,但这么写出来明显感觉比 Java 安全靠谱多了。 57 | 58 | -------------------------------------------------------------------------------- /articles/2017.1.30/如何优雅的在微信公众号中编辑代码.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.30/如何优雅的在微信公众号中编辑代码.jpg -------------------------------------------------------------------------------- /articles/2017.1.9/action.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.9/action.gif -------------------------------------------------------------------------------- /articles/2017.1.9/array.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.9/array.jpg -------------------------------------------------------------------------------- /articles/2017.1.9/comment.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.9/comment.gif -------------------------------------------------------------------------------- /articles/2017.1.9/comment2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.9/comment2.gif -------------------------------------------------------------------------------- /articles/2017.1.9/comment3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.9/comment3.gif -------------------------------------------------------------------------------- /articles/2017.1.9/enter.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.9/enter.gif -------------------------------------------------------------------------------- /articles/2017.1.9/findaction.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.9/findaction.png -------------------------------------------------------------------------------- /articles/2017.1.9/intellij.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.9/intellij.jpg -------------------------------------------------------------------------------- /articles/2017.1.9/iter_smart.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.9/iter_smart.gif -------------------------------------------------------------------------------- /articles/2017.1.9/iter_stupid.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.9/iter_stupid.gif -------------------------------------------------------------------------------- /articles/2017.1.9/livetemplate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.9/livetemplate.png -------------------------------------------------------------------------------- /articles/2017.1.9/lt10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.9/lt10.png -------------------------------------------------------------------------------- /articles/2017.1.9/lt11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.9/lt11.png -------------------------------------------------------------------------------- /articles/2017.1.9/lt12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.9/lt12.png -------------------------------------------------------------------------------- /articles/2017.1.9/lt13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.9/lt13.png -------------------------------------------------------------------------------- /articles/2017.1.9/lt14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.9/lt14.png -------------------------------------------------------------------------------- /articles/2017.1.9/lt15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.9/lt15.png -------------------------------------------------------------------------------- /articles/2017.1.9/lt2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.9/lt2.png -------------------------------------------------------------------------------- /articles/2017.1.9/lt3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.9/lt3.png -------------------------------------------------------------------------------- /articles/2017.1.9/lt4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.9/lt4.png -------------------------------------------------------------------------------- /articles/2017.1.9/lt5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.9/lt5.png -------------------------------------------------------------------------------- /articles/2017.1.9/lt6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.9/lt6.png -------------------------------------------------------------------------------- /articles/2017.1.9/lt8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.9/lt8.png -------------------------------------------------------------------------------- /articles/2017.1.9/lt9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.9/lt9.png -------------------------------------------------------------------------------- /articles/2017.1.9/main.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.9/main.gif -------------------------------------------------------------------------------- /articles/2017.1.9/multiline.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.9/multiline.gif -------------------------------------------------------------------------------- /articles/2017.1.9/multiline2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.9/multiline2.gif -------------------------------------------------------------------------------- /articles/2017.1.9/multiline_action.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.9/multiline_action.png -------------------------------------------------------------------------------- /articles/2017.1.9/newline.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.9/newline.gif -------------------------------------------------------------------------------- /articles/2017.1.9/newline2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.9/newline2.gif -------------------------------------------------------------------------------- /articles/2017.1.9/newline3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.9/newline3.gif -------------------------------------------------------------------------------- /articles/2017.1.9/newline_action.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.9/newline_action.png -------------------------------------------------------------------------------- /articles/2017.1.9/posix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.9/posix.png -------------------------------------------------------------------------------- /articles/2017.1.9/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.9/search.png -------------------------------------------------------------------------------- /articles/2017.1.9/search2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.9/search2.png -------------------------------------------------------------------------------- /articles/2017.1.9/swap_action.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.9/swap_action.png -------------------------------------------------------------------------------- /articles/2017.1.9/swap_fun.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.9/swap_fun.gif -------------------------------------------------------------------------------- /articles/2017.1.9/swap_smart.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.9/swap_smart.gif -------------------------------------------------------------------------------- /articles/2017.1.9/swap_stupid.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.9/swap_stupid.gif -------------------------------------------------------------------------------- /articles/2017.1.9/tab.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.1.9/tab.gif -------------------------------------------------------------------------------- /articles/2017.1.9/高效地使用你的 IntelliJ.md: -------------------------------------------------------------------------------- 1 | # 高效地使用你的 IntelliJ 2 | 3 | 这个世界上,有些人是奥义·真·懒,他们懒得折腾一切,甚至懒得活,所以他们不会看到这篇文章的。还有些人是奥义·嘴上说的·懒,这些人有个特点,懒到什么事儿都要弄个工具,于是人类社会就这么被一点儿推动着前进了。看到这篇文章的大家应该都是后面的这类人,so,给自己鼓个掌吧! 4 | 5 | 话说,人懒就要用 IDE,IntelliJ 已经超神了,用的人越来越多,不过,它有这么多技能你们都用到过吗? 6 | 7 | ## 回车 or Tab? 8 | 9 | 很多时候我们在召唤出自动补全之后,光标选中了我们想要的那个选项,于是我们按回车。。。 10 | 11 | ![](enter.gif) 12 | 13 | 额。。这。。难道就不能直接替换掉那个 map 吗?!当然可以: 14 | 15 | ![](tab.gif) 16 | 17 | 这操作有什么区别呢?前者按的是回车,后者按的是 Tab。 18 | 19 | 印象中,微软的东西都比较倾向于按 Tab 补全,比如 VS,再比如 Excel(Whaaaat?),说这个也没别的意思,就是想让你记住,有时候 Tab 比回车好用。 20 | 21 | ## Swap 一下位置? 22 | 23 | 如果你飞快地写下了两句代码,然后发现他们的顺序是错的,你会怎么办? 24 | 25 | ![](swap_stupid.gif) 26 | 27 | 选中一整行,剪切,然后粘到上一句的前面?你 Out 了!看我的! 28 | 29 | ![](swap_smart.gif) 30 | 31 | 怎么做到的?很简单,打开你的设置,找到 keymap,再找到下面的几个 Action: 32 | 33 | ![](swap_action.png) 34 | 35 | Statement 和 line 有时候会比较相似,比如我们刚才的情形;不过 Statement 还可以表示一整个函数或者类,于是你完全可以把光标放到一个函数的函数名上,然后 move up and down: 36 | 37 | ![](swap_fun.gif) 38 | 39 | 如果你觉得默认的快捷键不好使,自己定义一个,你开心就好。 40 | 41 | ## 想要不移动光标就换行? 42 | 43 | 经常遇到这种需求,我的光标在某一行的中间,这时候想要换行,于是。。 44 | 45 | ![](newline.gif) 46 | 47 | 这明显有点儿尴尬。。当然你也可以直接移到行末,再回车,但总是要操作两次。其实这个也简单了,按住 shift 再回车,就可以直接换到下一行: 48 | 49 | ![](newline2.gif) 50 | 51 | 而按住 cmd+option 再按回车就直接换到上一行: 52 | 53 | ![](newline3.gif) 54 | 55 | windows的快捷键我不知道,不过我还是要告诉大家它的名称,你自己定义就好: 56 | 57 | ![](newline_action.png) 58 | 59 | ## 快速迭代一个集合或者数组? 60 | 61 | 如果你在 Kotlin 里面,可能并不会有这样的困惑,毕竟我们可以写完一个集合,然后 .map 就行了。Java 里面可不能这样,于是。。。 62 | 63 | ![](iter_stupid.gif) 64 | 65 | 怎么办,怎么忍?让我们喊出我们的口号:不能忍! 66 | 67 | ![](iter_smart.gif) 68 | 69 | 上面只要我们在打出一个集合之后,再打出 for,就能自动生成这段迭代的代码,这个叫做 Postfix。IntelliJ 支持了挺多的 Postfix,我就不一一列出了,在设置里面输入 postfix 那么你将看到 IntelliJ 支持的所有 Postfix: 70 | ![](posix.png) 71 | 72 | ## 多行编辑,哎哟小心某些人的钛合金眼~ 73 | 74 | 多行编辑没什么神秘的,大家一看就明白了。第一种触发方式比较简单,按住 option或者alt,用鼠标往下拖就可以触发,例如: 75 | 76 | ![](multiline.gif) 77 | 78 | 第二种要高端一些了,比如我要修改个一个词,又不可以通过 refactor来统一修改,怎么办,难道有一百个还要让我改一百次吗?当然不需要,先选中第一个,然后如果是在Mac上,按 ctrl+G)选择下一个,或者直接 cmd+ctrl+G 选择全部,就如下图所示,选中之后,多行编辑触发,你就可以一下改掉所有的: 79 | 80 | ![](multiline2.gif) 81 | 82 | 这里涉及到添加选择下一个和选择全部的操作,大家可以自己随意定义快捷键: 83 | ![](multiline_action.png) 84 | 85 | ## 查找替换也有说法? 86 | 87 | 常规的查找替换肯定没啥可说的。不过不知道你注意到没,查找替换还有个 regex 的选项: 88 | 89 | ![](search.png) 90 | 91 | 这个咋用呢?很简单,搜索词按照标准的正则表达式写就行了。比如我要定位到这个文件里面的所有函数名称,并在他们后面加一个 Test 方法,这种通常来说多行编辑是不太好做了,所以: 92 | 93 | ![](search2.png) 94 | 95 | 替换结果中,$n 表示第n个匹配到的元组。这个用起来对正则表达式的功底要求比较高了,当然我觉得他更有用的地方在于帮助你熟悉正则比倒是的用法。 96 | 97 | ## 最强快捷键,没有之一 98 | 99 | 我之前看谷歌大会的视频,有一哥们在操作几乎任何操作的时候都用到了一个类似于命令行的快捷键,看上去非常酷: 100 | 101 | ![](action.gif) 102 | 103 | 在这里,几乎可以输入任意操作,比如我们想要查看 Kotlin 的字节码,或者想要看下历史记录,甚至 make/run/debug,都毫无压力。 104 | 105 | 实际上,如果你对 IntelliJ 的插件开发有那么一丁点儿了解(比如我,虽然我自己没有写过= =、),你就会知道 IntelliJ 里面的各种操作都是 Action,只要是个 Action,就都可以配置快捷键,而且索引方式也是按照名称,所以前面的输入框就可以毫无压力的索引到这些 Action 了。 106 | 107 | 那么这个搜索框本身是个啥呢?它自己也是一个 Action,叫做: 108 | 109 | ![](findaction.png) 110 | 111 | 给它配个快捷键,让你的 IntelliJ 起飞吧~ 112 | 113 | ## 为什么输入 main 就能打出完整的 main 方法? 114 | 115 | 我在录制视频的时候经常会用一个比较快捷的输入方法: 116 | 117 | ![](main.gif) 118 | 119 | 输入main 之后就可以打出完整的main方法,这是怎么做到的?打开你的设置,找到 Live Templates, 120 | 121 | ![](livetemplate.png) 122 | 123 | 新建一个 group 叫亚瑟: 124 | 125 | ![](lt2.png) 126 | 127 | ![](lt3.png) 128 | 129 | 在这个 group 当中我们新建一个 Live Templates: 130 | 131 | ![](lt4.png) 132 | 133 | 注意看,abbreviation 是缩写的意思,也就是说你将通过输入这段文字来触发模板,比如我们刚才的 main,我们现在想要方便的在注释中写下自己的名字和注释的时间,于是我们给他起个名字叫 "//" 134 | 135 | ![](lt5.png) 136 | 137 | description 就是一个注释的作用,所以不写也可以(虽然这并不是一个好习惯)。接下来我们要写 Template Text了。我们希望输入 // 之后能自动生成下面的代码: 138 | 139 | ``` 140 | <你的用户名>[当前时间] 141 | ``` 142 | 143 | 那么我们需要定义两个变量来代表 用户名和时间: 144 | 145 | ![](lt6.png) 146 | 147 | 接下来我们要考虑,我们的这个模板用在哪里呢? 148 | 149 | ![](lt8.png) 150 | 151 | 点击 Define,在弹出的菜单中选择 Java -> Comment: 152 | 153 | ![](lt9.png) 154 | 155 | 紧接着要给这两个变量赋值了,点击旁边的 Edit Variables: 156 | 157 | ![](lt10.png) 158 | 159 | Expressions 有个下拉菜单,选出 user() 和 time() 赋给我们定义好的两个变量,同时勾上后面的两个勾 Skip if define——如果想知道为什么,你把勾去掉试试。 160 | 161 | ![](lt11.png) 162 | 163 | 这样我们就创建好了一个新的模板,一路 OK之后,我们就可以试试了: 164 | 165 | ![](comment.gif) 166 | 167 | 不过,你对时间格式有点儿不太满意,其实你还想要日期对不对?于是: 168 | 169 | ![](lt12.png) 170 | 171 | ![](lt13.png) 172 | 173 | ![](comment2.gif) 174 | 175 | 其实这样基本就满足需求了。如果你偏偏对此感到不满意,为什么时间的格式不能自定义,那。。我想告诉你的是,谁说不可以的。。 176 | 177 | ![](lt14.png) 178 | 179 | ![](lt15.png) 180 | 181 | DATETIME 的表达式是: 182 | ``` 183 | groovyScript("import java.util.Date; import java.text.SimpleDateFormat; new SimpleDateFormat('yyyy-MM-dd HH:ss').format(new Date());") 184 | ``` 185 | 186 | 就是一段普通的 groovy 脚本,不过由于 groovy 完全兼容 Java 语法,所以你可以写一段 Java 代码进入,最后一行的值就是表达式的值。 187 | 188 | 结果嘛: 189 | 190 | ![](comment3.gif) 191 | 192 | ## 小结 193 | 194 | 当然 IntelliJ 当中好玩的东西不只这些,比如 最常用的 refactor等等,剩下的就需要大家自己去发现了,实在不行咱也可以写个插件或者去搜个别人做好的插件。IntelliJ 提供了很好的扩展性和定制性,每个人的背景和习惯不一样,对 IDE 的需求也不一样,只要肯折腾,这工具会越来越顺手的。 195 | -------------------------------------------------------------------------------- /articles/2017.2.13/lambda.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.2.13/lambda.jpg -------------------------------------------------------------------------------- /articles/2017.2.20/11RC-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.2.20/11RC-01.png -------------------------------------------------------------------------------- /articles/2017.2.20/Kotlin 1.1:我们都路上.md: -------------------------------------------------------------------------------- 1 | # Kotlin 1.1:我们都路上 2 | 3 | ##►1.1 RC 来了,Release 还会远吗? 4 | 5 |

![](11RC-01.png)
6 | 7 | 去年 2 月 19 日 1.0 发版,我记得此前看到论坛上面开始讨论 1.0 API 趋于稳定的话题,想想都还挺兴奋呢,一不留神,Kotlin 1.0 在稳定奔跑一年之后,也终于迎来下一个版本:就在前天(17日),我留意到 Kotlin 官博发出了 1.1 RC(Release Candidate) 的消息,截止到目前,1.1 的所有开发工作都已经进入尾声,剩下的就只有我们期待的眼神了。 8 | 9 | ##►成长,一路有你 10 | 11 |
![](road.JPG)
12 | 13 | 2016 这一年发生了挺多的事情,最重要的就是 Kotlin 终于有一个正式的版本,开始了按部就班的日子:每两个月一个正式版本以及一个 1.1 的里程碑版本。接着,我们也很快的发现我们期待的功能都悄悄的走进了 Kotlin 的更新日志,Kotlin 正一天一天的成长起来。 14 | 15 | 不知道各位看官年龄几何,对我来说,C 和 C++ 太老,Java 虽然小了一些,可它诞生的时候我还在小学里面玩 Dos;而当我真正开始认识它们的时候却发现它们实在是太庞大了,有时候甚至觉得可怕,有时候更是没办法理解它们。它们是编程语言的长者,而我,只是一个年轻的程序员。 16 | 17 | Kotlin 则不一样了。它出现的不算早,大概 2010 年的样子吧,那个时候我刚刚闲来无事考了个软考中级的 “软件设计师”,一个在学校里面随处可见的“小黄书”背后的没有多大用处的考试,那个时候大概是我基础最好的时候吧。后来 Kotlin 逐渐成长起来,而我也逐渐脱离了象牙塔里的天真,冲向了努力干活历练自己的道路中间。 18 | 19 | ##►还记得,你与 Kotiln 的第一次相遇吗? 20 | 21 |
![](zhiyin.jpg)
22 | 23 | 最早认识 Kotlin 还是在 15 年初,那时候我正热衷于编写 IntelliJ 的插件,尽管后面成果空空,不过一些个莫名其妙的后缀为 kt 的文件却着实让我头疼不已。尽管照着说明安装好 Kotlin 的插件,可因为版本不一致,始终无法编译过去,真是无可奈何啊。当时我还想,又有新语言啊,这可当真是学海无涯咯。 24 | 25 | 不过,随着接触的机会逐渐增多,我发现 Kotlin 解决了很多我对 Java 不满的问题,而它呢,却又全力支持着 Java 中的一切,始终让我们感觉不到我用了另外一种语言,语法的那点儿差异说真的比起不同语言背后的编程思维的差异来说,简直不值得一提。我在同时尝试了 groovy 和 scala 之后,觉得 Kotlin 才是我想要的,于是在 Kotlin 1.0 发布之际,我向 Bugly 公众号投稿文章:[Android 必备技能:最有可能接替Java的语言——Kotlin](http://www.println.net/post/Android-A-Powerful-Substitution-Kotlin) ,把我眼中的 Kotlin 向大家展现了出来。 26 | 27 | 28 | ##​►Kotlin 给你带来了什么? 29 | 去年上半年有段时间经常奔波在北京和深圳之间,工作节奏“日新月异”,项目似乎进入了一种莫名其妙的状态,而我自己则犹如置身死水,所幸我也是上过王者的人了,也不枉费我那一段时间在上面投入的一个个不眠之夜吧。 30 | 31 |
![](wangzhe.jpg)
32 | 33 | 那段时间,我对项目的代码有我“自以为是的足够”的祸害的自由,于是我开始肆无忌惮的用 Kotlin 写一些模块,完全没有顾及合作开发的我们组唯一的妹子的感受。以及,这代码后来落入导师手中,我也算是坑他们不浅呐。不过,如果没有这段经历,或许我后来也不会有那么大的底气去在 10 月份斗胆录制视频,也自然不会去开公众号每周发几篇水文了。说来,得好好谢谢他们。 34 | 35 | 36 |
![](embarassed.png)
37 | 38 | 话说,自从摊上这么个事儿,我只好每天早晨 6 点起来或写写东西,或看看书,学点儿东西,每天节奏也极其规律,中午再也没没有精力跟小伙伴们组团王者了,因为我得睡一个小时。 39 | 40 | 年前我又在 Bugly 公众号发了一篇文章:[你为什么需要 Kotlin](http://mp.weixin.qq.com/s?__biz=MzA3NTYzODYzMg==&mid=2653578489&idx=1&sn=17d6e657d81c0daa345489271d305b36&chksm=84b3b6feb3c43fe8b0197850bf6ca8caefaa8045671f75ed6dec2171a681496365acfd0ebd33&mpshare=1&scene=23&srcid=0217VmFlkVB0LB4I2YRbvicL#rd),结果大家都说我是被代码耽误了的段子手,呃。。我想说你们说的很对! 41 | 42 |
![](right.jpg)
43 | 44 | 承蒙各位朋友厚爱,经常提及后续视频录制的问题,我正在尝试重新录制一套较为细致和基础的视频,目前讲义已经编写完毕,至于发布时间,那得看我啥时候录得完啦。 45 | 46 | 末了,建议大家有事儿没事儿也都写写,我最开始在公司内部写文章刷积分玩,后来发现自己写的东西经常需要复习;不仅如此,很多时候遇到一个问题,可能最终用某种方式解决了,你以为这个问题你是搞清楚了的,不过,一旦你企图将其形成文字,你就会发现问题的背后将会是更多的细枝末节。俗话说得好,好记性不如啪啪啪的机械键盘啊! 47 | 48 |
![](../../arts/kotlin扫码关注.png)
-------------------------------------------------------------------------------- /articles/2017.2.20/cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.2.20/cover.jpg -------------------------------------------------------------------------------- /articles/2017.2.20/embarassed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.2.20/embarassed.png -------------------------------------------------------------------------------- /articles/2017.2.20/growup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.2.20/growup.png -------------------------------------------------------------------------------- /articles/2017.2.20/high_order_fun.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.2.20/high_order_fun.jpg -------------------------------------------------------------------------------- /articles/2017.2.20/right.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.2.20/right.jpg -------------------------------------------------------------------------------- /articles/2017.2.20/road.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.2.20/road.JPG -------------------------------------------------------------------------------- /articles/2017.2.20/wangzhe.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.2.20/wangzhe.jpg -------------------------------------------------------------------------------- /articles/2017.2.20/zhiyin.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.2.20/zhiyin.jpg -------------------------------------------------------------------------------- /articles/2017.2.6/Kotlin 1.1 Beta 2 发布~.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.2.6/Kotlin 1.1 Beta 2 发布~.jpg -------------------------------------------------------------------------------- /articles/2017.2.6/Kotlin 1.1 Beta 2 发布~.md: -------------------------------------------------------------------------------- 1 | # Kotlin 1.1 Beta 2 重点更新 2 | 3 | ## 1 协程改包名风波 4 | 5 | 说真的,看到这个标题的时候我还挺兴奋,离 release 又近了一步。不过,看了这篇文章的时候,我就觉得也是醉醉的。发生了啥呢? 6 | 7 | 原来,协程相关的依赖统统被标记为 experimental 了,以前叫: 8 | 9 | ```kotlin 10 | package kotlin.coroutines 11 | ``` 12 | 现在呢? 13 | 14 | ```kotlin 15 | package kotlin.coroutines.experimental 16 | ``` 17 | 18 | 这意味着啥?意味着我们在这次更新之后,还得把原来的协程代码的包重新导入一遍,另外,如果你想使用协程,那么你还需要在配置当中呢启用它,例如 gradle 配置需要加入: 19 | 20 | ```gradle 21 | kotlin { 22 |     experimental { 23 |         coroutines 'enable' 24 |     } 25 | } 26 | ``` 27 | 28 | 你在升级所有的依赖的时候,确保它是兼容 1.1.0-beta-38 的,这一点很重要,不然等着报错吧! 29 | 30 | 话说,为啥要这么搞呢?按照官方的说法就是,协程这个特性目前已经实现的非常不错了,内置 API 非常少,灵活扩展性也强,不过他们觉得这个东西还有很大的潜力,也不能就这样作为最终版本给大家放出来,而作为实验特性交给大家使用呢,更多地还是希望大家能提提意见啥的。嗯,说实在的,协程这个特性真不是个小特性。 31 | 32 | ## 2 兼容 1.0 33 | 34 | 话说,1.1 的编译器终于声称兼容 1.0 的源码了,这表明我们再也不用搞两个 IntelliJ 分别装 1.0 稳定版的插件和 1.1 Beta 版的插件了。 35 | 36 | 是的,就算你不用 1.1 的特性,你装 1.1 的插件,用 1.1 的编译器,写 1.0 的代码毫无压力!! 37 | 38 | 什么?你问我试了没?当然,我一直用最新的插件,折腾地挺苦的 T T,劝诸君还是装稳定版吧,吃螃蟹要做好心理准备~! 39 | 40 | ## 3 小结 41 | 42 | 浏览了一下 1.1Beta 2 的主要特性,其实就是改改包名,修几个小 Bug,大的改动基本没有了。如果大家想要尽早上手 1.1 的特性,那么就从现在开始吧~ 43 | 44 | -------------------------------------------------------------------------------- /articles/2017.3.13/Kotlin Script 介绍.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.3.13/Kotlin Script 介绍.jpg -------------------------------------------------------------------------------- /articles/2017.3.13/快速上手 Kotlin 11招.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.3.13/快速上手 Kotlin 11招.jpg -------------------------------------------------------------------------------- /articles/2017.3.20/cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.3.20/cover.jpg -------------------------------------------------------------------------------- /articles/2017.3.20/wechat_group.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.3.20/wechat_group.jpg -------------------------------------------------------------------------------- /articles/2017.3.27/cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.3.27/cover.jpg -------------------------------------------------------------------------------- /articles/2017.3.4/Kotlin11blogbanner1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/articles/2017.3.4/Kotlin11blogbanner1.jpg -------------------------------------------------------------------------------- /arts/Kotlin-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/arts/Kotlin-logo.png -------------------------------------------------------------------------------- /arts/Kotlin.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/arts/Kotlin.jpg -------------------------------------------------------------------------------- /arts/contributes.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/arts/contributes.jpg -------------------------------------------------------------------------------- /arts/e_group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/arts/e_group.png -------------------------------------------------------------------------------- /arts/kotlin扫码关注.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/arts/kotlin扫码关注.png -------------------------------------------------------------------------------- /code/Kt01/src/net/println/kt01/Main.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt01 2 | 3 | /** 4 | * Created by benny on 10/11/16. 5 | */ 6 | fun main(args: Array){ 7 | println("Hello World!!") 8 | println(Main("Bennyhuo", 0)) 9 | } 10 | 11 | class Main(val title: String, val id: Int){ 12 | override fun toString(): String { 13 | return "$id - $title" 14 | } 15 | } -------------------------------------------------------------------------------- /code/Kt02/src/net/println/kt02/Main.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt02 2 | 3 | /** 4 | * Created by benny on 10/11/16. 5 | */ 6 | 7 | fun main(args : Array){ 8 | println("Hello World!!!") 9 | println(Main(0, "bennyhuo")) 10 | } 11 | 12 | data class Main(val id : Int, val name: String) -------------------------------------------------------------------------------- /code/Kt03/build.gradle: -------------------------------------------------------------------------------- 1 | group 'net.println' 2 | version '1.0-SNAPSHOT' 3 | 4 | buildscript { 5 | ext.kotlin_version = '1.0.4' 6 | 7 | repositories { 8 | jcenter() 9 | } 10 | dependencies { 11 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 12 | } 13 | } 14 | 15 | apply plugin: 'java' 16 | apply plugin: 'kotlin' 17 | 18 | sourceCompatibility = 1.5 19 | 20 | repositories { 21 | jcenter() 22 | } 23 | 24 | dependencies { 25 | compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 26 | compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" 27 | testCompile group: 'junit', name: 'junit', version: '4.11' 28 | } -------------------------------------------------------------------------------- /code/Kt03/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/code/Kt03/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /code/Kt03/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Tue Oct 11 23:18:44 CST 2016 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.13-all.zip 7 | -------------------------------------------------------------------------------- /code/Kt03/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn ( ) { 37 | echo "$*" 38 | } 39 | 40 | die ( ) { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /code/Kt03/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /code/Kt03/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'Kt03' 2 | 3 | -------------------------------------------------------------------------------- /code/Kt03/src/main/java/net/println/kt03/Hello.java: -------------------------------------------------------------------------------- 1 | package net.println.kt03; 2 | 3 | /** 4 | * Created by benny on 10/12/16. 5 | */ 6 | public class Hello { 7 | public static void main(String... args) { 8 | int a = 021; 9 | System.out.println(a); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /code/Kt03/src/main/java/net/println/kt03/HelloJava.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt03 2 | 3 | /** 4 | * Created by benny on 10/11/16. 5 | */ 6 | object HelloJava { 7 | @JvmStatic fun main(args: Array) { 8 | val user = User(0, "bennyhuo") 9 | println(user) 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /code/Kt03/src/main/java/net/println/kt03/HelloKotlin.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt03 2 | 3 | /** 4 | * Created by benny on 10/11/16. 5 | */ 6 | fun main(args: Array){ 7 | val user = User(0, "bennyhuo") 8 | println(user) 9 | 10 | HelloKotlin::class.constructors.map(::println) 11 | } 12 | 13 | class HelloKotlin{ 14 | fun hello(){ 15 | 16 | } 17 | } -------------------------------------------------------------------------------- /code/Kt03/src/main/kotlin/net/println/kt03/User.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt03 2 | 3 | /** 4 | * Created by benny on 10/11/16. 5 | */ 6 | data class User(val id : Int, val name : String) { 7 | 8 | } -------------------------------------------------------------------------------- /code/Kt04/build.gradle: -------------------------------------------------------------------------------- 1 | group 'net.println' 2 | version '1.0-SNAPSHOT' 3 | 4 | buildscript { 5 | ext.kotlin_version = '1.0.4' 6 | 7 | repositories { 8 | mavenCentral() 9 | } 10 | dependencies { 11 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 12 | } 13 | } 14 | 15 | apply plugin: 'java' 16 | apply plugin: 'kotlin' 17 | 18 | sourceCompatibility = 1.5 19 | 20 | repositories { 21 | mavenCentral() 22 | } 23 | 24 | dependencies { 25 | compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 26 | compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" 27 | testCompile group: 'junit', name: 'junit', version: '4.11' 28 | } 29 | -------------------------------------------------------------------------------- /code/Kt04/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/code/Kt04/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /code/Kt04/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Oct 12 23:22:16 CST 2016 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.13-bin.zip 7 | -------------------------------------------------------------------------------- /code/Kt04/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn ( ) { 37 | echo "$*" 38 | } 39 | 40 | die ( ) { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /code/Kt04/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /code/Kt04/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'Kt04' 2 | 3 | -------------------------------------------------------------------------------- /code/Kt04/src/main/java/net/println/kt04/ConsoleParam.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt04 2 | 3 | /** 4 | * Created by benny on 10/14/16. 5 | */ 6 | fun main(args: Array): Unit{ 7 | args.map(::println) 8 | } -------------------------------------------------------------------------------- /code/Kt04/src/main/java/net/println/kt04/ConsoleParamInJava.java: -------------------------------------------------------------------------------- 1 | package net.println.kt04; 2 | 3 | /** 4 | * Created by benny on 10/14/16. 5 | */ 6 | public class ConsoleParamInJava { 7 | public static void main(String... args) { 8 | for (String arg : args) { 9 | System.out.println(arg); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /code/Kt05/build.gradle: -------------------------------------------------------------------------------- 1 | group 'net.println' 2 | version '1.0-SNAPSHOT' 3 | 4 | buildscript { 5 | ext.kotlin_version = '1.0.4' 6 | 7 | repositories { 8 | mavenCentral() 9 | } 10 | dependencies { 11 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 12 | } 13 | } 14 | 15 | apply plugin: 'java' 16 | apply plugin: 'kotlin' 17 | 18 | sourceCompatibility = 1.5 19 | 20 | repositories { 21 | mavenCentral() 22 | } 23 | 24 | dependencies { 25 | compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 26 | testCompile group: 'junit', name: 'junit', version: '4.11' 27 | } 28 | -------------------------------------------------------------------------------- /code/Kt05/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/code/Kt05/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /code/Kt05/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Oct 14 22:31:22 CST 2016 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.13-bin.zip 7 | -------------------------------------------------------------------------------- /code/Kt05/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn ( ) { 37 | echo "$*" 38 | } 39 | 40 | die ( ) { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /code/Kt05/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /code/Kt05/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'Kt05' 2 | 3 | -------------------------------------------------------------------------------- /code/Kt05/src/main/java/net/println/kt05/ConsoleParam2.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt05 2 | 3 | /** 4 | * a_b_c d_e f_g_h_j 5 | * a b c d e f g h j 6 | * Created by benny on 10/14/16. 7 | */ 8 | fun main(vararg args: String) { 9 | args.flatMap { 10 | it.split("_") 11 | }.map { 12 | print("$it ${it.length}") 13 | } 14 | } -------------------------------------------------------------------------------- /code/Kt05/src/main/java/net/println/kt05/ConsoleParamInJava.java: -------------------------------------------------------------------------------- 1 | package net.println.kt05; 2 | 3 | /** 4 | * Created by benny on 10/14/16. 5 | */ 6 | public class ConsoleParamInJava { 7 | public static void main(String... args) { 8 | for (String arg: args){ 9 | String[] splits = arg.split("_"); 10 | for (String split : splits) { 11 | System.out.print(split); 12 | System.out.print(" "); 13 | } 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /code/Kt06/build.gradle: -------------------------------------------------------------------------------- 1 | group 'net.println' 2 | version '1.0-SNAPSHOT' 3 | 4 | buildscript { 5 | ext.kotlin_version = '1.0.4' 6 | 7 | repositories { 8 | mavenCentral() 9 | } 10 | dependencies { 11 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 12 | } 13 | } 14 | 15 | apply plugin: 'java' 16 | apply plugin: 'kotlin' 17 | 18 | sourceCompatibility = 1.5 19 | 20 | repositories { 21 | mavenCentral() 22 | } 23 | 24 | dependencies { 25 | compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 26 | testCompile group: 'junit', name: 'junit', version: '4.11' 27 | } 28 | -------------------------------------------------------------------------------- /code/Kt06/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/code/Kt06/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /code/Kt06/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sat Oct 15 23:36:13 CST 2016 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.13-bin.zip 7 | -------------------------------------------------------------------------------- /code/Kt06/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn ( ) { 37 | echo "$*" 38 | } 39 | 40 | die ( ) { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /code/Kt06/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /code/Kt06/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'Kt06' 2 | 3 | -------------------------------------------------------------------------------- /code/Kt06/src/main/java/net/println/kt06/EnumInJava.java: -------------------------------------------------------------------------------- 1 | package net.println.kt06; 2 | 3 | public enum EnumInJava { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /code/Kt06/src/main/java/net/println/kt06/Main.java: -------------------------------------------------------------------------------- 1 | package net.println.kt06; 2 | 3 | /** 4 | * Created by benny on 10/16/15. 5 | */ 6 | public class Main { 7 | public static void main(String... args) { 8 | Lang lang = Lang.ENGLISH; 9 | 10 | String bye; 11 | switch (lang){ 12 | case ENGLISH: 13 | bye = "Bye"; 14 | break; 15 | case CHINESE: 16 | bye = "再见"; 17 | break; 18 | case JAPANESE: 19 | bye = "さようなら"; 20 | break; 21 | case KOREAN: 22 | bye = "안녕히가세요"; 23 | break; 24 | default: 25 | bye = "Bye"; 26 | } 27 | System.out.println(bye); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /code/Kt06/src/main/java/net/println/kt06/SayHello.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt06 2 | 3 | /** 4 | * Created by benny on 10/15/16. 5 | */ 6 | 7 | enum class Lang(val hello: String){ 8 | ENGLISH("Hello"), 9 | CHINESE("你好"), 10 | JAPANESE("こんにちは"), 11 | KOREAN("안녕하새요"); 12 | 13 | fun sayHello(){ 14 | println(hello) 15 | } 16 | 17 | companion object{ 18 | fun parse(name: String):Lang{ 19 | return Lang.valueOf(name.toUpperCase()) 20 | } 21 | } 22 | } 23 | 24 | fun main(args: Array) { 25 | if(args.size == 0) return 26 | val lang = Lang.parse(args[0]) 27 | println(lang) 28 | lang.sayHello() 29 | lang.sayBye() 30 | } 31 | 32 | fun Lang.sayBye(){ 33 | val bye = when(this){ 34 | Lang.ENGLISH ->"Bye" 35 | Lang.CHINESE ->"再见" 36 | Lang.JAPANESE ->"さようなら" 37 | Lang.KOREAN -> "안녕히가세요" 38 | } 39 | println(bye) 40 | } 41 | -------------------------------------------------------------------------------- /code/Kt08/build.gradle: -------------------------------------------------------------------------------- 1 | group 'net.println' 2 | version '1.0-SNAPSHOT' 3 | 4 | buildscript { 5 | ext.kotlin_version = '1.0.4' 6 | 7 | repositories { 8 | mavenLocal() 9 | 10 | jcenter() 11 | } 12 | dependencies { 13 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 14 | } 15 | } 16 | 17 | apply plugin: 'java' 18 | apply plugin: 'kotlin' 19 | 20 | sourceCompatibility = 1.5 21 | 22 | repositories { 23 | mavenLocal() 24 | 25 | jcenter() 26 | } 27 | 28 | dependencies { 29 | compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 30 | compile "com.squareup.retrofit2:retrofit:2.1.0" 31 | compile "com.squareup.retrofit2:converter-gson:2.1.0" 32 | testCompile group: 'junit', name: 'junit', version: '4.11' 33 | } 34 | -------------------------------------------------------------------------------- /code/Kt08/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/code/Kt08/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /code/Kt08/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Thu Oct 27 21:43:09 CST 2016 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-bin.zip 7 | -------------------------------------------------------------------------------- /code/Kt08/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn ( ) { 37 | echo "$*" 38 | } 39 | 40 | die ( ) { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /code/Kt08/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /code/Kt08/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'Kt08' 2 | 3 | -------------------------------------------------------------------------------- /code/Kt08/src/main/java/net/println/kt08/Service.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt08 2 | 3 | import retrofit2.Call 4 | import retrofit2.Retrofit 5 | import retrofit2.converter.gson.GsonConverterFactory 6 | import retrofit2.http.GET 7 | 8 | /** 9 | * Created by benny on 11/1/16. 10 | */ 11 | interface GitHubService{ 12 | 13 | @GET("/repos/enbandari/Kotlin-Tutorials/stargazers") 14 | fun getStarGazers(): Call> 15 | } 16 | 17 | object Service{ 18 | val gitHubService: GitHubService by lazy { 19 | Retrofit.Builder().baseUrl("https://api.github.com").addConverterFactory(GsonConverterFactory.create()).build().create(GitHubService::class.java) 20 | } 21 | } 22 | 23 | fun main(args: Array) { 24 | Service.gitHubService.getStarGazers().execute().body().map(::println) 25 | } -------------------------------------------------------------------------------- /code/Kt08/src/main/java/net/println/kt08/User.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt08 2 | 3 | /** 4 | * Created by benny on 11/1/16. 5 | */ 6 | data class User(val login: String, val id: Long, val avatar_url: String){ 7 | override fun toString(): String { 8 | return login 9 | } 10 | } -------------------------------------------------------------------------------- /code/Kt09/build.gradle: -------------------------------------------------------------------------------- 1 | group 'net.println' 2 | version '1.0-SNAPSHOT' 3 | 4 | buildscript { 5 | ext.kotlin_version = '1.0.4' 6 | 7 | repositories { 8 | mavenCentral() 9 | } 10 | dependencies { 11 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 12 | } 13 | } 14 | 15 | apply plugin: 'java' 16 | apply plugin: 'kotlin' 17 | 18 | sourceCompatibility = 1.5 19 | 20 | repositories { 21 | mavenCentral() 22 | } 23 | 24 | dependencies { 25 | compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 26 | compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" 27 | testCompile group: 'junit', name: 'junit', version: '4.11' 28 | } 29 | -------------------------------------------------------------------------------- /code/Kt09/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/code/Kt09/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /code/Kt09/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Nov 04 08:40:27 CST 2016 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.13-bin.zip 7 | -------------------------------------------------------------------------------- /code/Kt09/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn ( ) { 37 | echo "$*" 38 | } 39 | 40 | die ( ) { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /code/Kt09/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /code/Kt09/src/main/java/net/println/kt09/Tailrec.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt09 2 | 3 | import java.math.BigInteger 4 | 5 | /** 6 | * Created by benny on 11/6/16. 7 | */ 8 | class Result(var value: BigInteger = BigInteger.valueOf(1L)) 9 | 10 | 11 | tailrec fun factorial(num: Int, result: Result){ 12 | if(num == 0) result.value = result.value.times(BigInteger.valueOf(1L)) 13 | else { 14 | result.value = result.value.times(BigInteger.valueOf(num.toLong())) 15 | factorial(num - 1, result) 16 | } 17 | } 18 | 19 | fun main(args: Array) { 20 | val result = Result() 21 | factorial(1000000, result) 22 | println(result.value) 23 | } -------------------------------------------------------------------------------- /code/Kt10/build.gradle: -------------------------------------------------------------------------------- 1 | group 'net.println' 2 | version '1.0-SNAPSHOT' 3 | 4 | buildscript { 5 | ext.kotlin_version = '1.0.4' 6 | 7 | repositories { 8 | mavenCentral() 9 | } 10 | dependencies { 11 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 12 | } 13 | } 14 | 15 | apply plugin: 'java' 16 | apply plugin: 'kotlin' 17 | 18 | sourceCompatibility = 1.5 19 | 20 | repositories { 21 | mavenCentral() 22 | } 23 | 24 | dependencies { 25 | compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 26 | testCompile group: 'junit', name: 'junit', version: '4.11' 27 | } 28 | -------------------------------------------------------------------------------- /code/Kt10/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/code/Kt10/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /code/Kt10/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sat Nov 12 22:19:31 CST 2016 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.13-bin.zip 7 | -------------------------------------------------------------------------------- /code/Kt10/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /code/Kt10/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'Kt10' 2 | 3 | -------------------------------------------------------------------------------- /code/Kt10/src/main/java/net/println/kt10/java/LazyNotThreadSafe.java: -------------------------------------------------------------------------------- 1 | package net.println.kt10.java; 2 | 3 | /** 4 | * Created by benny on 11/13/16. 5 | */ 6 | public class LazyNotThreadSafe { 7 | private static LazyNotThreadSafe INSTANCE; 8 | 9 | private LazyNotThreadSafe(){} 10 | 11 | public static LazyNotThreadSafe getInstance(){ 12 | if(INSTANCE == null){ 13 | INSTANCE = new LazyNotThreadSafe(); 14 | } 15 | return INSTANCE; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /code/Kt10/src/main/java/net/println/kt10/java/LazyThreadSafeDoubleCheck.java: -------------------------------------------------------------------------------- 1 | package net.println.kt10.java; 2 | 3 | /** 4 | * Created by benny on 11/13/16. 5 | */ 6 | public class LazyThreadSafeDoubleCheck { 7 | private static volatile LazyThreadSafeDoubleCheck INSTANCE; 8 | 9 | private LazyThreadSafeDoubleCheck(){} 10 | 11 | public static LazyThreadSafeDoubleCheck getInstance(){ 12 | if(INSTANCE == null){ 13 | synchronized (LazyThreadSafeDoubleCheck.class){ 14 | if(INSTANCE == null) { 15 | //初始化时分为实例化和赋值两步, 尽管我们把这一步写成下面的语句, 16 | // 但Java虚拟机并不保证其他线程『眼中』这两步的顺序究竟是怎么样的 17 | INSTANCE = new LazyThreadSafeDoubleCheck(); 18 | } 19 | } 20 | } 21 | return INSTANCE; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /code/Kt10/src/main/java/net/println/kt10/java/LazyThreadSafeStaticInnerClass.java: -------------------------------------------------------------------------------- 1 | package net.println.kt10.java; 2 | 3 | /** 4 | * Created by benny on 11/13/16. 5 | */ 6 | public class LazyThreadSafeStaticInnerClass { 7 | 8 | private static class Holder{ 9 | private static LazyThreadSafeStaticInnerClass INSTANCE = new LazyThreadSafeStaticInnerClass(); 10 | } 11 | 12 | private LazyThreadSafeStaticInnerClass(){} 13 | 14 | public static LazyThreadSafeStaticInnerClass getInstance(){ 15 | return Holder.INSTANCE; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /code/Kt10/src/main/java/net/println/kt10/java/LazyThreadSafeSynchronized.java: -------------------------------------------------------------------------------- 1 | package net.println.kt10.java; 2 | 3 | /** 4 | * Created by benny on 11/13/16. 5 | */ 6 | public class LazyThreadSafeSynchronized { 7 | private static LazyThreadSafeSynchronized INSTANCE; 8 | 9 | private LazyThreadSafeSynchronized(){} 10 | 11 | public static synchronized LazyThreadSafeSynchronized getInstance(){ 12 | if(INSTANCE == null){ 13 | INSTANCE = new LazyThreadSafeSynchronized(); 14 | } 15 | return INSTANCE; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /code/Kt10/src/main/java/net/println/kt10/java/PlainOldSingleton.java: -------------------------------------------------------------------------------- 1 | package net.println.kt10.java; 2 | 3 | /** 4 | * Created by benny on 11/13/16. 5 | */ 6 | public class PlainOldSingleton { 7 | private static PlainOldSingleton INSTANCE = new PlainOldSingleton(); 8 | 9 | private PlainOldSingleton(){ 10 | System.out.println("PlainOldSingleton"); 11 | } 12 | 13 | public static PlainOldSingleton getInstance(){ 14 | return INSTANCE; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /code/Kt10/src/main/kotlin/net/println/kt10/kotlin/LazyNotThreadSafe.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt10.kotlin 2 | 3 | /** 4 | * Created by benny on 11/13/16. 5 | */ 6 | class LazyNotThreadSafe { 7 | 8 | companion object{ 9 | val instance by lazy(LazyThreadSafetyMode.NONE) { 10 | LazyNotThreadSafe() 11 | } 12 | 13 | //下面是另一种等价的写法, 获取单例使用 get 方法 14 | private var instance2: LazyNotThreadSafe? = null 15 | 16 | fun get() : LazyNotThreadSafe { 17 | if(instance2 == null){ 18 | instance2 = LazyNotThreadSafe() 19 | } 20 | return instance2!! 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /code/Kt10/src/main/kotlin/net/println/kt10/kotlin/LazyThreadSafeDoubleCheck.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt10.kotlin 2 | 3 | /** 4 | * Created by benny on 11/13/16. 5 | */ 6 | class LazyThreadSafeDoubleCheck private constructor(){ 7 | companion object{ 8 | val instance by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED){ 9 | LazyThreadSafeDoubleCheck() 10 | } 11 | 12 | private @Volatile var instance2: LazyThreadSafeDoubleCheck? = null 13 | 14 | fun get(): LazyThreadSafeDoubleCheck { 15 | if(instance2 == null){ 16 | synchronized(this){ 17 | if(instance2 == null) 18 | instance2 = LazyThreadSafeDoubleCheck() 19 | } 20 | } 21 | return instance2!! 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /code/Kt10/src/main/kotlin/net/println/kt10/kotlin/LazyThreadSafeStaticInnerObject.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt10.kotlin 2 | 3 | /** 4 | * Created by benny on 11/13/16. 5 | */ 6 | class LazyThreadSafeStaticInnerObject private constructor(){ 7 | companion object{ 8 | fun getInstance() = Holder.instance 9 | } 10 | 11 | private object Holder{ 12 | val instance = LazyThreadSafeStaticInnerObject() 13 | } 14 | } -------------------------------------------------------------------------------- /code/Kt10/src/main/kotlin/net/println/kt10/kotlin/LazyThreadSafeSynchronized.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt10.kotlin 2 | 3 | /** 4 | * Created by benny on 11/13/16. 5 | */ 6 | class LazyThreadSafeSynchronized private constructor() { 7 | companion object { 8 | private var instance: LazyThreadSafeSynchronized? = null 9 | 10 | @Synchronized 11 | fun get(): LazyThreadSafeSynchronized{ 12 | if(instance == null) instance = LazyThreadSafeSynchronized() 13 | return instance!! 14 | } 15 | } 16 | 17 | } -------------------------------------------------------------------------------- /code/Kt10/src/main/kotlin/net/println/kt10/kotlin/PlainOldSingleton.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt10.kotlin 2 | 3 | /** 4 | * Created by benny on 11/13/16. 5 | */ 6 | object PlainOldSingleton { 7 | 8 | } -------------------------------------------------------------------------------- /code/Kt11/build.gradle: -------------------------------------------------------------------------------- 1 | group 'net.println' 2 | version '1.0-SNAPSHOT' 3 | 4 | buildscript { 5 | ext.kotlin_version = '1.0.4' 6 | 7 | repositories { 8 | mavenCentral() 9 | } 10 | dependencies { 11 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 12 | } 13 | } 14 | 15 | apply plugin: 'java' 16 | apply plugin: 'kotlin' 17 | 18 | sourceCompatibility = 1.5 19 | 20 | repositories { 21 | jcenter() 22 | } 23 | 24 | dependencies { 25 | compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 26 | testCompile group: 'junit', name: 'junit', version: '4.11' 27 | } 28 | -------------------------------------------------------------------------------- /code/Kt11/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/code/Kt11/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /code/Kt11/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sun Nov 20 13:30:26 CST 2016 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.13-bin.zip 7 | -------------------------------------------------------------------------------- /code/Kt11/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /code/Kt11/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'Kt11' 2 | 3 | -------------------------------------------------------------------------------- /code/Kt11/src/main/kotlin/net/println/kt11/Main.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt11 2 | 3 | /** 4 | * Created by benny on 11/27/16. 5 | */ 6 | fun main(args: Array) { 7 | val player: Player = Player() 8 | player.play("http://ws.stream.qqmusic.qq.com/C2000012Ppbd3hjGOK.m4a") 9 | player.pause() 10 | player.resume() 11 | player.seekTo(30000) 12 | player.stop() 13 | } -------------------------------------------------------------------------------- /code/Kt11/src/main/kotlin/net/println/kt11/Player.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt11 2 | 3 | import kotlin.properties.Delegates 4 | 5 | /** 6 | * Created by benny on 11/20/16. 7 | */ 8 | class Player { 9 | private var state: State by Delegates.observable(State.IDLE, { prop, old, new -> 10 | println("$old -> $new") 11 | onPlayerStateChangedListener?.onStateChanged(old, new) 12 | }) 13 | 14 | private fun sendCmd(cmd: PlayerCmd) { 15 | when (cmd) { 16 | is PlayerCmd.Play -> { 17 | println("\nPlay ${cmd.url} from ${cmd.position}ms") 18 | state = State.PLAYING 19 | doPlay(cmd.url, cmd.position) 20 | } 21 | is PlayerCmd.Resume -> { 22 | println("\nResume. ") 23 | state = State.PLAYING 24 | doResume() 25 | } 26 | is PlayerCmd.Pause -> { 27 | println("\nPause. ") 28 | state = State.PAUSED 29 | doPause() 30 | } 31 | is PlayerCmd.Stop -> { 32 | println("\nStop.") 33 | state = State.IDLE 34 | doStop() 35 | } 36 | is PlayerCmd.Seek -> { 37 | println("\nSeek to ${cmd.position}ms, state: $state") 38 | } 39 | } 40 | } 41 | 42 | private fun doPlay(url: String, position: Long) { 43 | TODO("Play function not yet implemented") 44 | } 45 | 46 | private fun doResume(){ 47 | //todo 48 | } 49 | 50 | private fun doPause() { 51 | //todo 52 | } 53 | 54 | private fun doStop() { 55 | //todo 56 | } 57 | 58 | //region api 59 | interface OnPlayerStateChangedListener { 60 | fun onStateChanged(oldState: State, new: State) 61 | } 62 | 63 | var onPlayerStateChangedListener: OnPlayerStateChangedListener? = null 64 | 65 | fun play(url: String, position: Long = 0) { 66 | sendCmd(PlayerCmd.Play(url, position)) 67 | } 68 | 69 | fun resume() { 70 | sendCmd(PlayerCmd.Resume) 71 | } 72 | 73 | fun pause() { 74 | sendCmd(PlayerCmd.Pause) 75 | } 76 | 77 | fun stop() { 78 | sendCmd(PlayerCmd.Stop) 79 | } 80 | 81 | fun seekTo(position: Long) { 82 | sendCmd(PlayerCmd.Seek(position)) 83 | } 84 | //endregion 85 | } 86 | -------------------------------------------------------------------------------- /code/Kt11/src/main/kotlin/net/println/kt11/PlayerCmd.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt11 2 | 3 | /** 4 | * Created by benny on 11/27/16. 5 | */ 6 | sealed class PlayerCmd { 7 | class Play(val url: String, val position: Long = 0): PlayerCmd() 8 | 9 | class Seek(val position: Long): PlayerCmd() 10 | 11 | object Pause: PlayerCmd() 12 | 13 | object Resume: PlayerCmd() 14 | 15 | object Stop: PlayerCmd() 16 | } -------------------------------------------------------------------------------- /code/Kt11/src/main/kotlin/net/println/kt11/State.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt11 2 | 3 | /** 4 | * Created by benny on 11/27/16. 5 | */ 6 | enum class State { 7 | IDLE, PAUSED, PLAYING 8 | } -------------------------------------------------------------------------------- /code/Kt12/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public class Program 4 | { 5 | public static void Main(String[] args) 6 | { 7 | testGeneric(); 8 | } 9 | 10 | public static void testGeneric(){ 11 | Console.WriteLine(typeof(T)); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /code/Kt12/build.gradle: -------------------------------------------------------------------------------- 1 | group 'net.println' 2 | version '1.0-SNAPSHOT' 3 | 4 | buildscript { 5 | ext.kotlin_version = '1.0.4' 6 | 7 | repositories { 8 | mavenCentral() 9 | } 10 | dependencies { 11 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 12 | } 13 | } 14 | 15 | apply plugin: 'java' 16 | apply plugin: 'kotlin' 17 | 18 | sourceCompatibility = 1.6 19 | targetCompatibility = 1.6 20 | repositories { 21 | jcenter() 22 | } 23 | 24 | dependencies { 25 | compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 26 | compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" 27 | compile "com.google.code.gson:gson:2.7" 28 | testCompile group: 'junit', name: 'junit', version: '4.11' 29 | } 30 | -------------------------------------------------------------------------------- /code/Kt12/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/code/Kt12/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /code/Kt12/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Nov 28 22:47:53 CST 2016 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.13-bin.zip 7 | -------------------------------------------------------------------------------- /code/Kt12/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /code/Kt12/result_singer.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 0, 3 | "message": "ok", 4 | "content": { 5 | "id": 1, 6 | "name": "Unknown", 7 | "songs": [ 8 | { 9 | "id": 0, 10 | "name": "Rada" 11 | }, 12 | { 13 | "id": 1, 14 | "name": "Olympic Dream" 15 | }, 16 | { 17 | "id": 2, 18 | "name": "The Escapist" 19 | } 20 | ] 21 | } 22 | } -------------------------------------------------------------------------------- /code/Kt12/result_singer_field_loss.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 0, 3 | "message": "ok", 4 | "content": { 5 | "id": 1 6 | } 7 | } -------------------------------------------------------------------------------- /code/Kt12/result_songs.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 0, 3 | "message": "ok", 4 | "content": [ 5 | { 6 | "id": 0, 7 | "name": "Rada" 8 | }, 9 | { 10 | "id": 1, 11 | "name": "Olympic Dream" 12 | }, 13 | { 14 | "id": 2, 15 | "name": "The Escapist" 16 | } 17 | ] 18 | } -------------------------------------------------------------------------------- /code/Kt12/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'Kt12' 2 | 3 | -------------------------------------------------------------------------------- /code/Kt12/singer.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 1, 3 | "name": "Unknown", 4 | "songs": [ 5 | { 6 | "id": 0, 7 | "name": "Rada" 8 | }, 9 | { 10 | "id": 1, 11 | "name": "Olympic Dream" 12 | }, 13 | { 14 | "id": 2, 15 | "name": "The Escapist" 16 | } 17 | ] 18 | } -------------------------------------------------------------------------------- /code/Kt12/src/main/java/net/println/kt12/Main.java: -------------------------------------------------------------------------------- 1 | package net.println.kt12; 2 | 3 | /** 4 | * Created by benny on 12/4/16. 5 | */ 6 | public class Main { 7 | public static void main(String... args) { 8 | 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /code/Kt12/src/main/kotlin/net/println/kt12/Api.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt12 2 | 3 | import com.google.gson.Gson 4 | import com.google.gson.reflect.TypeToken 5 | import java.lang.reflect.Proxy 6 | 7 | /** 8 | * Created by benny on 12/4/16. 9 | */ 10 | interface Api { 11 | fun getSingerFromJson(json: String): BaseResult 12 | } 13 | 14 | object ApiFactory { 15 | val api: Api by lazy { 16 | Proxy.newProxyInstance(ApiFactory.javaClass.classLoader, arrayOf(Api::class.java)) { 17 | proxy, method, args -> 18 | val responseType = method.genericReturnType 19 | val adapter = Gson().getAdapter(TypeToken.get(responseType)) 20 | adapter.fromJson(args[0].toString()) 21 | } as Api 22 | } 23 | } -------------------------------------------------------------------------------- /code/Kt12/src/main/kotlin/net/println/kt12/Data.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt12 2 | 3 | /** 4 | * Created by benny on 12/1/16. 5 | */ 6 | data class BaseResult(val code: Int, val message: String, val content: Content) 7 | 8 | data class Song(val id: Long, val name: String) 9 | 10 | data class Singer(val id: Long, val name: String, val songs: List) 11 | -------------------------------------------------------------------------------- /code/Kt12/src/main/kotlin/net/println/kt12/GsonExt.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt12 2 | 3 | import com.google.gson.Gson 4 | 5 | inline fun Gson.fromJson(json: String): T{ 6 | return fromJson(json, T::class.java) 7 | } -------------------------------------------------------------------------------- /code/Kt12/src/main/kotlin/net/println/kt12/Main.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt12 2 | 3 | import java.io.File 4 | 5 | /** 6 | * Created by benny on 12/1/16. 7 | */ 8 | fun main(args: Array) { 9 | val json = File("result_singer_field_loss.json").readText() 10 | val result : BaseResult = ApiFactory.api.getSingerFromJson(json) 11 | println(result.content.name.isEmpty()) 12 | } -------------------------------------------------------------------------------- /code/Kt13/build.gradle: -------------------------------------------------------------------------------- 1 | group 'net.println' 2 | version '1.0-SNAPSHOT' 3 | 4 | buildscript { 5 | ext.kotlin_version = '1.0.5-2' 6 | ext.dagger_version = "2.8" 7 | ext.retrofit_version = "2.1.0" 8 | 9 | repositories { 10 | jcenter() 11 | } 12 | dependencies { 13 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 14 | } 15 | } 16 | 17 | apply plugin: 'kotlin' 18 | apply plugin: 'kotlin-kapt' 19 | 20 | sourceCompatibility = 1.5 21 | 22 | repositories { 23 | jcenter() 24 | } 25 | 26 | sourceSets { 27 | main.java.srcDirs += [file("$buildDir/generated/source/kapt2/main")] 28 | } 29 | 30 | dependencies { 31 | compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 32 | 33 | compile "com.squareup.retrofit2:retrofit:$retrofit_version" 34 | compile "com.squareup.retrofit2:converter-gson:$retrofit_version" 35 | compile "com.squareup.retrofit2:adapter-rxjava:$retrofit_version" 36 | 37 | compile "com.google.dagger:dagger:${dagger_version}" 38 | kapt "com.google.dagger:dagger-compiler:${dagger_version}" 39 | 40 | testCompile group: 'junit', name: 'junit', version: '4.11' 41 | } 42 | -------------------------------------------------------------------------------- /code/Kt13/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/code/Kt13/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /code/Kt13/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Nov 28 22:47:53 CST 2016 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.13-bin.zip 7 | -------------------------------------------------------------------------------- /code/Kt13/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /code/Kt13/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'Kt13' 2 | 3 | -------------------------------------------------------------------------------- /code/Kt13/src/main/kotlin/net/println/kt13/RESTFulComponent.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt13 2 | 3 | import dagger.Component 4 | import net.println.kt13.module.RetrofitModule 5 | import retrofit2.Retrofit 6 | import javax.inject.Singleton 7 | 8 | /** 9 | * Created by benny on 12/11/16. 10 | */ 11 | @Singleton 12 | @Component(modules = arrayOf(RetrofitModule::class)) 13 | interface RESTFulComponent { 14 | fun retrofit(): Retrofit 15 | } -------------------------------------------------------------------------------- /code/Kt13/src/main/kotlin/net/println/kt13/Service.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt08 2 | 3 | import net.println.kt13.DaggerRESTFulComponent 4 | import retrofit2.Call 5 | import retrofit2.http.GET 6 | import retrofit2.http.Query 7 | 8 | /** 9 | * Created by benny on 11/1/16. 10 | */ 11 | interface GitHubService{ 12 | 13 | @GET("/repos/enbandari/Kotlin-Tutorials/stargazers") 14 | fun getStarGazers(@Query("page") page: Int = 1, @Query("per_page") pageSize: Int = 20): Call> 15 | } 16 | 17 | object Service { 18 | val api: GitHubService by lazy { 19 | DaggerRESTFulComponent 20 | .builder() 21 | .build() 22 | .retrofit() 23 | .create(GitHubService::class.java) 24 | } 25 | } 26 | 27 | fun main(args: Array) { 28 | Service.api.getStarGazers().execute().body().map(::println) 29 | } -------------------------------------------------------------------------------- /code/Kt13/src/main/kotlin/net/println/kt13/User.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt08 2 | 3 | /** 4 | * Created by benny on 11/1/16. 5 | */ 6 | data class User(val login: String, val id: Long, val avatar_url: String){ 7 | override fun toString(): String { 8 | return login 9 | } 10 | } -------------------------------------------------------------------------------- /code/Kt13/src/main/kotlin/net/println/kt13/config/Settings.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt13.config 2 | 3 | /** 4 | * Created by benny on 12/11/16. 5 | */ 6 | object Settings { 7 | 8 | const val DEBUG = true 9 | 10 | } -------------------------------------------------------------------------------- /code/Kt13/src/main/kotlin/net/println/kt13/module/BaseUrlModule.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt13.module 2 | 3 | import dagger.Module 4 | import dagger.Provides 5 | import net.println.kt13.config.Settings 6 | import javax.inject.Singleton 7 | 8 | /** 9 | * Created by benny on 12/11/16. 10 | */ 11 | @Module 12 | class BaseUrlModule { 13 | companion object{ 14 | //测试环境 15 | const val DEBUG_URL = "https://api.github.com" 16 | 17 | //线上环境 18 | const val RELEASE_URL = "https://api.github.com" 19 | } 20 | 21 | @Singleton @Provides fun baseUrl(): String = if(Settings.DEBUG) DEBUG_URL else RELEASE_URL 22 | } -------------------------------------------------------------------------------- /code/Kt13/src/main/kotlin/net/println/kt13/module/CacheModule.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt13.module 2 | 3 | import dagger.Module 4 | import dagger.Provides 5 | import okhttp3.Cache 6 | import java.io.File 7 | import javax.inject.Singleton 8 | 9 | /** 10 | * Created by benny on 12/11/16. 11 | */ 12 | @Module 13 | class CacheModule { 14 | companion object{ 15 | const val CACHE_DIR = "./cache" 16 | const val CACHE_SIZE = 10 * 1024 * 1024L 17 | } 18 | 19 | @Singleton @Provides fun cache(): Cache = Cache(File(CACHE_DIR), CACHE_SIZE) 20 | } -------------------------------------------------------------------------------- /code/Kt13/src/main/kotlin/net/println/kt13/module/GsonConverterModule.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt13.module 2 | 3 | import com.google.gson.Gson 4 | import dagger.Module 5 | import dagger.Provides 6 | import retrofit2.Converter 7 | import retrofit2.converter.gson.GsonConverterFactory 8 | import javax.inject.Singleton 9 | 10 | /** 11 | * Created by benny on 12/11/16. 12 | */ 13 | @Module(includes = arrayOf(GsonModule::class)) 14 | class GsonConverterModule { 15 | @Singleton @Provides fun converter(gson: Gson): Converter.Factory = GsonConverterFactory.create(gson) 16 | } -------------------------------------------------------------------------------- /code/Kt13/src/main/kotlin/net/println/kt13/module/GsonModule.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt13.module 2 | 3 | import com.google.gson.Gson 4 | import dagger.Module 5 | import dagger.Provides 6 | import javax.inject.Singleton 7 | 8 | /** 9 | * Created by benny on 12/11/16. 10 | */ 11 | @Module 12 | class GsonModule { 13 | 14 | @Singleton @Provides fun gson(): Gson = Gson() 15 | } -------------------------------------------------------------------------------- /code/Kt13/src/main/kotlin/net/println/kt13/module/OkHttpClientModule.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt13.module 2 | 3 | import dagger.Module 4 | import dagger.Provides 5 | import okhttp3.Cache 6 | import okhttp3.OkHttpClient 7 | import javax.inject.Singleton 8 | 9 | /** 10 | * Created by benny on 12/11/16. 11 | */ 12 | @Module(includes = arrayOf(CacheModule::class)) 13 | class OkHttpClientModule { 14 | @Singleton @Provides fun okHttpClient(cache: Cache): OkHttpClient 15 | = OkHttpClient.Builder().cache(cache).build() 16 | } -------------------------------------------------------------------------------- /code/Kt13/src/main/kotlin/net/println/kt13/module/RetrofitModule.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt13.module 2 | 3 | import dagger.Module 4 | import dagger.Provides 5 | import okhttp3.OkHttpClient 6 | import retrofit2.CallAdapter 7 | import retrofit2.Converter 8 | import retrofit2.Retrofit 9 | import javax.inject.Singleton 10 | 11 | /** 12 | * Created by benny on 12/11/16. 13 | */ 14 | @Module(includes = arrayOf(GsonConverterModule::class, OkHttpClientModule::class, RxAdapterModule::class, BaseUrlModule::class)) 15 | class RetrofitModule { 16 | @Singleton @Provides fun retrofit( 17 | baseUrl: String, 18 | okHttpClient: OkHttpClient, 19 | adapterFactory: CallAdapter.Factory, 20 | converterFactory: Converter.Factory): Retrofit 21 | = Retrofit.Builder() 22 | .baseUrl(baseUrl) 23 | .addCallAdapterFactory(adapterFactory) 24 | .addConverterFactory(converterFactory) 25 | .client(okHttpClient).build() 26 | } -------------------------------------------------------------------------------- /code/Kt13/src/main/kotlin/net/println/kt13/module/RxAdapterModule.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt13.module 2 | 3 | import dagger.Module 4 | import dagger.Provides 5 | import retrofit2.CallAdapter 6 | import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory 7 | import javax.inject.Singleton 8 | 9 | /** 10 | * Created by benny on 12/11/16. 11 | */ 12 | @Module 13 | class RxAdapterModule { 14 | @Singleton @Provides fun adapter(): CallAdapter.Factory = RxJavaCallAdapterFactory.create() 15 | } -------------------------------------------------------------------------------- /code/Kt14/Kt14/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | apply plugin: 'kotlin' 3 | 4 | sourceCompatibility = 1.5 5 | 6 | dependencies { 7 | compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 8 | testCompile group: 'junit', name: 'junit', version: '4.11' 9 | } 10 | -------------------------------------------------------------------------------- /code/Kt14/Kt14/src/main/java/net/println/kt14/AccessToObject.java: -------------------------------------------------------------------------------- 1 | package net.println.kt14; 2 | 3 | /** 4 | * Created by benny on 12/18/16. 5 | */ 6 | public class AccessToObject { 7 | public static void main(String... args) { 8 | Singleton.INSTANCE.printlnHello(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /code/Kt14/Kt14/src/main/java/net/println/kt14/AccessToOverloads.java: -------------------------------------------------------------------------------- 1 | package net.println.kt14; 2 | 3 | /** 4 | * Created by benny on 12/18/16. 5 | */ 6 | public class AccessToOverloads { 7 | public static void main(String... args) { 8 | Overloads overloads = new Overloads(); 9 | overloads.overloaded(1, 2, 3); 10 | overloads.overloaded(1); 11 | overloads.overloaded(1,3); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /code/Kt14/Kt14/src/main/java/net/println/kt14/CallExtenstionMethod.java: -------------------------------------------------------------------------------- 1 | package net.println.kt14; 2 | 3 | /** 4 | * Created by benny on 12/17/16. 5 | */ 6 | public class CallExtenstionMethod { 7 | public static void main(String... args) { 8 | System.out.println(ExtensionMethodKt.notEmpty("Hello")); 9 | } 10 | } -------------------------------------------------------------------------------- /code/Kt14/Kt14/src/main/java/net/println/kt14/CallInternalClass.java: -------------------------------------------------------------------------------- 1 | package net.println.kt14; 2 | 3 | /** 4 | * Created by benny on 12/17/16. 5 | */ 6 | 7 | public class CallInternalClass{ 8 | public static void main(String... args) { 9 | InternalClass internalClass = new InternalClass(); 10 | internalClass.printlnHello$production_sources_for_module_Kt14_Kt14_main(); 11 | } 12 | } -------------------------------------------------------------------------------- /code/Kt14/Kt14/src/main/java/net/println/kt14/CallPackageMethod.java: -------------------------------------------------------------------------------- 1 | package net.println.kt14; 2 | 3 | /** 4 | * Created by benny on 12/17/16. 5 | */ 6 | public class CallPackageMethod{ 7 | public static void main(String... args) { 8 | PackageKt.printlnHello(); 9 | } 10 | } -------------------------------------------------------------------------------- /code/Kt14/Kt14/src/main/java/net/println/kt14/PersonMain.java: -------------------------------------------------------------------------------- 1 | package net.println.kt14; 2 | 3 | /** 4 | * Created by benny on 12/17/16. 5 | */ 6 | public class PersonMain { 7 | public static void main(String... args) { 8 | Person person = new Person("benny", 27); 9 | System.out.println(person.getName() + " is " + person.age); 10 | person.setName("andy"); 11 | person.age = 26; 12 | System.out.println(person.getName() + " is " + person.age); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /code/Kt14/Kt14/src/main/kotlin/net/println/kt14/CallInternalClass.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt14 2 | 3 | /** 4 | * Created by benny on 12/17/16. 5 | */ 6 | fun main(args: Array) { 7 | val internalClass = InternalClass() 8 | internalClass.printlnHello() 9 | } -------------------------------------------------------------------------------- /code/Kt14/Kt14/src/main/kotlin/net/println/kt14/ExtensionMethod.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt14 2 | 3 | /** 4 | * Created by benny on 12/17/16. 5 | */ 6 | fun String.notEmpty(): Boolean{ 7 | return this != "" 8 | } -------------------------------------------------------------------------------- /code/Kt14/Kt14/src/main/kotlin/net/println/kt14/InternalClass.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt14 2 | 3 | /** 4 | * Created by benny on 12/17/16. 5 | */ 6 | internal class InternalClass{ 7 | internal fun printlnHello(){ 8 | println("Hello") 9 | } 10 | } -------------------------------------------------------------------------------- /code/Kt14/Kt14/src/main/kotlin/net/println/kt14/Overloads.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt14 2 | 3 | /** 4 | * Created by benny on 12/18/16. 5 | */ 6 | class Overloads { 7 | @JvmOverloads 8 | fun overloaded(a: Int, b: Int = 0, c: Int = 1){ 9 | println("$a, $b, $c") 10 | } 11 | } -------------------------------------------------------------------------------- /code/Kt14/Kt14/src/main/kotlin/net/println/kt14/Package.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt14 2 | 3 | /** 4 | * Created by benny on 12/17/16. 5 | */ 6 | fun printlnHello(){ 7 | println("Hello") 8 | } 9 | 10 | fun main(args: Array) { 11 | 12 | } -------------------------------------------------------------------------------- /code/Kt14/Kt14/src/main/kotlin/net/println/kt14/Person.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt14 2 | 3 | /** 4 | * Created by benny on 12/17/16. 5 | */ 6 | data class Person(var name:String, @JvmField var age: Int) -------------------------------------------------------------------------------- /code/Kt14/Kt14/src/main/kotlin/net/println/kt14/Singleton.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt14 2 | 3 | /** 4 | * Created by benny on 12/17/16. 5 | */ 6 | object Singleton { 7 | fun printlnHello(){ 8 | println("Hello") 9 | } 10 | } -------------------------------------------------------------------------------- /code/Kt14/build.gradle: -------------------------------------------------------------------------------- 1 | group 'net.println' 2 | version '1.0-SNAPSHOT' 3 | 4 | buildscript { 5 | ext.kotlin_version = '1.0.5-2' 6 | 7 | repositories { 8 | mavenCentral() 9 | } 10 | dependencies { 11 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 12 | } 13 | } 14 | 15 | allprojects { 16 | repositories { 17 | mavenCentral() 18 | } 19 | } -------------------------------------------------------------------------------- /code/Kt14/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/code/Kt14/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /code/Kt14/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sat Dec 17 10:32:19 CST 2016 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.13-bin.zip 7 | -------------------------------------------------------------------------------- /code/Kt14/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /code/Kt14/kt14internal/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | apply plugin: 'kotlin' 3 | 4 | dependencies { 5 | compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 6 | compile project(":Kt14") 7 | testCompile group: 'junit', name: 'junit', version: '4.11' 8 | } 9 | -------------------------------------------------------------------------------- /code/Kt14/kt14internal/src/main/java/net/println/kt14internal/CallInternalClass.java: -------------------------------------------------------------------------------- 1 | package net.println.kt14internal; 2 | 3 | import net.println.kt14.InternalClass; 4 | 5 | /** 6 | * Created by benny on 12/17/16. 7 | */ 8 | public class CallInternalClass { 9 | public static void main(String... args) { 10 | InternalClass internalClass = new InternalClass(); 11 | internalClass.printlnHello$production_sources_for_module_Kt14_Kt14_main(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /code/Kt14/kt14internal/src/main/kotlin/net/println/kt14internal/CallInternalClassKt.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt14internal 2 | 3 | /** 4 | * Created by benny on 12/17/16. 5 | */ 6 | fun main(args: Array) { 7 | // val internalClass = InternalClass() 8 | // internalClass.printHello() 9 | } 10 | -------------------------------------------------------------------------------- /code/Kt14/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':Kt14', ':kt14internal' -------------------------------------------------------------------------------- /code/Kt15/build.gradle: -------------------------------------------------------------------------------- 1 | group 'net.println' 2 | version '1.0-SNAPSHOT' 3 | 4 | buildscript { 5 | ext.kotlin_version = '1.0.5-2' 6 | 7 | repositories { 8 | mavenCentral() 9 | } 10 | dependencies { 11 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 12 | } 13 | } 14 | 15 | apply plugin: 'java' 16 | apply plugin: 'kotlin' 17 | 18 | sourceCompatibility = 1.5 19 | 20 | repositories { 21 | mavenCentral() 22 | } 23 | 24 | dependencies { 25 | compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 26 | testCompile group: 'junit', name: 'junit', version: '4.11' 27 | } 28 | -------------------------------------------------------------------------------- /code/Kt15/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/code/Kt15/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /code/Kt15/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sat Dec 17 21:40:38 CST 2016 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.13-bin.zip 7 | -------------------------------------------------------------------------------- /code/Kt15/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /code/Kt15/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'Kt15' 2 | 3 | -------------------------------------------------------------------------------- /code/Kt15/src/main/java/net/println/kt15/DataClass.java: -------------------------------------------------------------------------------- 1 | package net.println.kt15; 2 | 3 | /** 4 | * Created by benny on 12/17/16. 5 | */ 6 | public class DataClass { 7 | private int id; 8 | 9 | public int getId() { 10 | return id; 11 | } 12 | 13 | public void setId(int id) { 14 | this.id = id; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /code/Kt15/src/main/java/net/println/kt15/Generics.java: -------------------------------------------------------------------------------- 1 | package net.println.kt15; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * Created by benny on 12/17/16. 8 | */ 9 | public class Generics { 10 | 11 | public abstract class View

{ 12 | P presenter; 13 | } 14 | 15 | public abstract class Presenter{ 16 | V view; 17 | } 18 | 19 | public static void main(String... args) { 20 | List list = new ArrayList(); 21 | list.add("Hello"); 22 | list.add(0); 23 | for (Object o : list) { 24 | System.out.println(o); 25 | } 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /code/Kt15/src/main/java/net/println/kt15/NullSafetyAbsClass.java: -------------------------------------------------------------------------------- 1 | package net.println.kt15; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | 5 | import java.text.SimpleDateFormat; 6 | import java.util.Date; 7 | 8 | /** 9 | * Created by benny on 12/17/16. 10 | */ 11 | public abstract class NullSafetyAbsClass { 12 | public abstract String formatDate(Date date); 13 | 14 | public @NotNull String formatTime(@NotNull Date date){ 15 | return new SimpleDateFormat("HH:mm:ss").format(date); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /code/Kt15/src/main/java/net/println/kt15/NullSafetyJava.java: -------------------------------------------------------------------------------- 1 | package net.println.kt15; 2 | 3 | /** 4 | * Created by benny on 12/17/16. 5 | */ 6 | public class NullSafetyJava { 7 | public String getData(){ 8 | return null; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /code/Kt15/src/main/java/net/println/kt15/SAMInJava.java: -------------------------------------------------------------------------------- 1 | package net.println.kt15; 2 | 3 | import java.util.ArrayList; 4 | 5 | /** 6 | * Created by benny on 12/17/16. 7 | */ 8 | public class SAMInJava { 9 | 10 | private ArrayList runnables = new ArrayList(); 11 | 12 | public void addTask(Runnable runnable){ 13 | runnables.add(runnable); 14 | System.out.println("After add: " + runnable + ", we have " + runnables.size() + " in all."); 15 | } 16 | 17 | public void removeTask(Runnable runnable){ 18 | runnables.remove(runnable); 19 | System.out.println("After remove: " + runnable + ", only " + runnables.size() + " left."); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /code/Kt15/src/main/kotlin/net/println/kt15/AccessDataClass.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt15 2 | 3 | /** 4 | * Created by benny on 12/17/16. 5 | */ 6 | fun main(args: Array) { 7 | val dataClass = DataClass() 8 | dataClass.id = 0 9 | println(dataClass.id) 10 | } -------------------------------------------------------------------------------- /code/Kt15/src/main/kotlin/net/println/kt15/ConcurrentRelated.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt15 2 | 3 | /** 4 | * Created by benny on 12/17/16. 5 | */ 6 | @Volatile var count: Int = 0 7 | 8 | fun count(){ 9 | synchronized(count){ 10 | count++ 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /code/Kt15/src/main/kotlin/net/println/kt15/GenericsInKt.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt15 2 | 3 | import java.util.* 4 | 5 | /** 6 | * Created by benny on 12/17/16. 7 | */ 8 | //Kotlin 无法写出这样的代码 9 | //abstract class View

>>{ 10 | // protected abstract val presenter: P 11 | //} 12 | // 13 | //abstract class Presenter>>{ 14 | // protected abstract val view: V 15 | //} 16 | 17 | fun main(args: Array) { 18 | val list = ArrayList() 19 | list.add("Hello") 20 | list.add(0) 21 | list.map(::println) 22 | } -------------------------------------------------------------------------------- /code/Kt15/src/main/kotlin/net/println/kt15/NullSafety.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt15 2 | 3 | /** 4 | * Created by benny on 12/17/16. 5 | */ 6 | fun main(args: Array) { 7 | val nullSafetyJava = NullSafetyJava() 8 | val data: String = nullSafetyJava.data 9 | val dataCanBeNull: String? = nullSafetyJava.data 10 | println(data) 11 | } -------------------------------------------------------------------------------- /code/Kt15/src/main/kotlin/net/println/kt15/NullSafetySubClass.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt15 2 | 3 | import java.util.* 4 | 5 | /** 6 | * Created by benny on 12/17/16. 7 | */ 8 | class NullSafetySubClass : NullSafetyAbsClass(){ 9 | override fun formatDate(date: Date): String { 10 | return date.toString() 11 | } 12 | } 13 | 14 | fun main(args: Array) { 15 | val nullSafetySubClass = NullSafetySubClass() 16 | println(nullSafetySubClass.formatDate(Date())) 17 | println(nullSafetySubClass.formatTime(Date())) 18 | } -------------------------------------------------------------------------------- /code/Kt15/src/main/kotlin/net/println/kt15/SAMConversion.kt: -------------------------------------------------------------------------------- 1 | package net.println.kt15 2 | 3 | /** 4 | * Created by benny on 12/17/16. 5 | */ 6 | fun main(args: Array) { 7 | val samInJava = SAMInJava() 8 | val lambda = { 9 | println("Hello") 10 | } 11 | samInJava.addTask(lambda) 12 | samInJava.addTask(lambda) 13 | samInJava.addTask(lambda) 14 | samInJava.addTask(lambda) 15 | samInJava.addTask(lambda) 16 | 17 | samInJava.removeTask(lambda) 18 | samInJava.removeTask(lambda) 19 | samInJava.removeTask(lambda) 20 | samInJava.removeTask(lambda) 21 | samInJava.removeTask(lambda) 22 | } -------------------------------------------------------------------------------- /code/MyBatisIssue/build.gradle: -------------------------------------------------------------------------------- 1 | group 'net.println.kotlin' 2 | version '1.0-SNAPSHOT' 3 | 4 | buildscript { 5 | ext.kotlin_version = '1.1.0' 6 | 7 | repositories { 8 | mavenCentral() 9 | } 10 | dependencies { 11 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 12 | classpath "org.jetbrains.kotlin:kotlin-noarg:$kotlin_version" 13 | } 14 | } 15 | 16 | apply plugin: 'java' 17 | apply plugin: 'kotlin' 18 | apply plugin: "kotlin-noarg" 19 | 20 | noArg{ 21 | annotation("net.println.kotlin.mybatis.annotations.PoKo") 22 | } 23 | 24 | sourceCompatibility = 1.5 25 | 26 | repositories { 27 | mavenCentral() 28 | } 29 | 30 | dependencies { 31 | compile fileTree(include: ['*.jar'], dir: 'libs') 32 | compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version" 33 | compile "org.mybatis:mybatis:3.4.2" 34 | testCompile group: 'junit', name: 'junit', version: '4.11' 35 | } 36 | -------------------------------------------------------------------------------- /code/MyBatisIssue/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/code/MyBatisIssue/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /code/MyBatisIssue/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sat Mar 25 09:41:11 CST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-3.1-bin.zip 7 | -------------------------------------------------------------------------------- /code/MyBatisIssue/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /code/MyBatisIssue/libs/mysql-connector-java-5.1.40-bin.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enbandari/Kotlin-Tutorials/01c4c7b3716e20be7bade27d0722739181e8d7a3/code/MyBatisIssue/libs/mysql-connector-java-5.1.40-bin.jar -------------------------------------------------------------------------------- /code/MyBatisIssue/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'MyBatisIssue' 2 | 3 | -------------------------------------------------------------------------------- /code/MyBatisIssue/src/main/kotlin/net/println/kotlin/mybatis/Main.java: -------------------------------------------------------------------------------- 1 | package net.println.kotlin.mybatis; 2 | 3 | /** 4 | * Created by benny on 3/26/17. 5 | */ 6 | public class Main { 7 | public static void main(String... args) { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /code/MyBatisIssue/src/main/kotlin/net/println/kotlin/mybatis/Main.kt: -------------------------------------------------------------------------------- 1 | package net.println.kotlin.mybatis 2 | 3 | import org.apache.ibatis.io.Resources 4 | import org.apache.ibatis.session.SqlSessionFactoryBuilder 5 | 6 | 7 | /** 8 | * Created by benny on 3/25/17. 9 | */ 10 | fun main(args: Array) { 11 | val resource = "net/println/kotlin/mybatis/config.xml" 12 | val inputStream = Resources.getResourceAsStream(resource) 13 | val sqlSessionFactory = SqlSessionFactoryBuilder().build(inputStream) 14 | val session = sqlSessionFactory.openSession() 15 | session.use { session -> 16 | val mapper = session.getMapper(UserMapper::class.java) 17 | val user = mapper.selectUser(1) 18 | println(user) 19 | } 20 | } -------------------------------------------------------------------------------- /code/MyBatisIssue/src/main/kotlin/net/println/kotlin/mybatis/TestUnsafe.kt: -------------------------------------------------------------------------------- 1 | package net.println.kotlin.mybatis 2 | 3 | import sun.misc.Unsafe 4 | 5 | /** 6 | * Created by benny on 3/26/17. 7 | */ 8 | 9 | class Test{ 10 | init { 11 | println("init") 12 | } 13 | 14 | companion object{ 15 | init { 16 | println("cinit") 17 | } 18 | } 19 | } 20 | 21 | fun main(args: Array) { 22 | val field = Unsafe::class.java.getDeclaredField("theUnsafe") 23 | field.isAccessible = true 24 | val unsafe = field.get(null) as Unsafe 25 | unsafe.allocateInstance(Test::class.java) 26 | 27 | } -------------------------------------------------------------------------------- /code/MyBatisIssue/src/main/kotlin/net/println/kotlin/mybatis/User.kt: -------------------------------------------------------------------------------- 1 | package net.println.kotlin.mybatis 2 | 3 | import net.println.kotlin.mybatis.annotations.PoKo 4 | 5 | /** 6 | * Created by benny on 3/25/17. 7 | */ 8 | @PoKo 9 | data class User (var id: Int, var username: String = "", var age: Int, var passwd: String = "") 10 | 11 | fun main(args: Array) { 12 | //println(User::class.java.newInstance()) 13 | } -------------------------------------------------------------------------------- /code/MyBatisIssue/src/main/kotlin/net/println/kotlin/mybatis/UserMapper.java: -------------------------------------------------------------------------------- 1 | package net.println.kotlin.mybatis; 2 | 3 | /** 4 | * Created by benny on 3/25/17. 5 | */ 6 | //@Mapper 7 | public interface UserMapper { 8 | // @Select("SELECT * FROM userinfo WHERE id = #{id}") 9 | User selectUser(int id); 10 | } -------------------------------------------------------------------------------- /code/MyBatisIssue/src/main/kotlin/net/println/kotlin/mybatis/annotations/PoKo.kt: -------------------------------------------------------------------------------- 1 | package net.println.kotlin.mybatis.annotations 2 | 3 | /** 4 | * Created by benny on 3/25/17. 5 | */ 6 | annotation class PoKo -------------------------------------------------------------------------------- /code/MyBatisIssue/src/main/resources/net/println/kotlin/mybatis/UserMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 9 | -------------------------------------------------------------------------------- /code/MyBatisIssue/src/main/resources/net/println/kotlin/mybatis/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /code/MyBatisIssue/src/main/resources/net/println/kotlin/mybatis/db.properties: -------------------------------------------------------------------------------- 1 | driver=com.mysql.jdbc.Driver 2 | url=jdbc:mysql://localhost:3306/User 3 | username=root 4 | password= -------------------------------------------------------------------------------- /code/MyBatisIssue/src/main/resources/net/println/kotlin/mybatis/userinfo.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE userinfo 2 | ( 3 | id INT(11) PRIMARY KEY NOT NULL AUTO_INCREMENT, 4 | username VARCHAR(45), 5 | age INT(11), 6 | passwd VARCHAR(45) 7 | ); -------------------------------------------------------------------------------- /code/RealmIssue/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | -------------------------------------------------------------------------------- /code/RealmIssue/app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /code/RealmIssue/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'kotlin-android' 3 | apply plugin: 'kotlin-android-extensions' 4 | apply plugin: 'realm-android' 5 | apply plugin: "kotlin-allopen" 6 | apply plugin: "kotlin-noarg" 7 | 8 | android { 9 | compileSdkVersion 25 10 | buildToolsVersion "25.0.2" 11 | defaultConfig { 12 | applicationId "net.println.kotlin.realm" 13 | minSdkVersion 16 14 | targetSdkVersion 25 15 | versionCode 1 16 | versionName "1.0" 17 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 18 | } 19 | buildTypes { 20 | release { 21 | minifyEnabled false 22 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 23 | } 24 | } 25 | } 26 | 27 | allOpen { 28 | annotation("net.println.kotlin.realm.PoKo") 29 | } 30 | 31 | noArg { 32 | annotation("net.println.kotlin.realm.PoKo") 33 | } 34 | 35 | 36 | dependencies { 37 | compile fileTree(dir: 'libs', include: ['*.jar']) 38 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 39 | exclude group: 'com.android.support', module: 'support-annotations' 40 | }) 41 | compile 'com.android.support:appcompat-v7:25.3.1' 42 | compile 'com.android.support.constraint:constraint-layout:1.0.2' 43 | testCompile 'junit:junit:4.12' 44 | compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" 45 | } 46 | -------------------------------------------------------------------------------- /code/RealmIssue/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in C:\Users\kanade\AppData\Local\Android\Sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /code/RealmIssue/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /code/RealmIssue/app/src/main/java/net/println/kotlin/realm/App.kt: -------------------------------------------------------------------------------- 1 | package net.println.kotlin.realm 2 | 3 | import android.app.Application 4 | 5 | import io.realm.Realm 6 | import io.realm.RealmConfiguration 7 | 8 | class App : Application() { 9 | override fun onCreate() { 10 | super.onCreate() 11 | Realm.init(this) 12 | Realm.setDefaultConfiguration( 13 | RealmConfiguration.Builder() 14 | .deleteRealmIfMigrationNeeded() 15 | .schemaVersion(1) 16 | .build()) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /code/RealmIssue/app/src/main/java/net/println/kotlin/realm/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package net.println.kotlin.realm 2 | 3 | import android.os.Bundle 4 | import android.support.v7.app.AppCompatActivity 5 | import android.util.Log 6 | import io.realm.Realm 7 | import kotlinx.android.synthetic.main.activity_main.* 8 | 9 | class MainActivity : AppCompatActivity() { 10 | companion object{ 11 | const val TAG = "KotlinRealm" 12 | } 13 | 14 | override fun onCreate(savedInstanceState: Bundle?) { 15 | super.onCreate(savedInstanceState) 16 | setContentView(R.layout.activity_main) 17 | add.setOnClickListener { 18 | Realm.getDefaultInstance().use { 19 | it.beginTransaction() 20 | val d = it.createObject(User::class.java, it.where(User::class.java).count()) 21 | d.name = "User ${d.id}" 22 | it.commitTransaction() 23 | } 24 | 25 | } 26 | 27 | query.setOnClickListener { 28 | Realm.getDefaultInstance().use { 29 | it.where(User::class.java).findAll().map { 30 | Log.d(TAG, it.toString()) 31 | } 32 | } 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /code/RealmIssue/app/src/main/java/net/println/kotlin/realm/PoKo.kt: -------------------------------------------------------------------------------- 1 | package net.println.kotlin.realm 2 | 3 | annotation class PoKo 4 | -------------------------------------------------------------------------------- /code/RealmIssue/app/src/main/java/net/println/kotlin/realm/User.kt: -------------------------------------------------------------------------------- 1 | package net.println.kotlin.realm 2 | 3 | import io.realm.RealmObject 4 | import io.realm.annotations.PrimaryKey 5 | 6 | @PoKo 7 | data class User(@PrimaryKey var id: Int, var name: String) : RealmObject() -------------------------------------------------------------------------------- /code/RealmIssue/app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 |