Kotlin第一次接觸
2.1 命令列的HelloWorld
安裝配置完Kotlin命令列環境之後,我們直接命令列輸入kotlinc, 即可進入 Kotlin REPL介面。
$ kotlinc
Welcome 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.Date
import java.text.SimpleDateFormat
fun main(args: Array<String>) {
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
└── resources
21 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.8
repositories {
mavenCentral()
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version"
testCompile group: 'junit', name: 'junit', version: '4.12'
}
工程原始碼地址:https://github.com/EasyKotlin/easykotlin/tree/easykotlin_hello_world_20170529
2.3 Web RESTFul HelloWorld
本節介紹使用 Kotlin
結合 SpringBoot
開發一個RESTFul版本的 Hello.World
。
- 新建gradle,kotlin工程:
開啟IDEA的File > New > Project
, 如下圖
按照介面操作,輸入相應的工程名等資訊,即可新建一個使用Gradle構建的標準Kotlin工程。
- build.gradle 基本配置
IDEA自動生成的Gradle配置檔案如下:
group 'com.jason.chen.mini_springboot'
version '1.0-SNAPSHOT'
buildscript {
ext.kotlin_version = '1.1.0'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply plugin: 'kotlin'
apply plugin: 'application'
mainClassName = 'jason.chen.mini_springboot.HelloWorldKt'
defaultTasks 'run'
repositories {
mavenCentral()
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
}
從上面的配置檔案我們可以看出,IDEA已經自動把Gradle 構建Kotlin工程外掛 kotlin-gradle-plugin,以及Kotlin標準庫kotlin-stdlib新增到配置檔案中了。
- 配置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")
}
}
- 配置無參(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中寫程式碼一樣,只需要用相應的註解標註即可,如 @Configuration 或 @Service。
- 配置application.properties
spring.datasource.url = jdbc:mysql://localhost:3306/easykotlin
spring.datasource.username = root
spring.datasource.password = root
#spring.datasource.driverClassName = com.mysql.jdbc.Driver
# Specify the DBMS
spring.jpa.database = MYSQL
# Keep the connection alive if idle for a long time (needed in production)
spring.datasource.testWhileIdle = true
spring.datasource.validationQuery = SELECT 1
# Show or not log for each sql query
spring.jpa.show-sql = true
# Hibernate ddl auto (create, create-drop, update)
spring.jpa.hibernate.ddl-auto = update
# Naming strategy
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
# The SQL dialect makes Hibernate generate better SQL for the chosen database
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
server.port=8000
- 整體工程架構
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
└── resources
19 directories, 13 files
一切盡在不言中,靜靜地看工程檔案結構。
直接寫個HelloWorldController
package com.easy.kotlin.controller
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RestController
/**
* Created by jack on 2017/6/7.
*/
@RestController
class HelloWorldController {
@GetMapping(value = *arrayOf("/helloworld", "/"))
fun helloworld(): Any {
return "Hello,World!"
}
}
我們再寫個訪問資料庫的標準四層程式碼
寫領域模型類People
package com.easy.kotlin.entity
import java.util.*
import javax.persistence.Entity
import javax.persistence.GeneratedValue
import javax.persistence.GenerationType
import javax.persistence.Id
/**
* Created by jack on 2017/6/6.
*/
@Entity
class 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.repository
import com.easy.kotlin.entity.People
import org.springframework.data.repository.CrudRepository
/**
* Created by jack on 2017/6/7.
*/
interface PeopleRepository : CrudRepository<People, Long> {
fun findByLastName(lastName: String): List<People>?
}
寫PeopleService
package com.easy.kotlin.service
import com.easy.kotlin.entity.People
import com.easy.kotlin.repository.PeopleRepository
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
/**
* Created by jack on 2017/6/7.
*/
@Service
class PeopleService : PeopleRepository {
@Autowired
val peopleRepository: PeopleRepository? = null
override fun findByLastName(lastName: String): List<People>? {
return peopleRepository?.findByLastName(lastName)
}
override fun <S : People?> save(entity: S): S? {
return peopleRepository?.save(entity)
}
override fun <S : People?> save(entities: MutableIterable<S>?): MutableIterable<S>? {
return peopleRepository?.save(entities)
}
override fun delete(entities: MutableIterable<People>?) {
}
override fun delete(entity: People?) {
}
override fun delete(id: Long?) {
}
override fun findAll(ids: MutableIterable<Long>?): MutableIterable<People>? {
return peopleRepository?.findAll(ids)
}
override fun findAll(): MutableIterable<People>? {
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.controller
import com.easy.kotlin.service.PeopleService
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.ResponseBody
/**
* Created by jack on 2017/6/7.
*/
@Controller
class 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<Any, Any>()
map.put("hello", peoples!!)
return map
}
}
- 執行測試
點選Gradle的bootRun
, 如下圖
如果沒有異常,啟動成功,我們將看到以下輸出:
開啟瀏覽器,訪問請求:
輸出響應:
Hello,World!
訪問
http://127.0.0.1:8000/hello?lastName=chen
// 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
}
...
]
}
本節示例工程原始碼:
https://github.com/EasyKotlin/easy_kotlin_chapter2_hello_world_springboot_restful
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也只需要這麼幾步:
- 首先,你要有一個Android Studio。 本節中,我們用的是2.2.3版本,其它版本應該也大同小異。
Android Studio 2.3.1
Build #AI-162.3871768, built on April 1, 2017
JRE: 1.8.0_112-release-b06 x86_64
JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
- 其次,安裝一個Kotlin的外掛。
依次開啟:Android Studio > Preferences > Plugins,
然後選擇『Browse repositories』,在搜尋框中搜尋Kotlin,結果列表中的『Kotlin』外掛,如下圖
點選安裝,安裝完成之後,重啟Android Studio。
- 新建一個Android專案
重新開啟Android Studio,新建一個Android專案吧,新增一個預設的MainActivity——像以前一樣即可。
- 轉換Java to Kotlin
安裝完外掛的AndroidStudio現在已經擁有開發Kotlin的功能。我們先來嘗試它的轉換功能:Java -> Kotlin,可以把現有的java檔案翻譯成Kotlin檔案。
開啟MainActivity檔案,在Code選單下面可以看到一個新的功能:Convert Java File to Kotlin File。
[圖片上傳失敗...(image-e03230-1532330256479)]
點選轉換,
可以看到轉換後的Kotlin檔案:MainActivity.kt
package com.kotlin.easy.kotlinandroid
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
這個轉換功能,對我們Java程式設計師在學習Kotlin是十分實用。我們可以基於我們之前的Java編碼的經驗來迅速學習Kotlin程式設計。
- 配置gradle檔案
MainActivity已經被轉換成了Kotlin實現,但是專案目前gradle編譯、構建、執行還不能執行,還需要進一步配置一下,讓專案支援grade的編譯、執行。當然,這一步也不需要我們做太多工作——IDEA都已經幫我們做好了。
在Java程式碼轉換成Kotlin程式碼之後,開啟MainActivity.kt檔案,編譯器會提示"Kotlin not configured",點選一下Configure按鈕,IDEA就會自動幫我們把配置檔案寫好了。
我們可以看出,主要的依賴項是:
kotlin-gradle-plugin
plugin: '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.執行
執行結果如下
工程原始碼:https://github.com/EasyKotlin/KotlinAndroid
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的過程。
首先按照以下步驟新建工程
[圖片上傳失敗...(image-a054db-1532330256479)]
等待Gradle初始化工程完畢,我們將得到一個Gradle KotlinJS 工程,其目錄如下
.
├── build
│ └── kotlin-build
│ └── caches
│ └── version.txt
├── build.gradle
├── settings.gradle
└── src
├── main
│ ├── java
│ ├── kotlin
│ └── resources
└── test
├── java
├── kotlin
└── resources
12 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構建工程,如下圖所示
控制檯輸出
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
:build
BUILD SUCCESSFUL in 2s
3 actionable tasks: 3 executed
23: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
└── resources
12 directories, 3 files
jack@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.js
26 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。程式碼如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>KotlinJS</title>
</head>
<body>
<!-- 優先載入kotlin.js,再載入應用程式程式碼app.js-->
<script type="text/javascript" src="kotlin.js"></script>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="js/app.js"></script>
<script>
var kotlinJS = app;
console.log(kotlinJS.com.easy.kotlin.helloWorld())
</script>
</body>
</html>
我們需要優先載入kotlin.js,再載入應用程式程式碼app.js。 當然,我們仍然可以像以前一樣使用諸如jquery.js這樣的庫。
在瀏覽器中開啟index.html
我們可以看到瀏覽器控制檯輸出
這個helloWorld() JavaScript函式
var println = Kotlin.kotlin.io.println_s8jyv4$;
function helloWorld() {
println('Hello,World!');
}
對應kotlin.js程式碼中的3755行處的程式碼:
BufferedOutputToConsoleLog.prototype.flush = function() {
console.log(68this.buffer);
this.buffer = "";
};
參考資料
1.https://kotlinlang.org/docs/reference/compiler-plugins.html
2.http://kotlinlang.org/docs/tutorials/javascript/working-with-modules/working-with-modules.html
相關文章
- 接觸GitHub的第一次Github
- 第一次接觸管理專案都要注意哪些問題?
- 第一次接觸jboss,執行例子出錯,鬱悶,求教
- 接觸postgresqlSQL
- MVVM初接觸MVVM
- WebSocket初接觸Web
- 初次接觸 CookieCookie
- SCSS初接觸CSS
- 初次接觸express框架Express框架
- 一、初次接觸javaJava
- ITextSharp 初次接觸
- iris 的 websocket 初始接觸Web
- 接觸el-admin
- MyBatis TypeHandler的初次接觸MyBatis
- 再次接觸物件導向物件
- 剛接觸JAVA 問問Java
- 再次接觸tts的特性TTS
- PL/SQL程式設計接觸SQL程式設計
- MicrosoftSecurityEssentials測試版全接觸ROS
- docker 及 linux 初接觸DockerLinux
- html5全接觸(一)HTML
- 分頁查詢初接觸
- 全面接觸SQL語法(轉)SQL
- 新手接觸spring第一課Spring
- Oracle資料庫之初步接觸Oracle資料庫
- ibm cdc 軟體初步接觸IBM
- linux 啟動全接觸(轉)Linux
- vue瞭解與初步接觸/使用Vue
- 與JavaFX第一次親密接觸Java
- XML相關知識全接觸(一)XML
- IT質量我保障——IT測試全接觸
- 托盤程式設計全接觸(轉)程式設計
- 托盤程式設計全接觸 (轉)程式設計
- 入侵檢測術語全接觸(轉)
- 第一次c語言課的感觸C語言
- 初次接觸 Laravel,先從下載開始Laravel
- Golang學習筆記(十九):Channel初步接觸Golang筆記
- Omi 入坑指南 The second floor 初步接觸