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

时间:2016-01-12 19:10:04

标签: kotlin kotlin-extension

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

HashSet

使用时,它看起来像普通的fun <T> HashSet(n : Int, fn: (Int) -> T) = HashSet<T>(n).apply { repeat(n) { add(fn(it)) } } 构造函数:

HashSet

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

2 个答案:

答案 0 :(得分:14)

<强> UPD

在更新的编码约定中,有section on this topic

  

工厂职能

     

如果为类声明工厂函数,请避免为其赋予与类本身相同的名称。首选使用不同的名称,明确为什么工厂函数的行为是特殊的。只有在没有特殊语义的情况下,才能使用与该类相同的名称。

     

示例:

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

我下面描述的动机似乎仍然存在。

如关于naming style的文档中所述:

  

如果有疑问,默认使用Java编码约定,例如:

     
      
  • 方法和属性以小写字母开头
  •   

避免将一个函数命名为类的一个强有力的理由是它可能会混淆一个稍后会使用它的开发人员,因为这与他们的期望相反:

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

最好明确表明它是一个工厂功能,而不是构造函数,以避免这种混淆。

在stdlib中通常也避免将一个函数命名为类。给定SomeClass,在stdlib中,工厂函数的首选命名样式是someClassOfsomeClassBy或其他任何解释函数语义的最佳方法。例子:

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

因此,人们应该有充分的理由让函数模仿构造函数。

相反,函数的名称可能会告诉用户更多(甚至是所有内容)它的用法。

答案 1 :(得分:-2)

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

如果它只在内部使用而所有其他开发者(如果有的话)都可以使用它,不过,我会说要去做。 Python承认这个想法,我喜欢它。哎呀,他们两种方式,你也可以在功能案例中命名一个类,如果它感觉更像是一个功能。但是,Python并不需要处理Java互操作,所以绝对不要为公共代码做这件事。