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

About Class Type match

3 replies
outersky
Joined: 2008-09-03,
User offline. Last seen 4 years 6 weeks ago.
Hi, all,

I have the following codes:
            
    if(clz == classOf[String] ){
        return Some( (rs getString name).asInstanceOf[T] );
    }else if(clz == classOf[Int] ){
        return Some( (rs getInt name).asInstanceOf[T]);
    }else if(clz == classOf[Date] ){
        return Some( (rs getDate name).asInstanceOf[T]);
    }
    return None;

when I try to rewrite it to :

return clz match {
        case x : Class[Int] => Some(rs getInt name)
        case x : Class[Date] => Some(rs getDate name)
        case x : Class[String] => Some(rs getString name)
        case _ => None
    }

The compiler told me that those case statements except the first one, are unreachable ? why? and how ?

Thanks.

outersky

Viktor Klang
Joined: 2008-12-17,
User offline. Last seen 1 year 27 weeks ago.
Re: About Class Type match
Due to type erasure?

On Tue, Mar 3, 2009 at 3:17 PM, lu dongping <outersky [at] gmail [dot] com> wrote:
Hi, all,

I have the following codes:
            
    if(clz == classOf[String] ){
        return Some( (rs getString name).asInstanceOf[T] );
    }else if(clz == classOf[Int] ){
        return Some( (rs getInt name).asInstanceOf[T]);
    }else if(clz == classOf[Date] ){
        return Some( (rs getDate name).asInstanceOf[T]);
    }
    return None;

when I try to rewrite it to :

return clz match {
        case x : Class[Int] => Some(rs getInt name)
        case x : Class[Date] => Some(rs getDate name)
        case x : Class[String] => Some(rs getString name)
        case _ => None
    }

The compiler told me that those case statements except the first one, are unreachable ? why? and how ?

Thanks.

outersky




--
Viktor Klang
Senior Systems Analyst
David Pollak
Joined: 2008-12-16,
User offline. Last seen 42 years 45 weeks ago.
Re: About Class Type match
Outersky,
Try the following... create a set of stable identifiers that have classes assigned to them:
val IntCls = classOf[Int]val StrCls = classOf[String]
And then:
def in[T](cls: Class[T], rs: ResultSet, name: String): Option[T] = cls match {  case IntCls => Some((rs getInt name).asInstanceOf[T])  case StrCls => Some((rs getString name).asInstanceOf[T])   case _ => None}
It's a tad more verbose than one would like, but JDBC and Scala don't play as cleanly together as I'd like.
Hope this helps.
Thanks,
David
On Tue, Mar 3, 2009 at 6:17 AM, lu dongping <outersky [at] gmail [dot] com> wrote:
Hi, all,

I have the following codes:
            
    if(clz == classOf[String] ){
        return Some( (rs getString name).asInstanceOf[T] );
    }else if(clz == classOf[Int] ){
        return Some( (rs getInt name).asInstanceOf[T]);
    }else if(clz == classOf[Date] ){
        return Some( (rs getDate name).asInstanceOf[T]);
    }
    return None;

when I try to rewrite it to :

return clz match {
        case x : Class[Int] => Some(rs getInt name)
        case x : Class[Date] => Some(rs getDate name)
        case x : Class[String] => Some(rs getString name)
        case _ => None
    }

The compiler told me that those case statements except the first one, are unreachable ? why? and how ?

Thanks.

outersky




--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp
James Iry
Joined: 2008-08-19,
User offline. Last seen 1 year 23 weeks ago.
Re: About Class Type match
First, one general comment - "return" is generally unnecessary in Scala and is usually a code smell except when you really need the power of non-local return.  Also, if is an expression.  So your first if/else example can be written as

def get[T](clz: Class[_], rs: ResultSet, name: String): Option[T] = {
    val result = if(clz == classOf[String] )
        Some(rs getString name)
    else if(clz == classOf[Int] ){
        Some(rs getInt name)
    else if(clz == classOf[Date] )
        Some(rs getDate name)
     else None
     result map (_.asInstanceOf[T])
}

Anyway, your problem is runtime type erasure.  Type parameters are erased from runtime code, so the runtime types of Class[Int] and Class[String] look the same at runtime.  Your match based code is the equivalent of checking isInstanceOf

scala> val x = classOf[String]
x: java.lang.Class[String] = class java.lang.String

scala> x.isInstanceOf[Class[String]]
warning: there were unchecked warnings; re-run with -unchecked for details
res3: Boolean = true

scala> x.isInstanceOf[Class[Int]]  
warning: there were unchecked warnings; re-run with -unchecked for details
res4: Boolean = true

Running with -unchecked

scala> x.isInstanceOf[Class[Int]]
<console>:6: warning: non variable type-argument Int in type is unchecked since it is eliminated by erasure
       x.isInstanceOf[Class[Int]]

As David showed in his email, it is possible to do it with pattern matching, just awkward because classOf can't be written in a pattern match.

On Tue, Mar 3, 2009 at 6:17 AM, lu dongping <outersky [at] gmail [dot] com> wrote:
Hi, all,

I have the following codes:
            
    if(clz == classOf[String] ){
        return Some( (rs getString name).asInstanceOf[T] );
    }else if(clz == classOf[Int] ){
        return Some( (rs getInt name).asInstanceOf[T]);
    }else if(clz == classOf[Date] ){
        return Some( (rs getDate name).asInstanceOf[T]);
    }
    return None;

when I try to rewrite it to :

return clz match {
        case x : Class[Int] => Some(rs getInt name)
        case x : Class[Date] => Some(rs getDate name)
        case x : Class[String] => Some(rs getString name)
        case _ => None
    }

The compiler told me that those case statements except the first one, are unreachable ? why? and how ?

Thanks.

outersky


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