为什么Clojure无法推断此def类型?

3

我在编写客户端/服务器的测试代码时,遇到了一些意外情况。在下面的代码中,Socket 构造函数的端口参数无法被推断:

(ns second-try.test.client
  (:import [java.net Socket]))

(def port 5555)

(defn -main []
  ; "Cannot disambiguate overloads of Socket"
  (let [sock (Socket. "127.0.0.1" port)]))

第一个参数的类型应该很明显,因为我在传递一个文字。我认为端口的类型也应该很明显,因为它只是一个文字,尽管它被隐藏在def后面。
然而,出于某种原因,它无法确定port的类型。我可以通过在def前面或参数前面放置注释来解决这个问题,但为什么需要这样做呢?难道它不应该明确知道类型吗?

无法弄清楚端口问题?代码在我的电脑上运行良好。如果问题出现在 Cursive 上,请参阅此答案 - user2609980
@ErwinRooijakkers 我正在使用Cursive,可能是这个原因。 - Carcigenicate
2个回答

3
在Clojure中,由于var可以在任何时候被重新定义,因此不可能推断存储在var中的值的类型。
然而,在运行时,Clojure应该没有问题确定类型,并且尽管需要使用反射来消除歧义,但相关代码应该(并确实)运行。
错误似乎与Cursive有关:https://dev59.com/OY7ea4cB1Zd3GeqPHezy#32473508 引用如下:
“添加类型提示...以指定您希望使用哪个重载版本将消除反射的需求,并希望平静Cursive。”
在您的情况下,我会尝试类似以下内容:
(defn -main []
  ; "Cannot disambiguate overloads of Socket"
  (let [^int p port
        sock (Socket. "127.0.0.1" p)]))

有道理。我以前从未重新定义过 def,所以我从未考虑过这可能会成为一个问题。谢谢。 - Carcigenicate
1
你是不是想把“p”传递给构造函数? - Carcigenicate
@Carcigenicate,是的,我想让p传递给构造函数。谢谢。 - Nathan Davis

2
在这种情况下,只需将您的变量声明为:const
(def ^:const port 5555)

(defn -main []
  (let [sock (Socket. "127.0.0.1"  port)]))

酷,我不知道你可以那样做。谢谢。 - Carcigenicate

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接