【问题标题】:Is it a good idea to use unicode symbols as Java identifiers?使用 unicode 符号作为 Java 标识符是个好主意吗?
【发布时间】:2011-02-17 03:19:07
【问题描述】:

我有一个如下所示的 sn-p 代码:

double Δt = lastPollTime - pollTime;
double α = 1 - Math.exp(-Δt / τ);
average += α * (x - average);

在 Java 标识符中使用 unicode 字符是多么糟糕的想法?或者这完全可以接受?

【问题讨论】:

  • ¿¿¿ʎʎɐɐʞɯɯɯ 'pɐq sı ǝpoɔ uı ǝpoɔıun
  • 我不确定我是赞成还是反对...
  • 附带说明,您可能有兴趣查看由 Guy L Steele(以及其他人)在 Sun 开发的 Fortress 语言。它支持广泛的 Unicode 运算符,甚至 ASCII 也可以“漂亮地打印”到 Unicode 中——参见projectfortress.sun.com/Projects/Community/wiki/…
  • 这让我想起了APL。告诉我你将它用作编程语言有多舒服?
  • ¿ʇɹɐ ʇnoqɐ ʇɐɥʍ ʇnq 'sǝʎ

标签: java unicode identifier


【解决方案1】:

这是个坏主意,出于各种原因。

  • 很多人的键盘不支持这些字符。如果我要在 qwerty 键盘(或任何其他没有希腊字母的键盘)上维护该代码,我必须一直复制和粘贴这些字符。

  • 某些人的编辑器或终端可能无法正确显示这些字符。例如,一些编辑器(不幸的是)仍然默认使用一些 ISO-8859(拉丁)变体。 ASCII 仍然如此流行的主要原因是它几乎总是有效。

  • 即使可以正确渲染字符,也可能会引起混乱。 Straight from Sun(强调我的):

    具有相同外观的标识符可能不同。例如,由单个字母 LATIN CAPITAL LETTER A (A, \u0041)、LATIN SMALL LETTER A (a, \u0061)、希腊大写字母 ALPHA (A, \u0391)、西里尔小写字母 A (a, \u0430) 和 MATHEMATICAL BOLD ITALIC SMALL A (a, \ud835\udc82) 都是不同的。

    ...

    Unicode 复合字符与分解后的字符不同。 例如,拉丁大写字母 A ACUTE (Á, \u00c1) 可以被认为与拉丁大写字母 A (A , \u0041) 排序时紧跟非间隔急性 (´, \u0301),但它们的标识符不同。

    这绝不是一个虚构的问题:α (U+03b1 GREEK SMALL LETTER ALPHA) 和 ⍺ (U+237a APL FUNCTIONAL SYMBOL ALPHA) 是不同的字符!

  • 无法判断哪些字符有效。您的代码中的字符可以工作,但是当我使用 FUNCTIONAL SYMBOL ALPHA 时,我的 Java 编译器会抱怨“非法字符:\9082”。即使功能符号在此代码中更合适。除了asking Character.isJavaIdentifierPart() 之外,似乎没有关于哪些字符可以接受的严格规则。

  • 尽管您可以编译它,但似乎所有 Java 虚拟机实现都已使用 Unicode 标识符进行了严格测试。如果这些字符仅用于方法范围内的变量,它们应该被编译掉,但如果它们是类成员,它们最终也会出现在 .class 文件中,可能会在错误的 JVM 实现上破坏您的程序。

【讨论】:

  • 扩展最后一点:您依赖于底层平台的默认文件编码。尽管这可以在 Sun JVM 上使用 -Dfile.encoding 进行控制(是的,依赖于 JVM 实现...),但您真的不想依赖它。那是 imo 的主要表演者。顺便说一句,答案很好,+1。
  • @BalusC:谢谢,但我认为你误解了。在.class文件的内部,只使用了一种编码,它类似于UTF-8。 en.wikipedia.org/wiki/Class_%28file_format%29 据我所知,file.encoding 仅用于为 InputStreamReader 等类指定默认编码。
【解决方案2】:

为什么不呢? 如果编写该代码的人可以轻松输入这些代码,那是可以接受的。

但是上帝帮助那些无法显示 unicode 或无法输入它们的人。

【讨论】:

  • 任何无法显示 Unicode 的人都需要走出 80 年代,进入 21 世纪。我的意思是翻转 RSTS/E 已经有了 i18n 的开始!
  • @ttmrichter:如果周围没有大量配置错误的机器和过时的软件,你会是对的......
  • 同样在 unix 和 linux 世界中,有很多人在控制台中使用 vim 或 emacs 来做他们的事情,但不能保证他们可以看到或写入 unicode 字符。
  • 如果 vim 和 emacs 无法显示已经存在近 20 年的标准中的字符,那么它们作为高效开发工具的声誉可能被严重高估了。或者,如果这是 Unix 系统的错,也许 Unix 不是它被破解的万能/万能系统。严重地。与 21 世纪同行。这里很可爱。 (谢天谢地,考虑到我住的地方等等,我的 Linux 机器似乎可以很好地应对 21 世纪。)
【解决方案3】:

看起来不错,因为它使用了正确的符号,但您的团队中有多少人会知道这些符号的击键?

我会使用英文表示,只是为了更容易输入。而其他人可能没有支持在其电脑上设置的这些符号的字符集。

【讨论】:

    【解决方案4】:

    该代码可读性好,但维护起来很糟糕——我建议使用简单的英文标识符,如下所示:

    double deltaTime = lastPollTime - pollTime;
    double alpha = 1 - Math.exp(-delta....
    

    【讨论】:

      【解决方案5】:

      如果您的工作组可以接受,则完全可以接受。这里的许多答案都是基于每个人都用英语编程的傲慢假设。如今,非英语程序员绝非罕见,而且他们正以越来越快的速度变得越来越少。既然他们可以使用完美的语言,为什么还要限制自己使用英文版本?

      除了英语傲慢之外,使用非英语标识符还有其他正当理由。例如,如果您正在编写数学包,如果您的目标是数学家,那么使用希腊语就可以了。当每个人都可以理解“Δ”并可能更快地键入它时,为什么人们要在您的工作组中键入“delta”?几乎任何问题领域都有自己的行话,有时这些行话用拉丁字母以外的其他方式表达。您到底为什么要尝试将所有内容都塞进 ASCII 码中?

      【讨论】:

      • @Longpoke:请指出我说“你很烂,因为你只会英语”的地方。 (提示:这是不可能的。)见鬼,指出我什至推断这个。 (提示:这也是不可能的。)然而,我要指出的是,那些说“不要在标识符中使用 Unicode,因为它使事情难以阅读”的人正在接受 very 傲慢的态度,只有说英语的程序员才算数。因此是“英语傲慢”。
      • 问题是Java中的关键字是英文的。 ifwhilepublicclass 等,以及运行时库中的所有方法。通过将另一种语言用于标识符和方法,您会遇到这样一种情况,即读者在阅读代码时必须在两种语言之间不断切换。这比只有一种语言更难,即使读者精通这两种语言。
      • @Thorbjørn:Java 中的关键字是伪英语。 Java 的“if”不是英语的“if”。它是形式逻辑中的“如果”,它与英语只有短暂的相似之处。 “while”、“public”、“class”等也是如此。这些不是文字。它们是符号。我们不会将它们作为英语单词处理。我们将它们处理为仅在 Java 中具有特定含义的符号(在另一种编程语言中通常具有完全不同的含义!)。所以我们已经在两种语言之间不断切换。通过在我们的母语中使用标识符,这是明确的。
      • @Longpoke:事实上,在其他几种人类语言中并不是这样。大多数人认为他们对语法了解的事情是完全错误的。例如,SVO 不仅不是通用的,“主体”和“客体”的概念本身也不是通用的。 (语言学家使用术语“代理”、“体验者”和“患者”,并根据这些来描述语言案例。)条件结构在不同语言中并不相同。双重否定在许多语言中都不是肯定的,它们是强调者。 “Not not red”的意思是“非常不红”而不是“红”。那种东西。
      • @ttmrichter,您可能在关键字方面有些正确,但在运行时库中使用的标识符方面却不是。如果不参考运行时库并且包含大量驼峰式英文单词,几乎不可能编写任何重要的 Java 程序。而且,是的,我是根据个人经验发言的。到目前为止,我们将丹麦语单词写入 Java 程序的尝试并不顺利,我得出的结论是语言切换就是这种情况。唯一的例外是没有合理英文翻译的领域特定概念。
      【解决方案6】:

      这是一个绝妙的主意。诚实的。 当时并不容易实现。让我们保留对它的引用以备将来使用。我希望喜欢将三角形、圆形、正方形等...作为程序代码的一部分。但是现在,请尝试按照 Crozin 建议的方式重写它。

      【讨论】:

        【解决方案7】:

        在完美的世界中,这是推荐的方式。

        不幸的是,当您移动到纯 7 位 ASCII 字符之外时会遇到字符编码(UTF-8 不同于 ISO-Latin-1 不同于 UTF-16 等),这意味着您最终会遇到问题。从 Windows 迁移到 Linux 时,我遇到过这种情况。我们的国家斯堪的纳维亚字符在此过程中中断,但幸运的是仅在字符串中。然后我们对所有这些都使用了 \u 编码。

        如果您可以绝对确定您永远不会遇到这样的事情 - 例如,如果您的文件包含正确的 BOM - 那么请务必这样做。它将使您的代码更具可读性。如果至少有一点怀疑,那就不要。

        (请注意,“使用非英语语言”是另一回事。我只是在考虑使用符号而不是字母)。

        【讨论】:

        • 那些符号非英语语言。 Delta 和 alpha 是希腊语。那是一种语言。那不是英语。
        • @ttmricher,我指的是在您的母语中使用标识符,而不是使用英语术语。 (如果法语是 Cheval 而不是 Horse)。这与所要求的在数学意义上使用“Δ”不同。
        猜你喜欢
        • 1970-01-01
        • 2017-12-18
        • 2011-04-05
        • 1970-01-01
        • 2015-02-07
        • 2010-09-08
        • 2020-03-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多