【发布时间】:2017-12-01 07:37:19
【问题描述】:
我正在浏览 Kotlin reference document 然后我看到了这个。
类声明由类名、类头组成 (指定其类型参数、主构造函数等)和 类主体,被花括号包围。标题和正文 是可选的;如果类没有主体,可以省略花括号。
class Empty
现在我想知道没有标题和正文的类声明有什么用
【问题讨论】:
我正在浏览 Kotlin reference document 然后我看到了这个。
类声明由类名、类头组成 (指定其类型参数、主构造函数等)和 类主体,被花括号包围。标题和正文 是可选的;如果类没有主体,可以省略花括号。
class Empty
现在我想知道没有标题和正文的类声明有什么用
【问题讨论】:
空类可用于与其他类一起表示状态,尤其是当它是密封类的一部分时。例如。
sealed class MyState {
class Empty : MyState()
class Loading : MyState()
data class Content(content: String) : MyState()
data class Error(error: Throwable) : MyState()
}
通过这种方式,您可以将它们视为具有更大灵活性的 java 枚举条目。
【讨论】:
Emtpy 和Loading 设为object 而不是class。
从实际程序员的日常角度来看,空类确实没有多大意义。然而,在某些情况下,这种行为是可取的。
在某些情况下,我们希望确保我们要定义一个类,同时我们希望确保永远不会创建此类的实例(从此类创建的类型称为empty type或uninhabited type)。
完美的例子是 Kotlin Nothing 没有类声明头和主体的类(注意它也有私有构造函数)
https://github.com/JetBrains/kotlin/blob/master/core/builtins/native/kotlin/Nothing.kt
Nothing 在 Kotlin 语言中的用法很少。其中之一是不返回值的函数(不要将其与Unit 混淆,其中函数返回实际上返回类型为Unit 的值)。一个典型的例子是用于测试的assertFail 方法或退出当前进程的方法。这两种方法实际上都不会返回任何值,但我们需要明确告诉编译器使用特殊类型 (Nothing)。
fun assertFail():Nothing {
throw Exception()
}
任何东西都不能用于开始投影,其中类型 Function<*, String> 可以投影到 Function<in Nothing, String>
空类的另一种用法是类型标记或占位符:
class DatabaseColumnName
class DatabaseTableName
addItem(DatabaseColumnName.javaClass, "Age")
addItem(DatabaseTableName.javaClass, "Person")
...
getItemsByType(DatabaseTableName.javaClass)
一些语言使用空类进行元编程,虽然我没有亲自探索过这部分: Advantages of an empty class in C++
【讨论】:
Spring Boot 框架中的空类使用示例:
@SpringBootApplication
class FooApplication
fun main(args: Array<String>) {
runApplication<FooApplication>(*args)
}
【讨论】:
作为最终结果没有多大意义。然而,它在主动开发和设计时作为某种占位符很有用,将来可能会扩展。这种简洁的语法允许您根据需要快速定义这些新类型。类似的东西:
class Person (
val FirstName: String,
val LastName: String,
// TODO
val Address: Address
)
class Address
我认为在文档中特别提到这一点的主要原因是为了证明语言语法通常可以很简洁,而不是专门为常用而创建的。
【讨论】:
密封类,从某种意义上说,是枚举类的扩展:枚举类型的值集合也受到限制,但每个枚举常量仅作为单个实例存在,而密封类的子类可以有多个实例可以包含状态。 reference
【讨论】: