标签: clojure-java-interop

如何在clojure/leiningen中要求java类

我正在测试Clojure/Java互操作.我创建了一个新的Leiningen项目并创建了这个project.clj文件,其中包含一些我将使用的依赖项:

    (defproject kente "0.1.0-SNAPSHOT"
      :description "FIXME: write description"
      :url "http://example.com/FIXME"
      :license {:name "Eclipse Public License"
                :url "http://www.eclipse.org/legal/epl-v10.html"}
      :dependencies [[org.clojure/clojure "1.4.0"]
                     [ring/ring-jetty-adapter "1.0.0-RC1"]
                     [compojure "0.6.5"]
                     [hiccup "0.3.7"]
                     [cheshire "5.0.1"]]
      :java-source-paths ["src/java"]
      :plugins [[lein-ring "0.8.2"]]
      :ring {:handler kente.core/application}
      :main kente.core)
Run Code Online (Sandbox Code Playgroud)

我还包括了"java-source-paths"列表,并将一个hello.java文件放入src/java目录中,如下所示:

public class hello {

    private String msg = "Hello World";

    public String sayHello() {
        return this.msg;
    }

}
Run Code Online (Sandbox Code Playgroud)

然后我从模板创建了这个core.clj文件:

    (ns kente.core
      (:require [java/hello]))

    (defn application
      "I don't do a whole lot."
      [x]
      (println x "Hello, World!"))

    (defn -main [] (application "Say: …
Run Code Online (Sandbox Code Playgroud)

clojure leiningen clojure-java-interop

3
推荐指数
1
解决办法
2669
查看次数

将本地Java类导入Clojure

我理解在clojure中导入Java类的一般想法,如下所示:

(import 'a.random.Class)
Run Code Online (Sandbox Code Playgroud)

但是,假设我有一个包含我想要使用的'Example'类的文件Example.java,如何导入这样的东西呢?

抱歉,如果这个相当noobish已经得到回答,我一直在环顾四周,但在发布之前一无所获,并提前感谢任何可以解决问题的人.

clojure clojure-java-interop

3
推荐指数
1
解决办法
561
查看次数

如何连接/展平字节数组

我正在创建一个生成.wav文件的函数.我已经设置了标题,但是我遇到了麻烦data.我有一个函数用于创建880Hz的正弦波(至少我认为这是它的作用,但这不是我的问题) - 问题是,如何将字节数组的集合转换为只有一个字节数组及其内容?这是我最好的尝试:

(defn lil-endian-bytes [i]
  (let [i (int i)]
  (byte-array
    (map #(.byteValue %)
         [(bit-and i 0x000000ff)
          (bit-shift-right (bit-and i 0x0000ff00) 8)
          (bit-shift-right (bit-and i 0x00ff0000) 16)
          (bit-shift-right (bit-and i 0xff000000) 24)]))))

(def leb lil-endian-bytes)

(let [wr (io/output-stream (str name ".wav") :append true)]
  (.write wr
       (byte-array (flatten (concat (map 
         (fn [sample] (leb (* 0xffff (math/sin (+ (* 2 3.14 880) sample)))))
         (range (* duration s-rate)) )))))
Run Code Online (Sandbox Code Playgroud)

但它没有做我想做的事情:将所有字节数组连接成一个向量,然后连接到单个字节数组.这对我来说有意义为什么它不能:它不能连接/压平一个字节[]因为它不是一个向量; 它是一个字节[].并且它不能将byte []转换为字节.但是我需要做些什么来实现这个目标呢?

io audio clojure clojure-java-interop

2
推荐指数
1
解决办法
1253
查看次数

将java实例的clojure绑定更正为Vars

我正在将一个实例绑定到Var:

(ns org.jb
  (:import (java.awt PopupMenu
                     TrayIcon
                     Toolkit
                     SystemTray)

           (javax.swing JFrame
                        Action)))

(def ^:dynamic popupmenu)
(def ^:dynamic image)
(def ^:dynamic trayicon)
(def ^:dynamic tray)

(defn start-app [appname icon]
  (binding [popupmenu (new PopupMenu)
            image (.. Toolkit (getDefaultToolkit) (getImage icon))
            trayicon (new TrayIcon image appname popupmenu)
            tray (. SystemTray getSystemTray)]

    (. trayicon setImageAutoSize true)    

    (. tray add trayicon)))

(start-app "escap" "res/escap_icon.png")
Run Code Online (Sandbox Code Playgroud)

错误:

ClassCastException clojure.lang.Var$Unbound cannot be cast to java.awt.Image  org.jb/start-app (org\jb.clj:17)
Run Code Online (Sandbox Code Playgroud)

我正在预定Var

(def image)
Run Code Online (Sandbox Code Playgroud)

甚至尝试过

(def ^:dynamic image)
Run Code Online (Sandbox Code Playgroud)

无法理解消息的期望.

但是,在词法范围内使用let代替绑定工作.但是想要实现动态绑定.

clojure clojure-java-interop

2
推荐指数
1
解决办法
389
查看次数

ClassCastException MyType无法强制转换为MyType?

我在Clojure中使用deftype时遇到了问题.如果我运行以下代码:

(defprotocol TestProt
  (geta [this])
  (getb [this]))

(deftype TestType [a b]
  TestProt
  (geta [this] a)
  (getb [this] b))

(defn test-function [^TestType a-testtype]
  (print (.geta a-testtype))) 

(def test-tt (TestType. 1 1))

(test-function test-tt)
Run Code Online (Sandbox Code Playgroud)

然后编译器抛出:ClassCastException MyProject.core.TestType无法强制转换为MyProject.core.TestType.我做错了什么,或者这是一个错误?请注意,如果我从test-function中删除类型注释,那么它只是:

(defn test-function [a-testtype]
  (print (.geta a-testtype))) 
Run Code Online (Sandbox Code Playgroud)

然后代码工作正常,但我得到一个关于反射的警告(启用了反射警告),并且它运行得更慢,这违背了在我当前用例中使用deftype的目的.

编辑:好的,代码在repl中工作,但是当我使用ctrl-alt-s加载它时(我在Eclipse中通过逆时针运行它).所以问题似乎是Eclipse或逆时针.

java jvm clojure clojure-java-interop counterclockwise

2
推荐指数
1
解决办法
134
查看次数

带类型提示的Clojure deftype ?:找不到匹配方法,省略了自动匹配的提示

我正在获取IllegalArgumentException: Can't find matching method: render, leave off hints for auto match,但是我需要类型提示来重载该方法。我想念什么...?

(defprotocol LinkRendererProtocol                                                                                                                                                                                                             
  (render                                                                                                                                                                                                                                     
    [this node]                                                                                                                                                                                                                               
    [this node text]                                                                                                                                                                                                                          
    [this node url title text]                                                                                                                                                                                                                
))                                                                                                                                                                                                                                            


(deftype LinkRenderer [handlers]                                                                                                                                                                                                              
  LinkRendererProtocol                                                                                                                                                                                                                        

  (render [this ^AutoLinkNode node]                                                                                                                                                                                                           
    (rendering :auto-link handlers node))                                                                                                                                                                                                     
  (render [this ^ExpLinkNode  node text]                                                                                                                                                                                                      
    (rendering :exp-link handlers node text))                                                                                                                                                                                                 
  (render [this ^ExpImageNode node text]                                                                                                                                                                                                      
    (rendering :exp-image-link handlers node text))                                                                                                                                                                                           
  (render [this ^MailLinkNode node]                                                                                                                                                                                                           
    (rendering :mail-link handlers node))                                                                                                                                                                                                     
  (render [this ^RefLinkNode  node url title text]                                                                                                                                                                                            
    (rendering :ref-link handlers node url …
Run Code Online (Sandbox Code Playgroud)

clojure clojure-java-interop

2
推荐指数
1
解决办法
615
查看次数

为什么这个Clojure代码与Java中的替代代码相比如此之慢?

tl; dr:为什么代码如此慢?

我尝试优化以下代码以提高速度; 它的目的是在进行n ^ 2次操作时将一个数组(大小n = 1000)转换为另一个(相同大小),转换的细节现在并不重要.

因为我试图尽可能快地获得速度,所以我尽可能使用Java原语; 仍然,我得到的通常是每个'转换'调用大约70毫秒.重写到Java时,平均调用时间小于2毫秒.

1)哇,Java很快

2)哇,Clojure很慢

3)你能解释一下,为什么会这样?天真地,我希望Clojure能够生成一个代码字节码,它应该非常接近Java,为什么不是这样呢?

4)我不是百分百肯定如何使用这些^提示,也许我弄错了?

(defn transform [^ints src]
  (let [res ^ints (make-array Integer/TYPE 1000)]
    (loop [x (int 0)]
      (if (= 1000 x) res
        (do
          (aset res x (areduce src i ret (int 0) 
            (+ ret (* (mod x 2) (mod i 3) (aget src i)))))
          (recur (inc x)))))))

(let [arr (into-array Integer/TYPE (range 1000))]
  (doseq [_ (range 20)]
      (println (time (transform arr)))
  ))
Run Code Online (Sandbox Code Playgroud)

java arrays performance clojure clojure-java-interop

2
推荐指数
1
解决办法
256
查看次数

有点功能吗?

这是我想要的行为:

user> (bit-get 4 2)
> 1
Run Code Online (Sandbox Code Playgroud)

我知道这可以超级轻松地使用bit-test,即:

(defn bit-get [x n]
  (if (bit-test x n) 1 0))
Run Code Online (Sandbox Code Playgroud)

但我很好奇是否已有任何东西.它可能对我来说有点小,但它似乎不是最佳(但是最低限度)必须测试某些东西是否,0或者1然后返回它们是否是0或者1基于该测试.因此,我也很高兴听到有任何方法可以在这里切断中间人,无论bit-getClojure或Java世界中是否有任何以前制作的功能.或许我首先弄错了,关于编译或运行时优化的一些事情使我bit-get上面的函数实际上不必运行测试只是为了返回它正在测试的值?或者 - 看到我对于按位运算符中涉及的时序/速度优化几乎一无所知 - 也许它似乎只是次优,但实际上是出于某种原因实现它的最快方式?

bit-manipulation clojure clojure-java-interop

1
推荐指数
1
解决办法
191
查看次数

在clojure中指定对象类

我不想刮一个网站,这需要我登录.我决定用Jsoup来做这件事.我无法正确地将这行代码"翻译"到Clojure:

Connection.Response loginForm = Jsoup.connect("**url**")
        .method(Connection.Method.GET)
        .execute();
Run Code Online (Sandbox Code Playgroud)

如果没有Connection.Response在我的Clojure代码中指定类,则连接具有类jsoup.helper.HttpConnect,该类缺少会话中的cookie所需的方法.

到目前为止,我已经提出了以下Clojure代码:

(import (org.jsoup Jsoup Connection
               Connection$Response Connection$Method))
(do
 (def url "*URL*")
 (def res (doto (org.jsoup.Jsoup/connect url)
   (.data "username" "*USERNAME*")
   (.data "password" "*PASSWORD")
   (.method Connection$Method/POST)
   (.execute)))
 (type res))
Run Code Online (Sandbox Code Playgroud)

clojure jsoup clojure-java-interop

1
推荐指数
1
解决办法
114
查看次数

Clojure:此类型不支持:布尔"

我正试图在clojure中实现餐饮哲学家的例子.由于某些原因,我的程序总是死于一个例外

"java.lang.UnsupportedOperationException:此类型不支持:布尔"

我无法理解这个错误消息,因为我已经尝试从列表中获取与第n个完美匹配的布尔值

我猜错误发生在函数philosopher-threadif语句

控制台打印:

  • 3在思考
  • 1正在思考
  • 4在思考
  • 0在想
  • 2在思考
  • 睡觉后0
  • 思考后0
  • 0交换
  • 0正在吃
  • 睡了3后
  • 思考后3

码:

(ns dining-philosphers.core
  (:gen-class))

(defn think [n] 
  (println (str n " is thinking"))
  (Thread/sleep (rand 1000))
  (println (str n " after sleep"))
)

(defn eat [n] 
  (println (str n " is eating"))
  (Thread/sleep (rand 1000))
)

(def isEating (atom '(false false false false false)))


(defn philosopher-thread [n] 
  (Thread. #( 
    (while true (do  
      (think n) 
      (println (str n " after think")) …
Run Code Online (Sandbox Code Playgroud)

clojure clojure-java-interop

1
推荐指数
1
解决办法
468
查看次数