简体   繁体   English

为什么我用Kotlin时sealed class里面定义了object class?

[英]Why is there a object class defined within sealed class when I use Kotlin?

The Code A is from the official sample project .代码A来自官方示例工程

Result<out R> is a sealed class, I'm very strange why Loading is defined as object class. Result<out R>是一个密封的class,我很奇怪为什么Loading定义为object class。

I think the Code B is more reasonable, is it right?我觉得Code B比较合理,对不对?

Code A代码A

sealed class Result<out R> {
   data class Success<out T>(val data: T) : Result<T>()
   data class Error(val exception: Exception) : Result<Nothing>()
   object Loading : Result<Nothing>()

   override fun toString(): String {
      return when (this) {
         is Success<*> -> "Success[data=$data]"
         is Error -> "Error[exception=$exception]"
         Loading -> "Loading"
      }
   }
}

Code B代码 B

sealed class Result<out R> {
   data class Success<out T>(val data: T) : Result<T>()
   data class Error(val exception: Exception) : Result<Nothing>()
   data class Loading : Result<Nothing>()

   override fun toString(): String {
      return when (this) {
         is Success<*> -> "Success[data=$data]"
         is Error -> "Error[exception=$exception]"
         is Loading -> "Loading"
      }
   }
}

Added Content:添加内容:

To Tenfour04 and a_local_nobody: Thanks!致 Tenfour04 和 a_local_nobody:谢谢!

The Android Studio can compile and run after I add is before Loading -> "Loading" in Code C. Android Studio在代码C中添加is before Loading -> "Loading"后可以编译运行。

1: What are differents between Code A and Code C? 1:Code A和Code C有什么区别?

2: And more, In my mind, all types whithin sealed class should be the same, maybe they are all data class, or they are all object. But Code A mix data class and object, and it's Ok, does it mean that I add even Interface whithin sealed class? 2:还有,在我看来,sealed class里面的所有类型应该都是一样的,可能都是数据class,也可能都是object。但是代码A混合了数据class和object,没关系,是不是意味着我在密封的 class 中添加偶数Interface

Code C代码 C

sealed class Result<out R> {
   data class Success<out T>(val data: T) : Result<T>()
   data class Error(val exception: Exception) : Result<Nothing>()
   object Loading : Result<Nothing>()

   override fun toString(): String {
      return when (this) {
         is Success<*> -> "Success[data=$data]"
         is Error -> "Error[exception=$exception]"
         is Loading -> "Loading"     // I add "is"
      }
   }
}

There's no reason not to use an object for a class that doesn't have any properties (holds no state).没有理由不将object用于没有任何属性(不包含任何状态)的 class。 object means you don't have to create multiple instances of it and you never have to worry about which instance you're looking at, so it's simpler. object意味着你不必创建它的多个实例,你永远不必担心你正在查看哪个实例,所以它更简单。 You don't have to call a constructor on it to get an instance, and there will never be more than one instance of it taking up memory.您不必在其上调用构造函数来获取实例,并且永远不会有超过一个实例占用 memory。

Note that your is Loading check in Code B will still work if Loading is an object .请注意,如果Loadingobject ,代码 B 中的is Loading检查仍然有效。 object s are more versatile because == and is checks are both valid and effectively mean the same thing. object更通用,因为==is检查都有效并且有效地表示同一件事。

By the way (as mentioned before by @a_local_nobody), you cannot create a data class with no properties, although you could create a regular class.顺便说一下(正如@a_local_nobody 之前提到的),您不能创建没有属性的数据 class,尽管您可以创建常规的 class。

that won't work, because:那行不通,因为:

data class Loading : Result<Nothing>() <-- this isn't valid for a data class

Data classes must have at least one primary constructor parameter, presumably the author used an object there to avoid having to make use of a constructor value, compared to the others:数据类必须至少有一个主要的构造函数参数,大概作者在那里使用了一个 object 来避免必须使用构造函数值,与其他相比:

 data class Success<out T>(val data: T) : Result<T>() <-- (val data: T)
 data class Error(val exception: Exception) : Result<Nothing>() <-- (val exception: Exception)

which clearly require values这显然需要价值观

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM