【问题标题】:kotlin secondary constructor argument processingkotlin 二级构造函数参数处理
【发布时间】:2021-03-11 19:03:16
【问题描述】:

我有一个自定义日期类,它的主要构造函数如下:

class CustomDate(val day : Int, val month : Int, val year : Int)
{
   init {
        ...some processing...
   }
}

我需要辅助构造函数,它以字符串“01.01.2021”的形式获取日期,并在调用主构造函数之前将它们拆分为日、月和年:

constructor(date : String) { ...some processing over date string that gives day, month and year... } 
: this(day, month, year)
{
   ...do stuff...
}

目前我只能想到做:

constructor(date : String) : this(0, 0, 0) {
   ... do processing on date string and assign new values to fields instead of 0s ...
}

但这看起来有点难看,如果有一种在调用主构造函数之前进行处理的方法,就像我在构造函数的第一个示例中提到的那样

【问题讨论】:

    标签: class kotlin constructor


    【解决方案1】:

    如果您需要在调用主构造函数之前进行任何重要处理,通常*最好有一个工厂方法,而不是另一个构造函数。

    在 Kotlin 中,一个好方法是这样写:

    class CustomDate(val day: Int, val month: Int, val year: Int) {
        companion object {
            operator fun invoke(date: String): CustomDate {
                // Calculate day, month, year…
                return CustomDate(day, month, year)
            }
        }
    }
    

    请参阅 here 以获取有关 operator funs 的文档以及 invoke() 的含义。但这里重要的是调用该方法看起来与调用构造函数一模一样!您可以像调用CustomDate(11, 3, 2021) 一样调用CustomDate("2021-03-11")

    这为您提供了工厂方法的优势,例如:

    • 可以在创建对象之前进行任意数量的处理。
    • 可以避免创建新实例,例如返回一个缓存的对象。
    • 可以返回子类。

    但是因为它看起来像一个简单的构造函数调用,所以很容易找到和阅读。它也更整洁,因为它将所有预计算与类的其余部分分开(如果您在初始化之前无意中访问属性,则可能会出现一些令人讨厌的问题)。

    这个成语我用过不少,感觉很自然(一旦你克服了有点奇怪的operator fun invoke)。

    显然,这仅适用于返回CustomDate 实例的方法!并且从参数类型中可以明显看出该方法将如何处理它们。如果有任何混淆的可能性——特别是如果你想要多个具有相同参数类型的工厂方法——那么最好在伴随对象中使用普通的 named 函数,例如:

    class CustomDate(val day: Int, val month: Int, val year: Int) {
        companion object {
            fun fromISO(date: String): CustomDate {
                // Calculate day, month, year…
                return CustomDate(day, month, year)
            }
        }
    }
    

    这将被称为CustomDate.fromISO("…")


    (* 在调用主构造函数之前种方法进行处理,但是非常有限。  主构造函数的参数可以是表达式,调用函数也可以。  但是如果您有多个参数,这可能会变得笨拙并涉及一些重复的工作。)

    【讨论】:

    • 哇!惊人的!这正是我一直在寻找的!谢谢你的详细回复:)
    猜你喜欢
    • 1970-01-01
    • 2019-06-02
    • 1970-01-01
    • 1970-01-01
    • 2019-03-18
    • 2019-06-19
    • 2018-05-08
    • 1970-01-01
    • 2023-03-24
    相关资源
    最近更新 更多