16

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

yazz.com
  • 57,320
  • 66
  • 234
  • 385

2 Answers2

18

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).

Michał Marczyk
  • 83,634
  • 13
  • 201
  • 212
11

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>
Alex Taggart
  • 7,805
  • 28
  • 31
  • 1
    Actually your right, I realised quite soon that since there are no notions of interfaces that casting isn't needed – yazz.com Sep 06 '10 at 17:48