kotlin是我最喜欢用的语言,语法简洁功能丰富,但是项目管理略嫌麻烦,那有什么办法可以跳过麻烦的项目管理,同时又直接使用jvm庞大生态的依赖呢
答案就是 kotlin script
使用
首先需要一个最新的idea,旧版本的idea对这类新特性的支持并不太好
kotlin脚本有好几种,临时文件里创建的scratch,gradle项目管理的build.gradle.kts,以及本文的主题 main.kts
用idea在任意位置创建一个 test.main.kts ,随便写一段代码
println("hello kotlin script")
虽然文件行号上没有任何标记,但是我们可以用 ctrl + shilt + f10 运行该文件

当然也可以直接新建一个运行项

引入依赖
引入依赖的方式如下 @file:DependsOn("com.google.code.gson:gson:2.11.0")
也可以用 @file:Repository("https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven") 指定maven仓库
修改代码如下,然后点一下代码编辑器右上角的加载脚本依赖项按钮
@file:DependsOn("com.google.code.gson:gson:2.11.0")
import com.google.gson.JsonElement
import com.google.gson.JsonParser
val json: JsonElement = JsonParser.parseString("""{ "name": "kotlin script", "age": 1 }""")
println(json)
此时就已经可以使用gson的类了
当然在没有科学上网的情况下有时候是无法正常下载依赖的,对于这一点我修改了maven镜像源,以便在不开tun的情况下正常下载依赖
序列化
虽然我一直都很喜欢kotlinx.serialization的序列化,但是该序列化依赖gradle插件,我还没有研究明白怎么在 kts 脚本里使用这种插件
所以为了在脚本里使用序列化,我会选择gson作为序列化实现
提供服务
我有一些简单的http服务需要实现,这个时候我会选择ktor,他和kotlin相性极佳(毕竟都是一家的项目)
@file:DependsOn("org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.10.2")
@file:DependsOn("io.ktor:ktor-server-content-negotiation:2.3.13")
@file:DependsOn("io.ktor:ktor-server-compression-jvm:2.3.13")
@file:DependsOn("io.ktor:ktor-serialization-kotlinx-json:2.3.13")
@file:DependsOn("io.ktor:ktor-server-core-jvm:2.3.13")
@file:DependsOn("io.ktor:ktor-server-netty-jvm:2.3.13")
@file:DependsOn("io.ktor:ktor-server-call-logging-jvm:2.3.13")
@file:DependsOn("com.google.code.gson:gson:2.11.0")
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import io.ktor.http.*
import io.ktor.server.application.*
import io.ktor.server.engine.*
import io.ktor.server.netty.*
import io.ktor.server.plugins.callloging.*
import io.ktor.server.plugins.compression.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import kotlinx.coroutines.*
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.slf4j.event.Level
import kotlin.system.exitProcess
val logger: Logger = LoggerFactory.getLogger("App")
val scope = CoroutineScope(Dispatchers.IO) + CoroutineExceptionHandler { coroutineContext, throwable ->
logger.warn("", throwable)
}
val gson = Gson()
val json = """
|{
| "kotlin": 1,
| "java": 2
|}
""".trimMargin()
// 信号处理
run {
Runtime.getRuntime().addShutdownHook(Thread {
logger.info("exit...")
scope.cancel()
server.stop(0, 0)
})
}
fun Route.configureRouting() {
get("/{id}/status") {
val id = call.parameters["id"]!!
val status = gson.fromJson<Map<String, Int>>(json, object : TypeToken<Map<String, Int>>() {}.type)[id]
call.respondText(status.toString())
}
}
// http服务
val server = embeddedServer(Netty, 5753) {
install(CallLogging) {
level = Level.INFO
}
install(Compression) {
gzip {
priority = 1.0
matchContentType(ContentType.Text.Any)
}
deflate {
priority = 10.0
minimumSize(1024)
}
}
routing {
configureRouting()
}
}
server.start(true)
exitProcess(0)
部署
在idea里面我们已经可以运行main.kts脚本了,但是如果要部署,那怎么办呢
这儿需要到 kotlin 的 release 下载 kotlin-compiler
#!/bin/bash
kotlinc/bin/kotlin -Dfile.encoding=utf8 your_file.main.kts
然而添加jvm参数的部分在win上用不了,虽然我提了issue但是并没有解决
优势
很多时候我会写很多测试代码,调研某个库的使用方法和功能实现,但是这些代码如果集中在一个项目,会让项目变得很大,加载很慢,如果分开会不方便统一管理
这个时候使用kotlin script就可以很方便的管理
小问题
当我有如下代码
@file:DependsOn("com.google.code.gson:gson:2.11.0")
import com.google.gson.JsonElement
import com.google.gson.JsonParser
val json: JsonElement = JsonParser.parseString("""{ "name": "kotlin script", "age": 1 }""")
object MyService {
fun someFunction(): String {
return json.toString()
}
}
println(MyService.someFunction())
那么运行之后会出现

虽然这是合理的是可能的,但是这是合理的是不太可能的
另外idea在重载kts脚本依赖的时候会阻塞ui线程导致idea无响应
再另外,对于低版本的idea使用kts脚本引用外部依赖,会在打开反编译代码的时候放一个索引按钮,但是点了压根没用(新版本修了
总结
对于一些简单项目,使用 kotlin script非常爽,不管是修改还是部署,都很方便
总之好用爱用多用😋