标签: clojure-java-interop

如何在clojure中参数化对Java枚举的访问?

说我有一个Java枚举.例如:

public enum Suits {CLUBS, DIAMONDS, HEARTS, SPADES};
Run Code Online (Sandbox Code Playgroud)

通常情况下,我可以用这样的枚举做一些clojure:

(defn do-something []
   (let [s Suits/DIAMONDS] (...)))
Run Code Online (Sandbox Code Playgroud)

但是,我想编写一个clojure函数,允许调用者指定要使用的枚举实例:

(defn do-something-parameterized [suit]
   (let [s  Suits/suit] (...)))
Run Code Online (Sandbox Code Playgroud)

我们的想法是让呼叫者传递"DIAMONDS",并有DIAMONDS枚举实例获取绑定到slet.

我可以cond匹配参数,但这似乎比必要的笨拙.我想我也可以使用宏来构造Suits/添加到suit.这是做到这一点的方式还是有一种我失踪的非宏观方式?

clojure clojure-java-interop

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

Clojure deftype:如何约束字段类型?

我正在尝试编写一个可以在Java中使用的Clojure库,而用户不知道它是用Clojure编写的.为此,我需要我的字段有适当的类型:

我喜欢我可以这样做:

(deftype Point [^double x ^double y])
Run Code Online (Sandbox Code Playgroud)

这会为x/y生成一个具有适当类型的类.但是,这似乎只适用于原语,而不适用于类:

(deftype Foo [^String bar])
Run Code Online (Sandbox Code Playgroud)

生成一个:

public final Object bar;
Run Code Online (Sandbox Code Playgroud)

我期待的地方:

public final String bar;
Run Code Online (Sandbox Code Playgroud)

有没有办法约束字段类型?在deftype/ 之外还有其他选择defrecord吗?

java clojure clojure-java-interop

10
推荐指数
2
解决办法
698
查看次数

是否可以将Clojure的案例表单与Java枚举一起使用?

case医生说

与cond和condp不同,case执行常量时间调度......所有常量表达式都是可以接受的.

我想从caseJava枚举上的常量时间调度中获益.Java的switch声明适用于枚举,但在Clojure中执行以下操作:

(defn foo [x] 
   (case x 
      java.util.concurrent.TimeUnit/MILLISECONDS "yes!"))

(foo java.util.concurrent.TimeUnit/MILLISECONDS)
Run Code Online (Sandbox Code Playgroud)

结果是: IllegalArgumentException No matching clause: MILLISECONDS

枚举是否不受支持case?难道我做错了什么?我必须诉诸cond或有更好的解决方案吗?

clojure clojure-java-interop

10
推荐指数
2
解决办法
1027
查看次数

我可以在Clojure中部分Java方法调用吗?

我有一个对象的方法.

myObject.myMethod(1)
Run Code Online (Sandbox Code Playgroud)

我可以在Clojure中调用它

(.myMethod myObject 1)
Run Code Online (Sandbox Code Playgroud)

我也可以使用词汇环境中的信息来调用它

(let [x 1] (.myMethod myObject x))
Run Code Online (Sandbox Code Playgroud)

我可以部分地这样做吗?例如

(let [myPartial (partial .myMethod myObject)]
      (myPartial 1))
Run Code Online (Sandbox Code Playgroud)

这给了我一个

java.lang.RuntimeException:无法在此上下文中解析符号:.myMethod

我目前正在使用匿名函数进行此工作

(let [myThing #(.myMethod myObject %)]
      (myThing 1))
Run Code Online (Sandbox Code Playgroud)

但是如果在这种情况下使用部分会很好.可能吗?

我确定答案将是绑定和发送,但我还没有感觉在编译和执行期间发生的调度.

clojure clojure-java-interop

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

Clojure的点特殊形式怪异

我很好奇为什么这样可行(正如我在阅读点特殊表格上的文档后所期望的那样):

(map #(. % isInstance {}) [clojure.lang.IPersistentMap])
Run Code Online (Sandbox Code Playgroud)

收益:

(true)
Run Code Online (Sandbox Code Playgroud)

但这不是:

(. clojure.lang.IPersistentMap isInstance {})
Run Code Online (Sandbox Code Playgroud)

我收到一个错误,"没有匹配的方法:isInstance".表单与map上面的函数调用完全相同,但除此之外map,它不起作用.为什么?

clojure clojure-java-interop

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

Clojure的懒惰如何与调用Java /不纯的代码相互作用?

我们今天在我们的代码中偶然发现了一个问题,并且无法回答这个Clojure问题:

Clojure是严格还是懒惰地评估不纯的代码(或调用Java代码)?

似乎副作用+懒惰序列可能导致奇怪的行为.


以下是我们所知道的问题:

Clojure有懒惰的序列:

user=> (take 5 (range)) ; (range) returns an infinite list
(0 1 2 3 4)
Run Code Online (Sandbox Code Playgroud)

Clojure有副作用和不纯的功能:

user=> (def value (println 5))
5                               ; 5 is printed out to screen
user=> value
nil                             ; 'value' is assigned nil
Run Code Online (Sandbox Code Playgroud)

此外,Clojure可以调用Java对象,这可能包括副作用.然而,副作用可能与懒惰评估相互作用不佳:

user=> (def my-seq (map #(do (println %) %) (range)))
#'user/my-seq
user=> (take 5 my-seq)                               
(0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 …
Run Code Online (Sandbox Code Playgroud)

functional-programming clojure lazy-evaluation clojure-java-interop

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

clojure gen-class varargs构造函数

在:constructors map和后续-init定义中,我如何表示一个varargs构造函数(假设超类有多个构造函数,其中一个是varargs)?

clojure java-interop gen-class clojure-java-interop

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

使Java类在Clojure中作为序列工作

我使用的Java类代表一系列结果(有点像Clojure向量).

我想将这个类与典型的Clojure序列函数一起使用(即我希望该类的行为就像它支持序列抽象一样)但是我无法更改类,因此无法使其实现clojure.lang.Seqable或类似.另外,令人讨厌的是,该课程没有实现java.util.Collectionjava.lang.Iterable.

我可以看到几个选项:

  • 使用iterator-seq该对象的(现有的)迭代器.
  • 将对象包装在另一个实现java.util.Collection/的类中clojure.lang.Sequable
  • 创建一个通过查询Object来构建Clojure向量或序列的函数

还有其他选择吗?什么是最好的方法?

java clojure sequence clojure-java-interop

8
推荐指数
2
解决办法
551
查看次数

如何标记Clojure函数以便我可以使用Java反射识别它

我需要以某种方式将某些Clojure函数标记为"特殊",以便Java代码可以使用反射识别它们.我试图在函数中添加注释,但显然不支持.我试图reify扩展接口IFn(以便Java代码可以识别函数对象),但这并不好,因为Clojure不直接使用reified方法作为代码实现invoke,而是间接调用Afunction实际的对象实现该方法(我需要invoke用实际的功能代码标记实际的方法).

有任何想法吗?

编辑:甚至以可以使用ASM库(而不是常规反射)访问的方式进行标记也没问题,但我需要以某种方式标记实际AFunction对象或invoke方法.此外,我无法访问实际AFunction对象 - 我需要标记在类上可见.

clojure clojure-java-interop

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

如何在Clojure中读取stdin中的所有行

我在Clojure 写了一个Brainf***翻译.我想在使用stdin时传递一个程序.但是,我仍然需要稍后从stdin读取用户输入.

目前,我这样做:

$ cat sample_programs/hello_world.bf | lein trampoline run
Run Code Online (Sandbox Code Playgroud)

我的Clojure代码只读取第一行,使用read-line:

(defn -main
  "Read a BF program from stdin and evaluate it."
  []
  ;; FIXME: only reads the first line from stdin
  (eval-program (read-line)))
Run Code Online (Sandbox Code Playgroud)

如何阅读我用过的文件中的所有行?*in*似乎是一个实例java.io.Reader,但它只提供.read(一个字符),.readLine(一行)和read(char[] cbuf, int off, int len)(似乎非常低级别).

stdin clojure clojure-java-interop

8
推荐指数
2
解决办法
3622
查看次数