2017-01-14 7 views
3

Я писал тест клиент/сервер и столкнулся с чем-то неожиданным. В следующем коде, аргумент порта Socket конструктор не может быть выведено:Почему Clojure не может вывести этот тип def?

(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 или перед аргументом, но зачем это необходимо? Разве не должно быть очевидно, что это за тип?

+0

Что не могу понять, порт ? Код отлично работает на моей машине. Если проблема связана с Cursive, см. [Этот ответ] (http://stackoverflow.com/questions/32472894/how-to-disambiguate-in-clojure). –

+0

@ErwinRooijakkers Я использую Cursive, чтобы это было возможно. – Carcigenicate

ответ

3

Невозможно вывести тип значения, хранящегося в var в Clojure, поскольку var может быть переопределен в любое время.

Однако у Clojure не должно возникнуть проблем с определением типа во время выполнения и, хотя для выполнения во время выполнения использования рефлексии потребуется использовать рефлексию, этот код должен (и должен) запускаться.

Ошибка по-видимому, связано с Cursive: https://stackoverflow.com/a/32473508/440294

Добавление типа-подсказку ..., чтобы указать, какие перегружать вы планируете использовать устранило бы необходимость отражения и, надеюсь, успокаивает Курсив вниз.

В вашем случае, я хотел бы попробовать что-то вроде:

(defn -main [] 
    ; "Cannot disambiguate overloads of Socket" 
    (let [^int p port 
     sock (Socket. "127.0.0.1" p)])) 
+0

Это имеет смысл. Я никогда не переопределял 'def' раньше, поэтому я никогда не думал о том, что это проблема. Благодарю. – Carcigenicate

+1

Вы имели в виду, что для 'p' нужно передать конструктору? – Carcigenicate

+0

@Carcigenicate, да, я имел в виду, что 'p' должен быть передан конструктору. Благодарю. –

2

В этом случае, просто объявить, что вы Var быть :const:

(def ^:const port 5555) 

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

Прохладный, я не знал, что вы можете это сделать. Благодарю. – Carcigenicate