- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我是 Kotlin 的初学者,最近阅读了 Sealed Classes .但是从文档中我真正得到的唯一想法是它们是存在的。
文档指出,它们“代表受限的类层次结构”。除此之外,我发现他们是具有超能力的枚举。这两个方面其实都不清楚。
那么你能帮我解决以下问题吗:
更新:我仔细检查了这个blog post仍然无法理解这个概念。如帖子所述
Benefit
The feature allows us to define class hierarchies that arerestricted in their types, i.e. subclasses. Since all subclasses needto be defined inside the file of the sealed class, there’s no chanceof unknown subclasses which the compiler doesn’t know about.
为什么编译器不知道其他文件中定义的其他子类?甚至 IDE 都知道这一点。只需按 Ctrl+Alt+B
例如,在 IDEA 中,List<>
即使在其他源文件中也将显示定义和所有实现。如果一个子类可以定义在一些第三方框架中,而应用程序中没有使用,我们为什么要关心呢?
最佳答案
假设您有一个域(您的宠物),您知道其中有明确的类型枚举(计数)。例如,您有两个且只有两个宠物(您将使用名为 MyPet
的类对其进行建模)。 Meowsi 是你的猫,Fido 是你的狗。
比较该人为示例的以下两个实现:
sealed class MyPet
class Meowsi : MyPet()
class Fido : MyPet()
因为你使用了密封类,当你需要根据宠物的类型来执行一个 Action 时,那么MyPet
的可能性就一分为二了,你可以确定MyPet
实例将恰好是以下两个选项之一:
fun feed(myPet: MyPet): String {
return when(myPet) {
is Meowsi -> "Giving cat food to Meowsi!"
is Fido -> "Giving dog biscuit to Fido!"
}
}
如果你不使用密封类,那么可能性并没有穷尽两种,你需要包含一个 else
语句:
open class MyPet
class Meowsi : MyPet()
class Fido : MyPet()
fun feed(myPet: MyPet): String {
return when(myPet) {
is Mewosi -> "Giving cat food to Meowsi!"
is Fido -> "Giving dog biscuit to Fido!"
else -> "Giving food to someone else!" //else statement required or compiler error here
}
}
换句话说,没有密封类,就没有穷尽(完全覆盖)的可能性。
请注意,您可以使用 Java enum
实现穷尽可能性,但这些并不是完全成熟的类。例如 enum
不能是另一个类的子类,只能实现一个接口(interface)(感谢 EpicPandaForce )。
完全耗尽可能性的用例是什么?打个比方,假设您的预算很紧,而且您的饲料非常珍贵,并且您希望确保最终不会喂食不属于您家庭的额外宠物。
没有 sealed
类,你家/应用程序中的其他人可以定义一个新的 MyPet
:
class TweetiePie : MyPet() //a bird
并且这个不想要的宠物将由您的 feed
方法喂养,因为它包含在 else
语句中:
else -> "Giving food to someone else!" //feeds any other subclass of MyPet including TweetiePie!
同样,在您的程序中耗尽可能性是可取的,因为它减少了您的应用程序可能处于的状态数量,并减少了在您可能处于行为定义不明确的状态时发生错误的可能性。
因此需要 sealed
类。
请注意,如果将 when
用作表达式,您只会获得强制性的 else
语句。根据文档:
If [
when
] is used as an expression, the value of the satisfied branch becomes the value of the overall expression [... and] theelse
branch is mandatory, unless the compiler can prove that all possible cases are covered with branch conditions
这意味着你不会因为这样的事情而获得密封类的好处):
fun feed(myPet: MyPet): Unit {
when(myPet) {
is Meowsi -> println("Giving cat food to Meowsi!") // not an expression so we can forget about Fido
}
}
要在这种情况下耗尽精力,您需要将语句转换为具有返回类型的表达式。
Some 建议使用这样的扩展功能会有所帮助:
val <T> T.exhaustive: T
get() = this
那么你可以这样做:
fun feed(myPet: MyPet): Unit {
when(myPet) {
is Meowsi -> println("Giving cat food to Meowsi!")
}.exhaustive // compiler error because we forgot about Fido
}
Others 建议扩展函数会污染命名空间,因此需要其他解决方法(如编译器插件)。
有关此问题的更多信息,请参见 here。
关于kotlin - Kotlin 中的密封类是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50772328/
我正在查看Kotlin Github page我注意到 Kotlin 语言本身大部分是用 Kotlin 编写的:我只是想知道,一种语言怎么可能大部分都是用它自己的语言编写的?在您可以使用正在创建的语言
我有以下非常简单的 kotlin 代码来演示中缀函数 com.lopushen.demo.presentation 包 fun main(args: Array) { print("Hello
我在 Java 中有 2 个模型类,其中一个扩展了另一个 @UseStag public class GenericMessages extends NavigationLocalizationMap
Kotlin 代码 runBlocking { flow { for (i in 0..4) { println("Emit $i")
这三个 Kotlin 插件和它们的实际作用有什么区别? plugins { id 'kotlin-android' id 'org.jetbrains.kotlin.android'
我正在为某些现有库添加 Kotlin 原生 linuxX64 目标支持。库已成功编译,但在运行测试用例时,出现以下运行时错误: kotlin.native.concurrent.InvalidMuta
关闭。这个问题需要details or clarity .它目前不接受答案。 想改进这个问题吗? 通过 editing this post 添加细节并澄清问题. 关闭 2 年前。 Improve t
我创建了一个类并向其添加了一个与成员函数具有相同签名的扩展,并执行了这个方法,它总是执行成员方法。 class Worker { fun work() = "...working" } fun
我知道传递给函数的参数将被视为“val”,即使变量被初始化为“var”。但这对我来说一直是个问题。在下面的示例代码中,我想通过使用函数“changeNum”修改变量“num”的值。但当然,Kotlin
现在,我正在尝试用 Kotlin 重写我的 Java 应用程序。然后,我遇到了日志语句,比如 log.info("do the print thing for {}", arg); 所以我有两种方法可
有点出名article关于许多语言的异步编程模型的状态,指出它们存在“颜色”问题,特别是将生态系统分为两个独立的世界:异步和非异步。以下是这种语言的属性: 每个函数都有一种颜色,红色或蓝色(例如asy
因为 KDoc 文档生成引擎是 abandoned in favor of Dokka , Kotlin 文档应该称为“KDoc 注释”,还是“Dokka 注释”? 最佳答案 如所述here , KD
我想在可空对象上传递函数引用。以 Android 为例,假设我想使用 Activity#onBackPressed来自作为该事件的子级的片段。 如果我想调用这个函数,我可以很容易地做到 activit
我有一个列表 (x, y)其中y只能是 0 或 1 这样 例如: [(3, 0), (3, 1), (5, 1)] [(5, 0), (3, 1), (5, 1)] [(1, 1), (3, 1),
从强类型语言的定义来看: A strongly-typed programming language is one in which each type of data (such as intege
这不能编译的事实是否意味着它们不是一流的类型? fun foo(s: String): Int = s.length // This won't compile. val bar = foo 有没有办
如果在 Java i++是一个表达式和 i++;是一个表达式语句,分号(;) 在 Kotlin 中是可选的,是 i++ Kotlin 中的表达式或表达式语句? 最佳答案 i++是一个表达式,因为它有一
代码(如下所示)是否正确?它取自 Kotlin-docs.pdf 的第 63 页,这也是 https://kotlinlang.org/docs/reference/generics.html 的最后
我正在尝试使用 Kotlin 为 Android 的一些全局 API 解析器(检查网络连接、调用 API 并通过来自源的单个调用返回格式化数据),并且在某些时候我不得不创建一个通用类型 object就
kotlinlang 中的任务: 使用月份变量重写此模式,使其与格式 13 JUN 1992(两位数字、一个空格、一个月份缩写、一个空格、四位数字)中的日期相匹配。 答案是:val month = "
我是一名优秀的程序员,十分优秀!