Skip to content

中级:库与 API

为了充分利用 Kotlin,请使用现有的库和 API,这样您可以将更多时间花在编码上,而不是重复造轮子。

库分发可重用的代码,从而简化常见任务。在库中,包含用于对相关类、函数和实用程序进行分组的软件包和对象。库将 API(应用程序编程接口)公开为一组函数、类或属性,开发者可以在其代码中使用它们。

Kotlin 库与 API

让我们来探索 Kotlin 的各种可能性。

标准库

Kotlin 拥有一个标准库,提供基本的类型、函数、集合和实用程序,使您的代码简洁且富有表现力。标准库的大部分内容(kotlin 软件包中的所有内容)在任何 Kotlin 文件中都是现成可用的,无需显式导入:

kotlin
fun main() {
    val text = "emosewa si niltoK"
    
   // 使用标准库中的 reversed() 函数
    val reversedText = text.reversed()

    // 使用标准库中的 print() 函数
    print(reversedText)
    // Kotlin is awesome
}

然而,标准库的某些部分需要先导入才能在代码中使用。 例如,如果您想使用标准库的时间测量功能,则需要导入 kotlin.time 软件包

在文件顶部,添加 import 关键字,后跟您需要的软件包:

kotlin
import kotlin.time.*

星号 * 是通配符导入,它告诉 Kotlin 导入软件包内的所有内容。您不能在伴生对象中使用星号 *。相反,您需要显式声明想要使用的伴生对象成员。

例如:

kotlin
import kotlin.time.Duration
import kotlin.time.Duration.Companion.hours
import kotlin.time.Duration.Companion.minutes

fun main() {
    val thirtyMinutes: Duration = 30.minutes
    val halfHour: Duration = 0.5.hours
    println(thirtyMinutes == halfHour)
    // true
}

此示例:

  • 导入 Duration 类及其伴生对象中的 hoursminutes 扩展属性。
  • 使用 minutes 属性将 30 转换为 30 分钟的 Duration
  • 使用 hours 属性将 0.5 转换为 30 分钟的 Duration
  • 检查两个时长是否相等并打印结果。

先搜索再构建

在决定编写自己的代码之前,请检查标准库,看看您要找的内容是否已经存在。以下是标准库已经为您提供的一系列类、函数和属性的领域:

要了解有关标准库中其他内容的更多信息,请查看其 API 参考

Kotlin 库

标准库涵盖了许多常见用例,但仍有一些它未涉及的领域。幸运的是,Kotlin 团队和社区的其他成员已经开发了广泛的库来补充标准库。例如,kotlinx-datetime 可以帮助您管理跨平台的时间。

您可以在我们的搜索平台上找到有用的库。要使用它们,您需要执行额外的步骤,例如添加依赖项或插件。每个库都有一个 GitHub 仓库,其中包含有关如何将其包含到您的 Kotlin 项目中的说明。

添加库后,您可以导入其中的任何软件包。以下是如何导入 kotlinx-datetime 软件包以查找纽约当前时间的示例:

kotlin
import kotlinx.datetime.*

fun main() {
    val now = Clock.System.now() // 获取当前时刻
    println("Current instant: $now")

    val zone = TimeZone.of("America/New_York")
    val localDateTime = now.toLocalDateTime(zone)
    println("Local date-time in NY: $localDateTime")
}

此示例:

  • 导入 kotlinx.datetime 软件包。
  • 使用 Clock.System.now() 函数创建一个包含当前时间的 Instant 类实例,并将结果赋值给 now 变量。
  • 打印当前时间。
  • 使用 TimeZone.of() 函数查找纽约的时区,并将结果赋值给 zone 变量。
  • 对包含当前时间的实例调用 .toLocalDateTime() 函数,并以纽约时区作为实参。
  • 将结果赋值给 localDateTime 变量。
  • 打印针对纽约时区调整后的时间。

要更详细地探索此示例中使用的函数和类,请参阅 API 参考

选择启用 API

库作者可能会将某些 API 标记为需要选择启用,然后您才能在代码中使用它们。当 API 仍处于开发阶段且未来可能会发生变化时,他们通常会这样做。如果您不选择启用,则会看到如下警告或错误:

text
This declaration needs opt-in. Its usage should be marked with '@...' or '@OptIn(...)'

要选择启用,请编写 @OptIn,后跟包含对 API 进行分类的类名的圆括号,并在其后附加上两个冒号 ::class

例如,标准库中的 uintArrayOf() 函数属于 @ExperimentalUnsignedTypes,如 API 参考中所示:

kotlin
@ExperimentalUnsignedTypes
inline fun uintArrayOf(vararg elements: UInt): UIntArray

在您的代码中,选择启用如下所示:

kotlin
@OptIn(ExperimentalUnsignedTypes::class)

以下是一个示例,它选择启用 uintArrayOf() 函数来创建一个无符号整数数组并修改其中的一个元素:

kotlin
@OptIn(ExperimentalUnsignedTypes::class)
fun main() {
    // 创建一个无符号整数数组
    val unsignedArray: UIntArray = uintArrayOf(1u, 2u, 3u, 4u, 5u)

    // 修改一个元素
    unsignedArray[2] = 42u
    println("Updated array: ${unsignedArray.joinToString()}")
    // Updated array: 1, 2, 42, 4, 5
}

这是选择启用的最简单方法,但还有其他方法。要了解更多信息,请参阅选择启用要求

练习

练习 1

您正在开发一款金融应用程序,帮助用户计算其投资的未来价值。计算复利的公式为:

A = P \times (1 + \displaystyle\frac{r}{n})^{nt}

其中:

  • A 是计息后累积的金额(本金 + 利息)。
  • P 是本金金额(初始投资)。
  • r 是年利率(小数)。
  • n 是每年复利的次数。
  • t 是资金投资的时间(以年为单位)。

更新代码以:

  1. kotlin.math 软件包中导入必要的函数。
  2. calculateCompoundInterest() 函数添加函数体,用于计算应用复利后的最终金额。

|--|--|

kotlin
// 在此处编写您的代码

fun calculateCompoundInterest(P: Double, r: Double, n: Int, t: Int): Double {
    // 在此处编写您的代码
}

fun main() {
    val principal = 1000.0
    val rate = 0.05
    val timesCompounded = 4
    val years = 5
    val amount = calculateCompoundInterest(principal, rate, timesCompounded, years)
    println("The accumulated amount is: $amount")
    // The accumulated amount is: 1282.0372317085844
}
kotlin
import kotlin.math.*

fun calculateCompoundInterest(P: Double, r: Double, n: Int, t: Int): Double {
    return P * (1 + r / n).pow(n * t)
}

fun main() {
    val principal = 1000.0
    val rate = 0.05
    val timesCompounded = 4
    val years = 5
    val amount = calculateCompoundInterest(principal, rate, timesCompounded, years)
    println("The accumulated amount is: $amount")
    // The accumulated amount is: 1282.0372317085844
}
练习 2

您想要测量在程序中执行多个数据处理任务所需的时间。更新代码以添加正确的导入语句,并使用来自 kotlin.time 软件包的函数:

kotlin
// 在此处编写您的代码

fun main() {
    val timeTaken = /* 在此处编写您的代码 */ {
        // 模拟一些数据处理
        val data = List(1000) { it * 2 }
        val filteredData = data.filter { it % 3 == 0 }

        // 模拟处理过滤后的数据
        val processedData = filteredData.map { it / 2 }
        println("Processed data")
    }

    println("Time taken: $timeTaken") // 例如 16 ms
}
参考答案
kotlin
import kotlin.time.measureTime

fun main() {
    val timeTaken = measureTime {
        // 模拟一些数据处理
        val data = List(1000) { it * 2 }
        val filteredData = data.filter { it % 3 == 0 }

        // 模拟处理过滤后的数据
        val processedData = filteredData.map { it / 2 }
        println("Processed data")
    }

    println("Time taken: $timeTaken") // 例如 16 ms
}
练习 3

最新的 Kotlin 版本中标准库提供了一个新功能。您想尝试一下,但它需要选择启用。该功能属于 @ExperimentalStdlibApi。您的代码中选择启用应该是什么样子的?

kotlin
@OptIn(ExperimentalStdlibApi::class)