2024 Clojure 状况调查!分享您的想法。

欢迎!请参阅关于页面以获取更多关于该网站如何工作的信息。

+1
语法和读取器
重新标记

我在对话框上挂了一个WindowListener,结果出错

$ clj windowlistener.clj
WARNING: When invoking clojure.main, use -M
Syntax error (IllegalArgumentException) compiling reify* at (windowlistener.clj:9:10).
Can't define method not in interfaces: windowIconified​

这是我的代码。你看到问题了吗?

(import 'javax.swing.JOptionPane
        'java.awt.event.WindowListener)
(let [jdialog (.createDialog
               (JOptionPane. (System/getProperty "java.version"))
               "WindowListener")
      wl (reify WindowListener
           (windowActivated [this e])
           (windowClosed [this e]) 	
           (windowClosing [this e]) 	
           (windowDeactivated [this e]) 	
           (windowDeiconified [this ​e]) 	
           (windowIconified​ [this e])
           (windowOpened [this ​e]))]
  (.addWindowListener jdialog wl)
  (.show jdialog))

我知道方法名拼写正确,因为我从Firefox显示的Javadoc [1] 中粘贴,然后重新排列括号。哈哈,复制粘贴是我的错误!这是我的十六进制转储

$ od -tcx1 ~/windowlistener.clj
...
0000700                               (   w   i   n   d   o   w   I   c
         20  20  20  20  20  20  20  28  77  69  6e  64  6f  77  49  63
0000720   o   n   i   f   i   e   d 342 200 213       [   t   h   i   s
         6f  6e  69  66  69  65  64  e2  80  8b  20  5b  74  68  69  73
0000740       e   ]   )      \t  \n                                    

342 200 213(即e2 80 8b垃圾)是什么?我猜文件是UTF-8格式的,在这种情况下,这些字节表示Unicode码点0x200b(通过位操作[2]),它表示零宽空格,根据unicode.org[3]。

(顺便说一句,我没有在Oracle的网页上找到这些字节。也许Firefox为了剪贴板的好处,在元素之间插入了零宽空格。)

我很惊讶编译器把零宽空格当作符号字符。这种行为与javadoc不相同。根据Character,零宽空格是标识符可忽略的

$ clj
Clojure 1.10.1
user=> (Character/isIdentifierIgnorable 0x200b)
true

Unicode小心翼翼地建议“为了安全” [4] “缩小”标识符集合,据推测,可能是因为构建具有看不见区分的代码是一种没有正当用途的权力。

实际上,javadoc忽略了零宽空格:在“public static void main”中的“main”中间插入零宽空格,你的程序仍然能正常工作。[5] 如果没有这个先例,我可能更愿意直接拒绝“可忽略的”,但我可以使用linters来做这件事。

我还对错误消息没有明确指出问题感到不满。javadoc通过首先剔除标识符可忽略的字符来避开这个挑战,因此没有看不见的方面需要揭露。无论如何,并非所有无意的零宽空格的使用都立即导致编译器错误。我从javadoc粘贴的代码充满了它们,包括附加到参数名称上,它们不会导致错误,直到以后——而且很可能是与“正确”的拼写相关的错误,而不是被感染的拼写。

总结来说,为了人道主义原因,我们建议Clojure将“可忽略的标识符”字符从符号中排除,无论是通过忽略它们(如javac所做)还是将它们视为一个错误吗?

[1] https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/java/awt/event/WindowListener.html

[2] https://en.wikipedia.org/wiki/UTF-8#Encoding

[3] https://util.unicode.org/UnicodeJsps/character.jsp?a=200B

[4] http://unicode.org/reports/tr31/#Figure_Code_Point_Categories_for_Identifier_Parsing

[5] 您可以使用Unicode字面量来完成

class A {
    public static void m\u200bain(String[] args) throws Exception {
        System.out.println("Hello world!");
    }
}

1 个答案

0
...