This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Pattern match on class literals

4 replies
Naftoli Gugenheim
Joined: 2008-12-17,
User offline. Last seen 42 years 45 weeks ago.

How do you pattern match on something like class literals, or for that matter anything that is only available from a function that starts with lowercase?
clazz match {
 case classOf[java.lang.Integer] => ...
}
doesn't work, and adding back ticks `...` causes the [ to be invalid syntax.
I need to match on a bunch of possibilities, so defining uppercase constants for each one isn't such a good idea, and putting the comparison as an if guard:
  case c if c==classOf[...] => ...
seems to make pattern matching extra -- I might as well just right a bunch of if/else ifs, which is what I did in meanwhile.
Another option that I don't like is matching on clazz.getName
Similar situations (not tested recently):
 case v.getA =>
 case getCalculation(param) =>
Is there no straightforward solution for such a typical scenario?
Thanks!
 

David Pollak
Joined: 2008-12-16,
User offline. Last seen 42 years 45 weeks ago.
Re: Pattern match on class literals
scala> val StrCls = classOf[String]
StrCls: java.lang.Class[String] = class java.lang.String

scala> val ObjCls = classOf[Object]
ObjCls: java.lang.Class[java.lang.Object] = class java.lang.Object

scala> def m(c: Class[_]) = c match {
     | case ObjCls => "Object"      
     | case StrCls => "String"      
     | case _ => "Huh?"             
     | }
m: (Class[_])java.lang.String

scala> m(classOf[String])
res1: java.lang.String = String

scala> m(classOf[AnyRef])
res2: java.lang.String = Object

scala> m(classOf[Int])  
res3: java.lang.String = Huh?


On Wed, Jan 7, 2009 at 12:35 PM, Naftoli Gugenheim <naftoligug [at] gmail [dot] com> wrote:
How do you pattern match on something like class literals, or for that matter anything that is only available from a function that starts with lowercase? clazz match {  case classOf[java.lang.Integer] => ... } doesn't work, and adding back ticks `...` causes the [ to be invalid syntax. I need to match on a bunch of possibilities, so defining uppercase constants for each one isn't such a good idea, and putting the comparison as an if guard:   case c if c==classOf[...] => ... seems to make pattern matching extra -- I might as well just right a bunch of if/else ifs, which is what I did in meanwhile. Another option that I don't like is matching on clazz.getName Similar situations (not tested recently):  case v.getA =>  case getCalculation(param) => Is there no straightforward solution for such a typical scenario? Thanks!  



--
Lift, the simply functional web framework http://liftweb.net
Collaborative Task Management http://much4.us
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp
Naftoli Gugenheim
Joined: 2008-12-17,
User offline. Last seen 42 years 45 weeks ago.
Re: Pattern match on class literals
Thanks, but as I specifically said: "I need to match on a bunch of possibilities, so defining uppercase constants for each one isn't such a good idea"... Is there really no better way?

On Wed, Jan 7, 2009 at 3:42 PM, David Pollak <feeder [dot] of [dot] the [dot] bears [at] gmail [dot] com> wrote:
scala> val StrCls = classOf[String]
StrCls: java.lang.Class[String] = class java.lang.String

scala> val ObjCls = classOf[Object]
ObjCls: java.lang.Class[java.lang.Object] = class java.lang.Object

scala> def m(c: Class[_]) = c match {
     | case ObjCls => "Object"      
     | case StrCls => "String"      
     | case _ => "Huh?"             
     | }
m: (Class[_])java.lang.String

scala> m(classOf[String])
res1: java.lang.String = String

scala> m(classOf[AnyRef])
res2: java.lang.String = Object

scala> m(classOf[Int])  
res3: java.lang.String = Huh?


On Wed, Jan 7, 2009 at 12:35 PM, Naftoli Gugenheim <naftoligug [at] gmail [dot] com> wrote:
How do you pattern match on something like class literals, or for that matter anything that is only available from a function that starts with lowercase? clazz match {  case classOf[java.lang.Integer] => ... } doesn't work, and adding back ticks `...` causes the [ to be invalid syntax. I need to match on a bunch of possibilities, so defining uppercase constants for each one isn't such a good idea, and putting the comparison as an if guard:   case c if c==classOf[...] => ... seems to make pattern matching extra -- I might as well just right a bunch of if/else ifs, which is what I did in meanwhile. Another option that I don't like is matching on clazz.getName Similar situations (not tested recently):  case v.getA =>  case getCalculation(param) => Is there no straightforward solution for such a typical scenario? Thanks!  



--
Lift, the simply functional web framework http://liftweb.net
Collaborative Task Management http://much4.us
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp

David Pollak
Joined: 2008-12-16,
User offline. Last seen 42 years 45 weeks ago.
Re: Pattern match on class literals
No better way using Pattern Matching, but if you've got a lot, why not use a Map:

val toDo: Map[Class[_], () => Unit] = Map(
  (classOf[String], () => println("Got a String")),
  (classOf[Object], () => println("Got an object")))

toDo(classOf[String])()



On Wed, Jan 7, 2009 at 12:44 PM, Naftoli Gugenheim <naftoligug [at] gmail [dot] com> wrote:
Thanks, but as I specifically said: "I need to match on a bunch of possibilities, so defining uppercase constants for each one isn't such a good idea"... Is there really no better way?

On Wed, Jan 7, 2009 at 3:42 PM, David Pollak <feeder [dot] of [dot] the [dot] bears [at] gmail [dot] com> wrote:
scala> val StrCls = classOf[String]
StrCls: java.lang.Class[String] = class java.lang.String

scala> val ObjCls = classOf[Object]
ObjCls: java.lang.Class[java.lang.Object] = class java.lang.Object

scala> def m(c: Class[_]) = c match {
     | case ObjCls => "Object"      
     | case StrCls => "String"      
     | case _ => "Huh?"             
     | }
m: (Class[_])java.lang.String

scala> m(classOf[String])
res1: java.lang.String = String

scala> m(classOf[AnyRef])
res2: java.lang.String = Object

scala> m(classOf[Int])  
res3: java.lang.String = Huh?


On Wed, Jan 7, 2009 at 12:35 PM, Naftoli Gugenheim <naftoligug [at] gmail [dot] com> wrote:
How do you pattern match on something like class literals, or for that matter anything that is only available from a function that starts with lowercase? clazz match {  case classOf[java.lang.Integer] => ... } doesn't work, and adding back ticks `...` causes the [ to be invalid syntax. I need to match on a bunch of possibilities, so defining uppercase constants for each one isn't such a good idea, and putting the comparison as an if guard:   case c if c==classOf[...] => ... seems to make pattern matching extra -- I might as well just right a bunch of if/else ifs, which is what I did in meanwhile. Another option that I don't like is matching on clazz.getName Similar situations (not tested recently):  case v.getA =>  case getCalculation(param) => Is there no straightforward solution for such a typical scenario? Thanks!  



--
Lift, the simply functional web framework http://liftweb.net
Collaborative Task Management http://much4.us
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp




--
Lift, the simply functional web framework http://liftweb.net
Collaborative Task Management http://much4.us
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp
David Biesack
Joined: 2008-11-18,
User offline. Last seen 2 years 38 weeks ago.
Re: Pattern match on class literals

David P posted one way:

> Date: Wed, 7 Jan 2009 12:42:16 -0800
> From: David Pollak
> CC:
>
> scala> val StrCls = classOf[String]
> StrCls: java.lang.Class[String] = class java.lang.String
>
> scala> val ObjCls = classOf[Object]
> ObjCls: java.lang.Class[java.lang.Object] = class java.lang.Object
>
> scala> def m(c: Class[_]) = c match {
> | case ObjCls => "Object"
> | case StrCls => "String"
> | case _ => "Huh?"
> | }
> m: (Class[_])java.lang.String
>
> scala> m(classOf[String])
> res1: java.lang.String = String
>
> scala> m(classOf[AnyRef])
> res2: java.lang.String = Object
>
> scala> m(classOf[Int])
> res3: java.lang.String = Huh?

although you stated

> > I need to match on a bunch of possibilities, so defining uppercase
> > constants for each one isn't such a good idea

But perhaps there is an alternative way to achieve what you want.

Can you instead match on an instance (i.e. you did not state where clazz
is coming from... If it is

val clazz = o.getClass()

then instead you may want to just use:

o match {
case i : String => ...
case m : MyType => ...
case y : YourType => ...
}

Or, perhaps you can use a classMap : Map[Class,Runnable] = {...} and then simply call

classMap(clazz).run()

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland