我正在测试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中导入Java类的一般想法,如下所示:
(import 'a.random.Class)
Run Code Online (Sandbox Code Playgroud)
但是,假设我有一个包含我想要使用的'Example'类的文件Example.java,如何导入这样的东西呢?
抱歉,如果这个相当noobish已经得到回答,我一直在环顾四周,但在发布之前一无所获,并提前感谢任何可以解决问题的人.
我正在创建一个生成.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 []转换为字节.但是我需要做些什么来实现这个目标呢?
我正在将一个实例绑定到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中使用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或逆时针.
我正在获取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) 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) 这是我想要的行为:
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上面的函数实际上不必运行测试只是为了返回它正在测试的值?或者 - 看到我对于按位运算符中涉及的时序/速度优化几乎一无所知 - 也许它似乎只是次优,但实际上是出于某种原因实现它的最快方式?
我不想刮一个网站,这需要我登录.我决定用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中实现餐饮哲学家的例子.由于某些原因,我的程序总是死于一个例外
"java.lang.UnsupportedOperationException:此类型不支持:布尔"
我无法理解这个错误消息,因为我已经尝试从列表中获取与第n个完美匹配的布尔值
我猜错误发生在函数philosopher-thread的if语句中
控制台打印:
码:
(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)