安卓& Kotlin Books Kotlin学徒

24
与kotlin脚本 由Ellen Shapiro撰写

到目前为止,在这本书中,你已经从Intellij Ideage内使用了Kotlin,写作你在JVM上运行的程序。

然而,科特林也可以完全独立运行,使之成为一种脚本语言,让您轻松实现自动化日常任务。

您可以从命令行运行内容的力量,但在可读性和安全方面保持与Kotlin一起使用的所有好处。

重要的:本章的剩余部分您正在运行MacOS-Suptorted UNIX操作系统(例如HSMSD或Solaris)。如果您正在运行Windows,您将希望使用 cygwin. 或Windows 10 适用于Linux的子系统 能够使用此处显示的相同命令。这些工具在Windows上可能存在一些限制,但它们至少是一个开始的地方。

什么是脚本?

脚本 是指编写小程序,您可以独立于IDE运行,以便在计算机上自动执行任务。

A 脚本 是小程序,你编写和运行。它可以是手的选择,当你调用它,这样你可以写多用一个可重复使用的脚本。

你经常听到人们谈论 壳牌脚本, which is using .sh scripts to do things using the shell provided by your OS (often in an application called 终端 )。常见的贝壳是 抨击 , ZSH. , 和 .

这很棒,您可以在基本上在任何Mac或Linux系统上完成此盒子。但是,Shell脚本有许多问题,导致开发人员追求替代方案:

  • 壳牌脚本是 没有类型安全. You might think a variable is a String, but, if it’s actually an Int 和 you try to perform a String operation with it, your script will exit with an error.
  • 壳牌脚本是 没有编译。您只发现如果您的程序无法运行或退出错误,则犯了一个错误。
  • 带来 图书馆 到一个shell脚本涉及使整个系统中可用付款。这可能不是你想要的行为的原因有很多,其中包括安全性。
  • shell脚本可能非常 难以阅读。命令通常作为字符串或选项传递,并且可以很难与之合作,特别是如果您是新的工作。

在过去的十年中,许多语言都获得了脚本的普及。 Python 红宝石 特别是已成为极其流行的脚本语言。

Howek,虽然在麦克斯特写的脚本,但既不带来kat的图书馆牛肉。两者都是 动态类型,这意味着你不必宣布提前(或在创建时甚至推断)一个变量的类型会,与您建立后,它甚至可能改变!

相比之下,kotlin是 静态打字,由于变量的类型无法在其声明或推断后更改。例如,当您编写以下内容时:

val three = 3

The variable three is 推断 to have a type of Int. If you were to write:

val three: String = 3

You’d get an error, since you’ve explicitly declared the type of three to be a String , 和 the value 3 is not a String, it’s an Int. This helps prevent all kinds of errors that happen when you 思考 您已成为一种特定的变量,但实际上并不是那种类型。

最近,像Kotlin和Swift这样的语言带来了将类型安全和编译代码运行到脚本的能力。您仍然能够创建一个帮助您自动化修复的简单程序,但您可以以更安全和更可靠的方式进行。如果这对你有用,现在是时候潜入并通过安装kotlin来脚本来开始!

安装Kotlin用于脚本

截至目前,您的计算机已通过您的IDE,Intellij Idea访问Kotlin。但是,为了允许脚本访问,您需要将Kotlin用于整个系统。

安装SDKMAN!

笔记 :如果你已经有SDKMAN!安装,跳转到下面的“安装Kotlin”部分。

curl -s //get.sdkman.io | bash

安装Kotlin.

打开一个新终端 - 如果shell程序允许它 - 并使用sdkman安装kotlin的新窗口或新选项卡!通过键入以下命令并按Enter:

sdk install kotlin
which kotlin
/Users/[username]/.sdkman/candidates/kotlin/current/bin/kotlin
/usr/local/bin/kotlin
kotlinc-jvm

使用Repl.

一个REPL实质上是您可以在其中键入的东西,要付出立即执行一个小程序科特林。当它启动,你会看到这样的事情:

println("Hello, world!")

val groceries = listOf("apples", "ground beef", "toilet paper")
groceries.joinToString("\n")
apples
ground beef
toilet paper
groceries.map { it.count() }
[6, 11, 12]
data class Grocery(val name: String, val cost: Float)
val moreGroceries = listOf(Grocery("apples", 0.50f), Grocery("ground beef", 5.25f), Grocery("toilet paper", 2.23f))
val cost = moreGroceries.fold(0.0f) { running, next ->
  running + next.cost
}
println("Your groceries cost $cost")
Your groceries cost 7.98
:quit
kotlinc-jvm
println("$groceries")
错误:未解决方案参考:杂货
Orjub:iwfobiszov sucusocpa:nduputuup

创建脚本文件

Kotlin script files are a unique type of Kotlin file. They compile as if the entire file is the main() function for a Kotlin program.

从命令行运行脚本

首先,进入计算机的文件浏览器到 起动机 本章的目录。你会发现它没有任何东西 - 这是因为你真的要从划痕开始。

touch script.kts
println("Hello, scripting!")
kotlinc -script script.kts
Hello, scripting!

用intellij想法运行脚本

退出您的通用文本编辑器并打开Intellij Idea。如果您关闭其他项目,则应在此屏幕上降落:

Hello, scripting!

处理争论

一个 争论如果涉及运行Kotlin脚本,则是您输入命令行的字符串。在按Enter键运行之前,使用您正在运行的脚本在文件的路径后输入此路径。

if (args.isEmpty()) {
  println("[no args]")
} else {
  println("Args:\n ${args.joinToString("\n ")}")
}
[no args]

hello
Args:
 hello

Args:
 hello
 Ellen Shapiro
kotlinc -script script.main.kts
[no args]
kotlinc -script script.main.kts Kotlin scripting is awesome
Args:
 Kotlin
 scripting
 is
 awesome
kotlinc -script script.main.kts "Kotlin scripting is awesome"
Args:
 Kotlin scripting is awesome

从系统获取信息

获取有关文件系统的信息是最有帮助的,这将使您在霍夫何时做,而且它在哪里。

fun currentFolder(): File {
  return File("").absoluteFile
}
import java.io.File
val current = currentFolder()
println("Current folder: $current")
Current folder: [fullpath]/KotlinApprentice/24-scripting-with-kotlin/projects/starter
fun File.contents(): List<File> {
  return this.listFiles().toList()
}
val current = currentFolder()
println("Current folder contents:\n ${current.contents().joinToString("\n ")}")
Current folder contents:
 [fullpath]/KotlinApprentice/scripting-with-kotlin/projects/starter/.DS_Store
 [fullpath]/KotlinApprentice/scripting-with-kotlin/projects/starter/script.main.kts
 [fullpath]/KotlinApprentice/scripting-with-kotlin/projects/starter/.idea
fun File.fileNames(): List<String> {
  return this.contents().map { it.name }
}
println("Current folder contents:\n ${current.fileNames().joinToString("\n ")}")
Current folder contents:
 .DS_Store
 script.main.kts
 .idea
fun File.folders(): List<File> {
  return this.contents().filter { it.isDirectory }
}

fun File.files(): List<File> {
  return this.contents().filter { it.isFile }
}
fun File.fileNames(): List<String> {
  return this.files().map { it.name }
}
fun File.folderNames(): List<String> {
  return this.folders().map { it.name }
}
fun File.printFolderInfo() {
  // 1
  println("Contents of `${this.name}`:")

  // 2
  if (this.folders().isNotEmpty()) {
    println("- Folders:\n   ${this.folderNames().joinToString("\n   ")}")
  }

  // 3
  if (this.files().isNotEmpty()) {
    println("- Files:\n   ${this.fileNames().joinToString("\n   ")}")
  }

  // 4
  println("Parent: ${this.parentFile.name}")
}
current.printFolderInfo()
Contents of `starter`:
- Folders:
   .idea
- Files:
   .DS_Store
   script.main.kts
Parent: projects

添加参数

Often, arguments are passed in with the format name=Value. This makes it easy to detect which argument is for what purpose, no matter what the order of arguments is.

fun valueFromArgsForPrefix(prefix: String): String? {
  val arg = args.firstOrNull { it.startsWith(prefix) }

  if (arg == null) return null

  val pieces = arg.split("=")
  return if (pieces.size == 2) {
    pieces[1]
  } else {
    null
  }
}
val folderPrefix = "folder="
val folderValue = valueFromArgsForPrefix(folderPrefix)
if (folderValue != null) {
  val folder = File(folderValue).absoluteFile
  folder.printFolderInfo()
} else {
  println("No path provided, printing working directory info")
  currentFolder().printFolderInfo()
}
pwd
/Users/ellen/Desktop/Wenderlich/KotlinApprentice/scripting-with-kotlin/projects/starter
kotlinc -script script.main.kts "Kotlin scripting is awesome"
No path provided, printing working directory info
Contents of `starter`:
- Folders:
   .idea
- Files:
   .DS_Store
   script.main.kts
Parent: projects
kotlinc -script script.main.kts "Kotlin scripting is awesome" folder=/Users/ellen/Desktop/Wenderlich/KotlinApprentice/scripting-with-kotlin/projects/starter
Contents of `projects`:
- Folders:
   starter
   final
   challenge
- Files:
   .DS_Store

挑战

关键点

  • 脚本 在可以从命令行运行的文本编辑器中编写小程序,用于在计算机上执行各种类型的处理。
  • 作为一种脚本语言,Kotlin给你了 静态打字 缺少像Python和Ruby这样的其他脚本语言。
  • kotlin配有 读取评估打印环 或者可以用于以交互式方式调查Kotlin代码的求建。
  • Kotlin scripts end with the extension .kts, as opposed to normal Kotlin code that ends with .kt.
  • 您可以将Intellij Idea用作脚本编辑器,然后在IDE中运行脚本或从操作系统上的命令行shell运行。
  • Kotlin scripts run inside a hidden main() function and can access args passed into the script at the command line. Scripts can also import Kotlin and Java libraries to access their features.
  • 您可以使用Kotlin脚本读取和写入文件系统上的文件和文件夹,还有更多!

然后去哪儿?

The tool kscript (//github.com/holgerbrandl/kscript)提供围绕Kotlin脚本的便利包装。它允许预编码脚本,这会导致更快的迭代,它还允许您在运行时使用更简单的语法来访问Kotlin。创造者谈到了Kotlinconf 2017的谈话,值得关注他试图解决的一些问题的大纲。你可以看它 //www.youtube.com/watch?v=cOJPKhlRa8c.

有一个技术问题?想报告一个错误吗? 您可以向官方书籍论坛中的书籍作者提出问题和报告错误 这里 .

有反馈分享在线阅读体验吗? 如果您对UI,UX,高亮反馈,或者我们的在线读者的其他功能,您可以付款给设计团队与下面的表格:

© 2021 Razeware LLC

您可以免费读取,本章的部分显示为 混淆了 文本。解锁这本书,以及我们整个书籍和视频目录,带有Raywenderlich.com的专业订阅。

现在解锁

要突出或记笔记,您需要在订阅中拥有这本书或自行购买。