【问题标题】:Kotlin: Scoping using Object vs ClassKotlin:使用对象与类进行范围界定
【发布时间】:2017-06-10 13:23:14
【问题描述】:

我有几个数据类,很短,所以我将它们组合在一个文件中。

我可以在 Kotlin 文件中按原样定义它们,但希望它是类/对象内的范围,因此该文件不仅仅是一个文件,而是在类/对象下以便更好地分组

我可以的

object Model {
    data class Result(val query: Query)
    data class Query(val searchinfo: SearchInfo)
    data class SearchInfo(val totalhits: Int)
}

我也可以

class Model {
    data class Result(val query: Query)
    data class Query(val searchinfo: SearchInfo)
    data class SearchInfo(val totalhits: Int)
}

它们在我看来都一样。有什么不同?在确定数据类的范围方面是否有首选方式?

【问题讨论】:

    标签: kotlin


    【解决方案1】:

    我建议不要使用类来确定其他类的范围。正如托德在他的回答中解释的那样,您可以使用密封类,它提供了exhaustive when checks 的实际好处。如果你不需要这个特性,Kotlin 有一个内置的作用域机制 - 包:

    package org.company.model
    
    data class Result(val query: Query)
    data class Query(val searchinfo: SearchInfo)
    data class SearchInfo(val totalhits: Int)
    

    我可以按原样在 Kotlin 文件中定义它们,但希望它是类/对象内的范围,因此该文件不仅仅是一个文件,而是在类/对象下以便更好地分组

    包含多个顶级元素的文件没有任何问题。这是一个有用的语言特性,正是在这种情况下使用的。

    【讨论】:

    • 嗨基里尔,感谢您的回答。我同意,将它作为顶级没有问题。但是,我使用的是 Retrofit 2 和 proguard,有些 proguard 会如何混淆它导致编译错误,所以我将它的范围限定为我可以按照 stackoverflow.com/a/44473703/3286489 保留类,而无需单独保留它们
    • 如果你把你的模型类放在子包中,你可以指示 ProGuard 只保留那个子包。
    【解决方案2】:

    另一种选择是使所有数据类成为密封Model 类的子类。这将使您受益于将它们全部定义在一个地方,因为 Kotlin 对密封类强制执行此操作。此外,让类型系统知道 Model 类型的所有实例对 when 表达式也很有帮助,因为这样就不需要您放置 else -> 块。

    sealed class Model
    data class Result(val query: Query) : Model()
    data class Query(val searchinfo: SearchInfo) : Model()
    data class SearchInfo(val totalhits: Int) : Model() 
    

    你可以直接使用它们:

    val r = Result(Query(SearchInfo(3))
    

    不要将它们包装在另一个 classobject 中,您必须像这样引用它们:

    val r = Model.Result(Model.Query(Model.SearchInfo(3)))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-13
      • 1970-01-01
      • 2018-02-04
      相关资源
      最近更新 更多