我们是否应避免在Kotlin中命名与现有类相同的函数? 为什么?

Kotlin允许命名与现有类相同的函数,例如HashSet具有初始化函数可以像这样实现:

 fun  HashSet(n : Int, fn: (Int) -> T) = HashSet(n).apply { repeat(n) { add(fn(it)) } } 

使用时,它看起来像一个正常的HashSet构造函数:

 var real = HashSet() var fake = HashSet(5) { "Element $it" } 

这应该避免或鼓励,为什么?

UPD

在更新的编码惯例中,有一个关于这个主题的部分 :

工厂function

如果你为一个类声明一个工厂函数,避免给它和类本身一样的名字。 更喜欢使用明确的名称,明确为什么工厂function的行为是特殊的。 只有在没有特别的语义时,才可以使用与该类相同的名称。

例:

 class Point(val x: Double, val y: Double) { companion object { fun fromPolar(angle: Double, radius: Double) = Point(...) } } 

但是我下面描述的动机似乎依然存在。


正如在有关命名风格的文档中所述:

如果有疑问,请默认Java代码约定,例如:

  • 方法和属性以小写开头

避免命名与类相同的function的一个强有力的理由是,它可能会混淆后面将使用它的开发者,因为违背了他们的期望:

  • 该函数将不可用于超级构造函数调用(如果该类是open
  • 它不会通过reflection作为构造函数来显示
  • 它将不能用作Java代码中的构造函数( new HashSet(n, it -> "Element " + it)是一个错误)
  • 如果你想稍后改变实现并返回一些子类实例,它会变得更混乱, HashSet(n) { "Element $it" }将不会构造HashSet但是,例如LinkedHashSet

为了避免这种混淆,最好明确地说明它是一个工厂函数而不是构造函数。

在stdlib中通常也可以避免命名与类相同的函数。 给定SomeClass ,在stdlib中,工厂函数的首选命名风格是someClassOfsomeClassBy或其他解释函数的最佳语义。 例子:

  • generateSequence { ... }sequenceOf(...)
  • lazy { ... }lazyOf(...)
  • compareBy { ... }
  • listOf(...)listOf(...)setOf(...) mapOf(...)

所以,应该有一个强有力的理由来有一个function模仿一个构造函数。

相反,函数的名称可能会告诉用户更多(甚至是全部)关于它的用法。

我同意+热键。 在这种情况下最好避免混淆。

如果只是在内部使用,而其他所有的开发者(如果有的话)都可以使用,但是我想要去做。 Python承认这个想法,我喜欢它。 哎呀,他们是双向的,如果你觉得它更像是一个函数,你也可以在函数的情况下命名一个类。 但是,Python不必处理Java互操作,所以绝对不要用于公共代码。