我们应该避免命名与Kotlin中现有类相同的函数吗?为什么? [英] Should we avoid naming a function same as an existing class in Kotlin? Why?

查看:54
本文介绍了我们应该避免命名与Kotlin中现有类相同的函数吗?为什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Kotlin allows to name a function same as an existing class, e.g. HashSet with initializer function could be implemented like this:

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

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

When used, it looks like a normal HashSet constructor:

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

应该避免还是鼓励这样做?

Should this be avoided or encouraged and why?

推荐答案

UPD

在更新的编码约定中,该主题的部分:

In the updated coding conventions, there's a section on this topic:

工厂功能

如果为类声明了工厂函数,请避免为其提供与类本身相同的名称.最好使用唯一的名称,以明确说明为什么工厂功能的行为很特殊.只有在确实没有特殊语义的情况下,您才能使用与该类相同的名称.

If you declare a factory function for a class, avoid giving it the same name as the class itself. Prefer using a distinct name making it clear why the behavior of the factory function is special. Only if there is really no special semantics, you can use the same name as the class.

示例:

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

不过,我下面描述的动机似乎仍然存在.

The motivation I described below, though, seems to still hold.

如有关命名样式的文档所述:

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

If in doubt default to the Java Coding Conventions such as:

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

避免将相同的函数命名为类的一个重要原因是,它可能会使以后使用它的开发人员感到困惑,因为与他们的期望相反:

One strong reason to avoid naming a function same to a class is that it might confuse a developer who will use it later, because, contrary to their expectations:

  • 该函数将无法用于超级构造函数调用(如果类为open)
  • 它不会通过反射作为构造函数可见
  • 它不能用作Java代码中的构造函数(new HashSet(n, it -> "Element " + it)是错误)
  • 如果您想稍后更改实现并返回一些子类实例,则HashSet(n) { "Element $it" }不会构造HashSet而是例如构造LinkedHashSet
  • 会更加令人困惑.
  • the function won't be available for super constructor call (if the class is open)
  • it won't be visible as a constructor through reflection
  • it won't be usable as a constructor in Java code (new HashSet(n, it -> "Element " + it) is an error)
  • if you want to change the implementation later and return some subclass instance instead, it will get even more confusing that HashSet(n) { "Element $it" } will construct not a HashSet but, for example, a LinkedHashSet

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

It's better to show it explicitly that it's a factory function, not a constructor, to avoid this confusion.

通常在stdlib中也避免将相同的函数命名为类.给定SomeClass,在stdlib中,工厂功能的首选命名方式是someClassOfsomeClassBy或能最好地解释该功能语义的内容.示例:

Naming a function same to a class is generally avoided in stdlib, too. Given SomeClass, in stdlib a preferred naming style for factory functions is someClassOf, someClassBy or whatever explains the semantics of the function best. The examples:

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

因此,绝对有理由让函数模仿构造函数.

So, one should definitely have strong reason to have a function mimic a constructor.

相反,函数的名称可能会告诉用户更多(甚至所有)有关其用法的信息.

Instead, a function's name might tell a user more (even everything) about its usage.

这篇关于我们应该避免命名与Kotlin中现有类相同的函数吗?为什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆