UPD
在更新的编码约定中,有一个关于这个主题的部分:
工厂功能
如果你为一个类声明一个工厂函数,避免给它与类本身相同的名字。更喜欢使用不同的名称,以明确为什么工厂函数的行为是特殊的。只有在真的没有特殊语义的情况下,才可以使用与类相同的名称。
例子:
class Point(val x: Double, val y: Double) {
companion object {
fun fromPolar(angle: Double, radius: Double) = Point(...)
}
}
不过,我在下面描述的动机似乎仍然成立。
如有关命名样式的文档中所述:
如果有疑问,默认使用 Java 编码约定,例如:
避免将函数命名为与类相同的一个重要原因是,它可能会使以后使用它的开发人员感到困惑,因为与他们的期望相反:
- 该函数将不可用于超级构造函数调用(如果类是
open
)
- 它不会通过反射作为构造函数可见
- 它不能用作 Java 代码中的构造函数(
new HashSet(n, it -> "Element " + it)
是一个错误)
- 如果您想稍后更改实现并返回一些子类实例,那么它将变得更加混乱,
HashSet(n) { "Element $it" }
它将构造不是 aHashSet
而是例如 aLinkedHashSet
最好明确地表明它是一个工厂函数,而不是构造函数,以避免这种混淆。
在 stdlib 中通常也避免将函数命名为与类相同。给定SomeClass
,在 stdlib 中,工厂函数的首选命名样式是someClassOf
,someClassBy
或者任何最能解释函数语义的名称。示例:
generateSequence { ... }
和sequenceOf(...)
lazy { ... }
和lazyOf(...)
compareBy { ... }
listOf(...)
, setOf(...)
,mapOf(...)
因此,绝对应该有充分的理由让函数模仿构造函数。
相反,函数的名称可能会告诉用户更多(甚至是所有内容)它的用法。