说我有一个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枚举实例获取绑定到s的let.
我可以cond匹配参数,但这似乎比必要的笨拙.我想我也可以使用宏来构造Suits/添加到suit.这是做到这一点的方式还是有一种我失踪的非宏观方式?
我正在尝试编写一个可以在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吗?
该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或有更好的解决方案吗?
我有一个对象的方法.
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)
但是如果在这种情况下使用部分会很好.可能吗?
我确定答案将是绑定和发送,但我还没有感觉在编译和执行期间发生的调度.
我很好奇为什么这样可行(正如我在阅读点特殊表格上的文档后所期望的那样):
(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代码)?
似乎副作用+懒惰序列可能导致奇怪的行为.
以下是我们所知道的问题:
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
在:constructors map和后续-init定义中,我如何表示一个varargs构造函数(假设超类有多个构造函数,其中一个是varargs)?
我使用的Java类代表一系列结果(有点像Clojure向量).
我想将这个类与典型的Clojure序列函数一起使用(即我希望该类的行为就像它支持序列抽象一样)但是我无法更改类,因此无法使其实现clojure.lang.Seqable或类似.另外,令人讨厌的是,该课程没有实现java.util.Collection或java.lang.Iterable.
我可以看到几个选项:
iterator-seq该对象的(现有的)迭代器.java.util.Collection/的类中clojure.lang.Sequable还有其他选择吗?什么是最好的方法?
我需要以某种方式将某些Clojure函数标记为"特殊",以便Java代码可以使用反射识别它们.我试图在函数中添加注释,但显然不支持.我试图reify扩展接口IFn(以便Java代码可以识别函数对象),但这并不好,因为Clojure不直接使用reified方法作为代码实现invoke,而是间接调用Afunction实际的对象实现该方法(我需要invoke用实际的功能代码标记实际的方法).
有任何想法吗?
编辑:甚至以可以使用ASM库(而不是常规反射)访问的方式进行标记也没问题,但我需要以某种方式标记实际AFunction对象或invoke方法.此外,我无法访问实际AFunction对象 - 我需要标记在类上可见.
我在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)(似乎非常低级别).