Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I cast a Java class in Clojure?

I would like to cast a clojure Java object (assigned with let*) to another Java class type. Is this possible and if so then how can I do this?

Update: Since I posted this question I have realised that I do not need to cast in Clojure as it has no concept of an interface, and is more like Ruby duck typing. I only need to cast if I need to know that an object is definitely of a certain type, in which case I get a ClassCastException

like image 552
yazz.com Avatar asked Sep 06 '10 15:09

yazz.com


People also ask

Can clojure use Java libraries?

Clojure programs get compiled to Java bytecode and executed within a JVM process. Clojure programs also have access to Java libraries, and you can easily interact with them using Clojure's interop facilities.

How do you call a method in Clojure?

If you want to call a static method of the String class, the syntax is (String/methodName arg1 arg2) .

Is clojure interoperable with Java?

Overview. Clojure was designed to be a hosted language that directly interoperates with its host platform (JVM, CLR and so on). Clojure code is compiled to JVM bytecode. For method calls on Java objects, Clojure compiler will try to emit the same bytecode javac would produce.


2 Answers

There is a cast function to do that in clojure.core:

user> (doc cast)
-------------------------
clojure.core/cast
([c x])
  Throws a ClassCastException if x is not a c, else returns x.

By the way, you shouldn't use let* directly -- it's just an implementation detail behind let (which is what should be used in user code).

like image 55
Michał Marczyk Avatar answered Oct 03 '22 07:10

Michał Marczyk


Note that the cast function is really just a specific type of assertion. There's no need for actual casting in clojure. If you're trying to avoid reflection, then simply type-hint:

user=> (set! *warn-on-reflection* true)
true
user=> (.toCharArray "foo")  ; no reflection needed
#<char[] [C@a21d23b>
user=> (defn bar [x]         ; reflection used
         (.toCharArray x))
Reflection warning, NO_SOURCE_PATH:17 - reference to field toCharArray can't be resolved.
#'user/bar
user=> (bar "foo")           ; but it still works, no casts needed!
#<char[] [C@34e93999>
user=> (defn bar [^String x] ; avoid the reflection with type-hint
         (.toCharArray x)) 
#'user/bar
user=> (bar "foo")
#<char[] [C@3b35b1f3>
like image 11
Alex Taggart Avatar answered Oct 03 '22 05:10

Alex Taggart