Почему Clojure не может вывести этот тип определения?
Я писал тест клиент-сервер и столкнулся с чем-то неожиданным. В следующем коде аргумент порта 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
или перед аргументом, но зачем это нужно? Разве не должно быть очевидно, что это за тип?
2 ответа
На самом деле невозможно определить тип значения, хранящегося в переменной в Clojure, потому что переменная может быть переопределена в любое время.
Однако у Clojure не должно быть проблем с определением типа во время выполнения, и, хотя для устранения неоднозначности во время выполнения потребуется использование отражения, соответствующий код должен (и должен) выполняться.
Кажется, ошибка связана с Cursive: /questions/7598085/kak-ustranit-neodnoznachnost-v-clojure/7598093#7598093
Добавление подсказки типа... для указания того, какую перегрузку вы ожидаете использовать, устранит необходимость в отражении и, возможно, успокоит Cursive down.
В вашем случае я бы попробовал что-то вроде:
(defn -main []
; "Cannot disambiguate overloads of Socket"
(let [^int p port
sock (Socket. "127.0.0.1" p)]))
В этом случае просто объявите, что вы var :const
:
(def ^:const port 5555)
(defn -main []
(let [sock (Socket. "127.0.0.1" port)]))