inline class Name(private val value: String) {
// ...
}
这样的类在使用时将被替换成为它所保存的值:
// 使用
val name: Name = Name("Marcin")
// 整个编译过程中,将会被下面这样的代码所替换
val name: String = "Marcin"
此类中的方法将被作为静态所使用方法:
inline class Name(private val value: String) {
// ...
fun greet() {
print("Hello, I am $value")
}
}
// 使用
val name: Name = Name("Marcin")
name.greet()
// 整个编译过程中,将会被下面这样的代码所替换
val name: String = "Marcin"
Name.`greet-impl`(name)
interface Timer {
fun callAfter(time: Int, callback: ()->Unit)
}
time 的单位是什么呢? 可能是毫秒、秒、分钟... 现在还不清楚,很容易出错。 一个著名的例子是:某个火星气候轨道器错误地撞向了火星大气层,背后的原因是控制它的软件是由一个外包公司开发的,它产生的输出单位不是 NASA 所期望的。它所输出的结果单位是磅力秒(lbf·s),但是 NASA 期望的单位是牛顿秒(N·s)。这次任务的总成本是3.276亿美元,以完全失败告终。正如你所看到的,测量单位的混乱可能会产生非常严重的后果。
开发人员建议描述单位的一种常见方法是将其包含在参数名中:
interface Timer {
fun callAfter(timeMillis: Int, callback: ()->Unit)
}
interface User {
fun decideAboutTime(): Int
fun wakeUp()
}
interface Timer {
fun callAfter(timeMillis: Int, callback: ()->Unit)
}
fun setUpUserWakeUpUser(user: User, timer: Timer) {
val time: Int = user.decideAboutTime()
timer.callAfter(time) {
user.wakeUp()
}
}
typealias ClickListener =
(view: View, event: Event) -> Unit
class View {
fun addClickListener(listener: ClickListener) {}
fun removeClickListener(listener: ClickListener) {}
//...
}
但是需要了解的是,类型别名并不能以任何方式保护我们免受类型误用,它们只是为类型添加了一个新名称。如果我们将 Int 同时命名为 MiLls 和 Second,我们就产生一种错觉,认为类型系统保护了我们,而实际上并没有:
typealias Seconds = Int
typealias Millis = Int
fun getTime(): Millis = 10
fun setUpTimer(time: Seconds) {}
fun main() {
val seconds: Seconds = 10
val millis: Millis = seconds // 不会编译报错
setUpTimer(getTime())
}