博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
第2章 快速开始:HelloWorld 《Kotlin 极简教程》
阅读量:5746 次
发布时间:2019-06-18

本文共 22995 字,大约阅读时间需要 76 分钟。

hot3.png

第2章 快速开始:HelloWorld 《Kotlin 极简教程》

“Hello, World"程序是指在计算机屏幕上输出“Hello,world”这行字符串的计算机程序,“hello, world”的中文意思是“世界,你好”。这个程序在Brian Kernighan 和Dennis M. Ritchie合著的《The C Programme Language》使用而广泛流行。因为它的简洁、实用,表达了一个编程语言的极简功能。

我们在本章将介绍使用Kotlin程序设计语言**,分别使用命令行、应用程序、Web RESTFul、Android、Kotlin JavaScript等方式向世界问好:你好,世界。

2.1 命令行版HelloWorld

安装配置完Kotlin命令行环境之后,我们直接命令行输入kotlinc, 即可进入 Kotlin REPL界面。

$ kotlincWelcome to Kotlin version 1.1.2-2 (JRE 1.8.0_40-b27)Type :help for help, :quit for quit>>> println("Hello,World!")Hello,World!>>> import java.util.Date>>> Date()Wed Jun 07 14:19:33 CST 2017

2.2 应用程序版HelloWorld

我们如果想拥有学习Kotlin的相对较好的体验,就不建议使用eclipse了。毕竟Kotlin是JetBrains家族的亲儿子,跟Intelli IDEA是血浓于水啊。

我们使用IDEA新建gradle项目,选择Java,Kotlin(Java)框架支持,如下图:

新建完项目,我们写一个HelloWorld.kt类

package com.easy.kotlin/** * Created by jack on 2017/5/29. */import java.util.Dateimport java.text.SimpleDateFormatfun main(args: Array
) { println("Hello, world!") println(SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date()))}

整体的项目目录结构如下

.├── README.md├── build│   ├── classes│   │   └── main│   │       ├── META-INF│   │       │   └── easykotlin_main.kotlin_module│   │       └── com│   │           └── easy│   │               └── kotlin│   │                   └── HelloWorldKt.class│   └── kotlin-build│       └── caches│           └── version.txt├── build.gradle├── settings.gradle└── src    ├── main    │   ├── java    │   ├── kotlin    │   │   └── com    │   │       └── easy    │   │           └── kotlin    │   │               └── HelloWorld.kt    │   └── resources    └── test        ├── java        ├── kotlin        └── resources21 directories, 7 files

直接运行HelloWorld.kt,输出结果如下

Hello, world!2017-05-29 01:15:30

关于工程的编译、构建、运行,是由gradle协同kotlin-gradle-plugin,在kotlin-stdlib-jre8,kotlin-stdlib核心依赖下完成的。build.gradle配置文件如下:

group 'com.easy.kotlin'version '1.0-SNAPSHOT'buildscript {    ext.kotlin_version = '1.1.1'    repositories {        mavenCentral()    }    dependencies {        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"    }}apply plugin: 'java'apply plugin: 'kotlin'sourceCompatibility = 1.8repositories {    mavenCentral()}dependencies {    compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version"    testCompile group: 'junit', name: 'junit', version: '4.12'}

工程源码地址:

2.3 Web RESTFul HelloWorld

本节介绍使用 Kotlin 结合 SpringBoot 开发一个RESTFul版本的 Hello.World

  1. 新建gradle,kotlin工程:

打开IDEA的File > New > Project , 如下图

螢幕快照 2017-03-11 12.40.05.png

按照界面操作,输入相应的工程名等信息,即可新建一个使用Gradle构建的标准Kotlin工程。

  1. build.gradle 基本配置

IDEA自动生成的Gradle配置文件如下:

group 'com.easy.kotlin'version '1.0-SNAPSHOT'buildscript {    ext.kotlin_version = '1.1.2-2'        repositories {        mavenCentral()    }    dependencies {//        Kotlin Gradle插件        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"    }}apply plugin: 'java'apply plugin: 'kotlin'sourceCompatibility = 1.8targetCompatibility = 1.8repositories {    mavenCentral()}dependencies {    compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version"    testCompile group: 'junit', name: 'junit', version: '4.12'}

从上面的配置文件我们可以看出,IDEA已经自动把Gradle 构建Kotlin工程插件 kotlin-gradle-plugin,以及Kotlin标准库kotlin-stdlib添加到配置文件中了。

  1. 配置SpringBoot相关内容

下面我们来配置SpringBoot相关内容。首先在构建脚本里面添加ext变量springBootVersion。

ext.kotlin_version = '1.1.2-2'ext.springboot_version = '1.5.2.RELEASE'

然后在构建依赖里添加spring-boot-gradle-plugin

buildscript {...    dependencies {//        Kotlin Gradle插件        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"//        SpringBoot Gradle插件        classpath("org.springframework.boot:spring-boot-gradle-plugin:$springboot_version")//        Kotlin整合SpringBoot的默认无参构造函数,默认把所有的类设置open类插件        classpath("org.jetbrains.kotlin:kotlin-noarg:$kotlin_version")        classpath("org.jetbrains.kotlin:kotlin-allopen:$kotlin_version")    }}
  1. 配置无参(no-arg)、全开放(allopen)插件

其中,org.jetbrains.kotlin:kotlin-noarg是无参(no-arg)编译器插件,它为具有特定注解的类生成一个额外的零参数构造函数。 这个生成的构造函数是合成的,因此不能从 Java 或 Kotlin 中直接调用,但可以使用反射调用。 这样我们就可以使用 Java Persistence API(JPA)实例化 data 类。

其中,org.jetbrains.kotlin:kotlin-allopen 是全开放编译器插件。我们使用Kotlin 调用Java的Spring AOP框架和库,需要类为 open(可被继承实现),而Kotlin 类和函数都是默认 final 的,这样我们需要为每个类和函数前面加上open修饰符。

这样的代码写起来,可费事了。还好,我们有all-open 编译器插件。它会适配 Kotlin 以满足这些框架的需求,并使用指定的注解标注类而其成员无需显式使用 open 关键字打开。 例如,当我们使用 Spring 时,就不需要打开所有的类,跟我们在Java中写代码一样,只需要用相应的注解标注即可。

Kotlin 1.0.6 版本里提供了 kotlin-spring 插件,用下面的注解把Kotlin的类或成员函数设置为open:

@Component

@Transactional

@Cacheable

这样的注解支持,意味着我们使用 @Configuration,@Controller,@RestController,@Service 或 @Repository 注解的类会自动设置为 open ,因为这些注解都使用了@Component。

完整的build.gradle配置文件如下

group 'com.easy.kotlin'version '1.0-SNAPSHOT'buildscript {    ext.kotlin_version = '1.1.2-2'    ext.springboot_version = '1.5.2.RELEASE'    repositories {        mavenCentral()    }    dependencies {//        Kotlin Gradle插件        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"//        SpringBoot Gradle插件        classpath("org.springframework.boot:spring-boot-gradle-plugin:$springboot_version")//        Kotlin整合SpringBoot的默认无参构造函数,默认把所有的类设置open类插件//        无参(no-arg)编译器插件为具有特定注解的类生成一个额外的零参数构造函数。 这个生成的构造函数是合成的,因此不能从 Java 或 Kotlin 中直接调用,但可以使用反射调用。 这允许 Java Persistence API(JPA)实例化 data 类,虽然它从 Kotlin 或 Java 的角度看没有无参构造函数        classpath("org.jetbrains.kotlin:kotlin-noarg:$kotlin_version")//        全开放插件(kotlin-allopen)        classpath("org.jetbrains.kotlin:kotlin-allopen:$kotlin_version")    }}apply plugin: 'java'apply plugin: 'kotlin'//Kotlin整合SpringBoot需要的spring,jpa,org.springframework.boot插件//Kotlin-spring 编译器插件,它根据 Spring 的要求自动配置全开放插件。apply plugin: 'kotlin-spring'//该插件指定 @Entity 和 @Embeddable 注解作为应该为一个类生成无参构造函数的标记。apply plugin: 'kotlin-jpa'apply plugin: 'org.springframework.boot'sourceCompatibility = 1.8targetCompatibility = 1.8repositories {    mavenCentral()}dependencies {    compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version"    testCompile group: 'junit', name: 'junit', version: '4.12'    compile("org.springframework.boot:spring-boot-starter-web")    testCompile("org.springframework.boot:spring-boot-starter-test")    compile("org.springframework.boot:spring-boot-starter-data-jpa")    compile('mysql:mysql-connector-java:5.1.13')}
  1. 配置application.properties
spring.datasource.url = jdbc:mysql://localhost:3306/easykotlinspring.datasource.username = rootspring.datasource.password = root#spring.datasource.driverClassName = com.mysql.jdbc.Driver# Specify the DBMSspring.jpa.database = MYSQL# Keep the connection alive if idle for a long time (needed in production)spring.datasource.testWhileIdle = truespring.datasource.validationQuery = SELECT 1# Show or not log for each sql queryspring.jpa.show-sql = true# Hibernate ddl auto (create, create-drop, update)spring.jpa.hibernate.ddl-auto = update# Naming strategyspring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy# The SQL dialect makes Hibernate generate better SQL for the chosen databasespring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialectserver.port=8000
  1. 整体工程架构

UNIX操作系统说,“一切都是文件”。所以,我们 的所有的源代码、字节码、工程资源文件等等,一切都是文件。文件里面存的是字符串(01也当做是字符)。各种框架、库、编译器,解释器,都是对这些字符串流进行过滤,最后映射成01机器码(或者CPU微指令码等),最终落地到硬件上的高低电平。

整体工程目录如下:

.├── README.md├── build│   └── kotlin-build│       └── caches│           └── version.txt├── build.gradle├── easykotlin.sql├── settings.gradle└── src    ├── main    │   ├── java    │   ├── kotlin    │   │   └── com    │   │       └── easy    │   │           └── kotlin    │   │               ├── Application.kt    │   │               ├── controller    │   │               │   ├── HelloWorldController.kt    │   │               │   └── PeopleController.kt    │   │               ├── entity    │   │               │   └── People.kt    │   │               ├── repository    │   │               │   └── PeopleRepository.kt    │   │               └── service    │   │                   └── PeopleService.kt    │   └── resources    │       ├── application.properties    │       └── banner.txt    └── test        ├── java        ├── kotlin        └── resources19 directories, 13 files

一切尽在不言中,静静地看工程文件结构。

直接写个HelloWorldController

package com.easy.kotlin.controllerimport org.springframework.web.bind.annotation.GetMappingimport org.springframework.web.bind.annotation.RestController/** * Created by jack on 2017/6/7. */@RestControllerclass HelloWorldController {    @GetMapping(value = *arrayOf("/helloworld", "/"))    fun helloworld(): Any {        return "Hello,World!"    }}

我们再写个访问数据库的标准四层代码

写领域模型类People

package com.easy.kotlin.entityimport java.util.*import javax.persistence.Entityimport javax.persistence.GeneratedValueimport javax.persistence.GenerationTypeimport javax.persistence.Id/** * Created by jack on 2017/6/6. */@Entityclass People(        @Id @GeneratedValue(strategy = GenerationType.AUTO)        val id: Long?,        val firstName: String?,        val lastName: String?,        val gender: String?,        val age: Int?,        val gmtCreated: Date,        val gmtModified: Date) {    override fun toString(): String {        return "People(id=$id, firstName='$firstName', lastName='$lastName', gender='$gender', age=$age, gmtCreated=$gmtCreated, gmtModified=$gmtModified)"    }}

写PeopleRepository

package com.easy.kotlin.repositoryimport com.easy.kotlin.entity.Peopleimport org.springframework.data.repository.CrudRepository/** * Created by jack on 2017/6/7. */interface PeopleRepository : CrudRepository
{ fun findByLastName(lastName: String): List
?}

写PeopleService

package com.easy.kotlin.serviceimport com.easy.kotlin.entity.Peopleimport com.easy.kotlin.repository.PeopleRepositoryimport org.springframework.beans.factory.annotation.Autowiredimport org.springframework.stereotype.Service/** * Created by jack on 2017/6/7. */@Serviceclass PeopleService : PeopleRepository {    @Autowired    val peopleRepository: PeopleRepository? = null    override fun findByLastName(lastName: String): List
? { return peopleRepository?.findByLastName(lastName) } override fun
save(entity: S): S? { return peopleRepository?.save(entity) } override fun save(entities: MutableIterable?): MutableIterable? { return peopleRepository?.save(entities) } override fun delete(entities: MutableIterable
?) { } override fun delete(entity: People?) { } override fun delete(id: Long?) { } override fun findAll(ids: MutableIterable
?): MutableIterable
? { return peopleRepository?.findAll(ids) } override fun findAll(): MutableIterable
? { return peopleRepository?.findAll() } override fun exists(id: Long?): Boolean { return peopleRepository?.exists(id)!! } override fun count(): Long { return peopleRepository?.count()!! } override fun findOne(id: Long?): People? { return peopleRepository?.findOne(id) } override fun deleteAll() { }}

写PeopleController

package com.easy.kotlin.controllerimport com.easy.kotlin.service.PeopleServiceimport org.springframework.beans.factory.annotation.Autowiredimport org.springframework.stereotype.Controllerimport org.springframework.web.bind.annotation.GetMappingimport org.springframework.web.bind.annotation.RequestParamimport org.springframework.web.bind.annotation.ResponseBody/** * Created by jack on 2017/6/7. */@Controllerclass PeopleController {    @Autowired    val peopleService: PeopleService? = null    @GetMapping(value = "/hello")    @ResponseBody    fun hello(@RequestParam(value = "lastName") lastName: String): Any {        val peoples = peopleService?.findByLastName(lastName)        val map = HashMap
() map.put("hello", peoples!!) return map }}
  1. 运行测试

首先在本地mysql数据库中新建schema

CREATE SCHEMA `easykotlin` DEFAULT CHARACTER SET utf8 ;

然后,点击Gradle的bootRun , 如下图

螢幕快照 2017-06-07 11.47.42.png

如果没有异常,启动成功,我们将看到以下输出:

螢幕快照 2017-06-07 11.50.07.png

打开浏览器,访问请求:

输出响应:

Hello,World!

访问

// 20170607115700// http://127.0.0.1:8000/hello?lastName=chen{  "hello": [    {      "id": 1,      "firstName": "Jason",      "lastName": "Chen",      "gender": "Male",      "age": 28,      "gmtCreated": 1496768497000,      "gmtModified": 1496768497000    },    {      "id": 3,      "firstName": "Corey",      "lastName": "Chen",      "gender": "Female",      "age": 20,      "gmtCreated": 1496768497000,      "gmtModified": 1496768497000    }    ...  ]}

本节示例工程源代码:

2.4 Android版的HelloWorld

2017谷歌I/O大会:宣布 Kotlin 成 Android 开发一级语言。

2017谷歌I/O大会上,谷歌宣布,将Kotlin语言作为安卓开发的一级编程语言。Kotlin由JetBrains公司开发,与Java100%互通,并具备诸多Java尚不支持的新特性。谷歌称还将与JetBrains公司合作,为Kotlin设立一个非盈利基金会。

JetBrains在2010年首次推出Kotlin编程语言,并在次年将之开源。下一版的AndroidStudio(3.0)也将提供支持。

下面我们简要介绍如何在Android上开始一个Kotlin的HelloWorld程序。

对于我们程序员来说,我们正处于一个美好的时代。得益于互联网的发展、工具的进步,我们现在学习一门新技术的成本和难度都比过去低了很多。

假设你之前没有使用过Kotlin,那么从头开始写一个HelloWorld的app也只需要这么几步:

  1. 首先,你要有一个Android Studio。 本节中,我们用的是2.2.3版本,其它版本应该也大同小异。
Android Studio 2.3.1Build #AI-162.3871768, built on April 1, 2017JRE: 1.8.0_112-release-b06 x86_64JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
  1. 其次,安装一个Kotlin的插件。

依次打开:Android Studio > Preferences > Plugins,

然后选择『Browse repositories』,在搜索框中搜索Kotlin,结果列表中的『Kotlin』插件,如下图

点击安装,安装完成之后,重启Android Studio。

  1. 新建一个Android项目

重新打开Android Studio,新建一个Android项目吧,添加一个默认的MainActivity——像以前一样即可。

  1. 转换Java to Kotlin

安装完插件的AndroidStudio现在已经拥有开发Kotlin的功能。我们先来尝试它的转换功能:Java -> Kotlin,可以把现有的java文件翻译成Kotlin文件。

打开MainActivity文件,在Code菜单下面可以看到一个新的功能:Convert Java File to Kotlin File。

点击转换,

可以看到转换后的Kotlin文件:MainActivity.kt

package com.kotlin.easy.kotlinandroidimport android.support.v7.app.AppCompatActivityimport android.os.Bundleclass MainActivity : AppCompatActivity() {    override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        setContentView(R.layout.activity_main)    }}

这个转换功能,对我们Java程序员在学习Kotlin是十分实用。我们可以基于我们之前的Java编码的经验来迅速学习Kotlin编程。

  1. 配置gradle文件

MainActivity已经被转换成了Kotlin实现,但是项目目前gradle编译、构建、运行还不能执行,还需要进一步配置一下,让项目支持grade的编译、运行。当然,这一步也不需要我们做太多工作——IDEA都已经帮我们做好了。

在Java代码转换成Kotlin代码之后,打开MainActivity.kt文件,编译器会提示"Kotlin not configured",点击一下Configure按钮,IDEA就会自动帮我们把配置文件写好了。

我们可以看出,主要的依赖项是:

kotlin-gradle-pluginplugin: 'kotlin-android'kotlin-stdlib-jre7

完整的配置文件如下:

Project build.gradle

// Top-level build file where you can add configuration options common to all sub-projects/modules.buildscript {    ext.kotlin_version = '1.1.2-4'    repositories {        jcenter()    }    dependencies {        classpath 'com.android.tools.build:gradle:2.3.1'        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"        // NOTE: Do not place your application dependencies here; they belong        // in the individual module build.gradle files    }}allprojects {    repositories {        jcenter()    }}task clean(type: Delete) {    delete rootProject.buildDir}

Module build.gradle

apply plugin: 'com.android.application'apply plugin: 'kotlin-android'android {    compileSdkVersion 25    buildToolsVersion "25.0.2"    defaultConfig {        applicationId "com.kotlin.easy.kotlinandroid"        minSdkVersion 14        targetSdkVersion 25        versionCode 1        versionName "1.0"        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"    }    buildTypes {        release {            minifyEnabled false            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'        }    }}dependencies {    compile fileTree(dir: 'libs', include: ['*.jar'])    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {        exclude group: 'com.android.support', module: 'support-annotations'    })    compile 'com.android.support:appcompat-v7:25.3.1'    compile 'com.android.support.constraint:constraint-layout:1.0.2'    testCompile 'junit:junit:4.12'    compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"}repositories {    mavenCentral()}

所以说使用IDEA来写Kotlin代码,这工具的完美集成会让你用起来如丝般润滑。毕竟Kotlin的亲爸爸JetBrains是专门做工具的,而且Intelli IDEA又是那么敏捷、智能。

配置之后,等Gradle Sync完成,即可运行。

6.运行

运行结果如下

工程源码:

2.5 JavaScript版HelloWorld

在Kotlin 1.1中,开始支持JavaScript和协程是引人注目的亮点。本节我们简单介绍Kotlin代码编译转化为JavaScript的方法。

为了极简直观地感受这个过程,我们先在命令行REPL环境体验一下Kotlin源码被编译生成对应的JavaScript代码的过程。

首先,使用编辑器新建一个HelloWord.kt

fun helloWorld(){	println("Hello,World!")}

命令行使用kotlinc-js编译

kotlinc-js -output HelloWorld.js HelloWorld.kt

运行完毕,我们会在当前目录下看到HelloWorld.js, 其内容如下

if (typeof kotlin === 'undefined') {  throw new Error("Error loading module 'HelloWorld'. Its dependency 'kotlin' was not found. Please, check whether 'kotlin' is loaded prior to 'HelloWorld'.");}var HelloWorld = function (_, Kotlin) {  'use strict';  var println = Kotlin.kotlin.io.println_s8jyv4$;  function helloWorld() {    println('Hello,World!');  }  _.helloWorld = helloWorld;  Kotlin.defineModule('HelloWorld', _);  return _;}(typeof HelloWorld === 'undefined' ? {} : HelloWorld, kotlin);

我们看到,使用kotlinc-js 转换成的js代码依赖'kotlin'模块。这个模块是Kotlin支持JavaScript脚本的内部封装模块。也就是说,如果我们想要使用HelloWorld.js,先要引用kotlin.js。这个kotlin.js 在kotlin-stdlib-js-1.1.2.jar里面。

下面我们使用IDEA新建一个Kotlin(JavaScript)工程。在这个过程中,我们将会看到使用Kotlin来开发js的过程。

首先按照以下步骤新建工程

螢幕快照 2017-06-07 21.32.23.png

螢幕快照 2017-06-07 21.33.40.png

螢幕快照 2017-06-07 21.33.57.png

螢幕快照 2017-06-07 21.34.08.png

等待Gradle初始化工程完毕,我们将得到一个Gradle KotlinJS 工程,其目录如下

.├── build│   └── kotlin-build│       └── caches│           └── version.txt├── build.gradle├── settings.gradle└── src    ├── main    │   ├── java    │   ├── kotlin    │   └── resources    └── test        ├── java        ├── kotlin        └── resources12 directories, 3 files

其中,build.gradle配置文件为

group 'com.easy.kotlin'version '1.0-SNAPSHOT'buildscript {    ext.kotlin_version = '1.1.2'    repositories {        mavenCentral()    }    dependencies {        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"    }}apply plugin: 'kotlin2js'repositories {    mavenCentral()}dependencies {    compile "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlin_version"}

其中,apply plugin: 'kotlin2js' 是Gradle的kotlin编译成js的插件。org.jetbrains.kotlin:kotlin-stdlib-js是KotlinJS的运行库。

另外,我们需要再配置一下Kotlin代码编译成JS的编译规则,以及文件放置目录等属性,如下所示

build.doLast {    configurations.compile.each { File file ->        copy {            includeEmptyDirs = false            from zipTree(file.absolutePath)            into "${projectDir}/web"            include { fileTreeElement ->                def path = fileTreeElement.path                path.endsWith(".js") && (path.startsWith("META-INF/resources/") || !path.startsWith("META-INF/"))            }        }    }}compileKotlin2Js {    kotlinOptions.outputFile = "${projectDir}/web/js/app.js"    kotlinOptions.moduleKind = "plain" // plain (default),AMD,commonjs,umd    kotlinOptions.sourceMap = true    kotlinOptions.verbose = true    kotlinOptions.suppressWarnings = true    kotlinOptions.metaInfo = true}

其中,kotlinOptions.moduleKind配置项是Kotlin代码编译成JavaScript代码的类型。 支持普通JS(plain),AMD(Asynchronous Module Definition,异步模块定义)、CommonJS和UMD(Universal Model Definition,通用模型定义)。

AMD通常在浏览器的客户端使用。AMD是异步加载模块,可用性和性能相对会好。

CommonJS是服务器端上使用的模块系统,通常用于nodejs。

UMD是想综合AMD、CommonJS这两种模型,同时支持它们在客户端或服务器端上使用。

我们这里为了极简化演示,直接采用了普通JS plain 类型。

除了输出的 JavaScript 文件,该插件默认会创建一个带二进制描述符的额外 JS 文件。 如果你是构建其他 Kotlin 模块可以依赖的可重用库,那么该文件是必需的,并且应该与转换结果一起分发。 其生成由 kotlinOptions.metaInfo 选项控制。

一切配置完毕,我们来写Kotlin代码App.kt

package com.easy.kotlin/** * Created by jack on 2017/6/7. */fun helloWorld() {    println("Hello,World!")}

然后,我们直接使用Gradle构建工程,如下图所示

螢幕快照 2017-06-07 23.48.23.png

控制台输出

23:47:05: Executing external task 'build'...Using a single directory for all classes from a source set. This behaviour has been deprecated and is scheduled to be removed in Gradle 5.0	at build_3e0ikl0qk0r006tvk0olcp2lu.run(/Users/jack/easykotlin/chapter2_hello_world_kotlin2js/build.gradle:15):compileJava NO-SOURCE:compileKotlin2Js:processResources NO-SOURCE:classes:jar:assemble:compileTestJava NO-SOURCE:compileTestKotlin2Js NO-SOURCE:processTestResources NO-SOURCE:testClasses UP-TO-DATE:test NO-SOURCE:check UP-TO-DATE:buildBUILD SUCCESSFUL in 2s3 actionable tasks: 3 executed23:47:08: External task execution finished 'build'.

此时,我们可以看到工程目录变为

.├── build│   └── kotlin-build│       └── caches│           └── version.txt├── build.gradle├── settings.gradle└── src    ├── main    │   ├── java    │   ├── kotlin    │   └── resources    └── test        ├── java        ├── kotlin        └── resources12 directories, 3 filesjack@jacks-MacBook-Air:~/easykotlin/chapter2_hello_world_kotlin2js$ tree ..├── build│   ├── kotlin│   │   └── sessions│   ├── kotlin-build│   │   └── caches│   │       └── version.txt│   ├── libs│   │   └── chapter2_hello_world_kotlin2js-1.0-SNAPSHOT.jar│   └── tmp│       └── jar│           └── MANIFEST.MF├── build.gradle├── settings.gradle├── src│   ├── main│   │   ├── java│   │   ├── kotlin│   │   │   └── com│   │   │       └── easy│   │   │           └── kotlin│   │   │               └── App.kt│   │   └── resources│   └── test│       ├── java│       ├── kotlin│       └── resources└── web    ├── js    │   ├── app    │   │   └── com    │   │       └── easy    │   │           └── kotlin    │   │               └── kotlin.kjsm    │   ├── app.js    │   ├── app.js.map    │   └── app.meta.js    ├── kotlin.js    └── kotlin.meta.js26 directories, 14 files

这个web目录就是Kotlin代码通过kotlin-stdlib-js-1.1.2.jar编译的输出结果。

其中,app.js代码如下

if (typeof kotlin === 'undefined') {  throw new Error("Error loading module 'app'. Its dependency 'kotlin' was not found. Please, check whether 'kotlin' is loaded prior to 'app'.");}var app = function (_, Kotlin) {  'use strict';  var println = Kotlin.kotlin.io.println_s8jyv4$;  function helloWorld() {    println('Hello,World!');  }  var package$com = _.com || (_.com = {});  var package$easy = package$com.easy || (package$com.easy = {});  var package$kotlin = package$easy.kotlin || (package$easy.kotlin = {});  package$kotlin.helloWorld = helloWorld;  Kotlin.defineModule('app', _);  return _;}(typeof app === 'undefined' ? {} : app, kotlin);//@ sourceMappingURL=app.js.map

里面这段自动生成的代码显得有点绕

var package$com = _.com || (_.com = {});  var package$easy = package$com.easy || (package$com.easy = {});  var package$kotlin = package$easy.kotlin || (package$easy.kotlin = {});  package$kotlin.helloWorld = helloWorld;    Kotlin.defineModule('app', _);  return _;

简化之后的意思表达如下

_.com.easy.kotlin.helloWorld = helloWorld;

目的是建立Kotlin代码跟JavaScript代码的映射关系。这样我们在前端代码中调用

function helloWorld() {    println('Hello,World!');  }

这个函数时,只要这样调用即可

app.com.easy.kotlin.helloWorld()

下面我们来新建一个index.html页面,使用我们生成的app.js。代码如下

    
KotlinJS

我们需要优先加载kotlin.js,再加载应用程序代码app.js。 当然,我们仍然可以像以前一样使用诸如jquery.js这样的库。

在浏览器中打开index.html

螢幕快照 2017-06-08 00.11.15.png

我们可以看到浏览器控制台输出

螢幕快照 2017-06-08 00.14.57.png

这个helloWorld() JavaScript函数

var println = Kotlin.kotlin.io.println_s8jyv4$;  function helloWorld() {    println('Hello,World!');  }

对应kotlin.js代码中的3755行处的代码:

BufferedOutputToConsoleLog.prototype.flush = function() {    console.log(this.buffer);    this.buffer = "";  };

本节工程源代码:

本章小结

本章简单介绍了Kotlin分别使用命令行、应用程序、Web RESTFul、Android、Kotlin JavaScript等平台上的快速开发入门的Hello,World示例。

Kotlin是静态类型编程语言,支持多个平台:JVM平台,Android平台,浏览器JS,本地机器码等平台。与Java,Android 100%互通。

从Web RESTFul的示例中,我们也可以了解到Kotlin可以基本无缝使用Java生态库(有的使用场景,想要优雅地编程,可能需要插件支持,比如说我们讲到的no-args,allopen插件)。Android开发无缝使用Java库也是类似的。

然后,我们还可以看到,使用Kotlin代码来自动生成对应JS代码的有趣体验。

前两章中,我们从整体上了解了Kotlin语言背景,体验了在多平台上使用Kotlin语言进行快速开始Hello,World的开发过程。在下一章节中,我们将走进Kotlin语言的基础学习。

参考资料

1.

2.

转载于:https://my.oschina.net/universsky/blog/918603

你可能感兴趣的文章
PyQt的图片资源的路径问题。
查看>>
调试神经网络让人抓狂?这有16条锦囊妙计送给你
查看>>
mount -o remount,rw /
查看>>
3、cisco实验模拟软件PT安装
查看>>
【Android进阶学习】Popupwindow的应用
查看>>
简单的四舍五入
查看>>
CentOS安装中文汉字输入法ibus
查看>>
如何忌口有利于伤口的愈合
查看>>
在远程计算机运行PowerShell命令
查看>>
Celerra(七)---Dedup:file-level or block-level??
查看>>
什么是RAID?
查看>>
xen虚拟化实战系列(九)之xen虚拟机时间配置
查看>>
技术分享连载(四十三)
查看>>
释译python fileinput中的description
查看>>
分布式计算的重要原则--CAP理论
查看>>
ndroid笔记:Webview 支持 input type=file选择上传图片
查看>>
edge.js架起node.js和.net互操作桥梁
查看>>
EsxServer 的时间同步设置
查看>>
ISA Server 2004 -- 理解ISA Server 2004的应用层过滤器
查看>>
MyEclipse中add jars和add external jars的区别带来的svn checkout的问题
查看>>