Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

编程中的一个基本原则是 DRY 缩写:不要重复自己

多个相同的代码片段在进行修复或改进时需要进行维护。因此,复制代码不仅是额外的工作,而且每次复制都会引发出错的机会。

import 关键字从其他文件中重用代码。使用 import 的一种方法是指定类、函数或属性的名称:

import packagename.ClassName
import packagename.functionName
import packagename.propertyName

是一组相关联的代码。每个包通常被设计用于解决特定问题,通常包含多个函数和类。例如,我们可以从 kotlin.math 库中导入数学常数和函数:

// Packages/ImportClass.kt
import kotlin.math.PI
import kotlin.math.cos  // 余弦函数

fun main() {
  println(PI)
  println(cos(PI))
  println(cos(2 * PI))
}
/* 输出:
3.141592653589793
-1.0
1.0
*/

有时您想要使用多个具有相同名称的第三方库,这些库包含相同名称的类或函数。as 关键字允许您在导入时更改名称:

// Packages/ImportNameChange.kt
import kotlin.math.PI as circleRatio
import kotlin.math.cos as cosine

fun main() {
  println(circleRatio)
  println(cosine(circleRatio))
  println(cosine(2 * circleRatio))
}
/* 输出:
3.141592653589793
-1.0
1.0
*/

如果库的名称选择不当或过长,as 是很有用的。

您可以在代码的主体中完全限定一个导入。在下面的示例中,由于使用了显式的包名,代码可能变得不太可读,但是每个元素的来源绝对清晰:

// Packages/FullyQualify.kt

fun main() {
  println(kotlin.math.PI)
  println(kotlin.math.cos(kotlin.math.PI))
  println(kotlin.math.cos(2 * kotlin.math.PI))
}
/* 输出:
3.141592653589793
-1.0
1.0
*/

要从一个包中导入所有内容,可以使用星号:

// Packages/ImportEverything.kt
import kotlin.math.*

fun main() {
  println(E)
  println(E.roundToInt())
  println(E.toInt())
}
/* 输出:
2.718281828459045
3
2
*/

kotlin.math 包中包含一个方便的 roundToInt() 函数,它会将 Double 值四舍五入到最近的整数,与 toInt() 不同,后者仅截断小数点后的部分。

为了重用代码,您可以使用 package 关键字创建一个包。package 语句必须是文件中的第一个非注释语句。package 后面是您的包的名称,按惯例全部小写:

// Packages/PythagoreanTheorem.kt
package pythagorean
import kotlin.math.sqrt

class RightTriangle(
  val a: Double,
  val b: Double
) {
  fun hypotenuse() = sqrt(a * a + b * b)
  fun area() = a * b / 2
}

您可以随意为源代码文件命名,不像 Java 需要文件名与类名相同。

Kotlin 允许您为包选择任何名称,但是认为包名与包含包文件的目录名称相同是一个很好的做法(这对本书中的示例并不总是适用)。

现在,通过使用 importpythagorean 包中的元素可以使用了:

// Packages/ImportPythagorean.kt
import pythagorean.RightTriangle

fun main() {
  val rt = RightTriangle(3.0, 4.0)
  println(rt.hypotenuse())
  println(rt.area())
}
/* 输出:
5.0
6.0
*/

在本书的其余部分,对于任何在 main() 之外定义的函数、类等,我们都会使用 package 语句,以防止与书中的其他文件发生命名冲突,但通常我们不会在仅包含 main() 的文件中使用 package 语句。

练习和解答可以在 www.AtomicKotlin.com 找到。