简体   繁体   中英

Scala Generic Type as Class Parameter and matching (& Slick)

I'm trying to understand how to pass a type parameter to a class during pattern matching and have it implied for the subsequent method (not a part of the class being matched on), like so:

class:

case class QueryRequest[A](data: List[A])

pattern match:

def receive = {

    case QueryRequest(data) => sender ! QueryResponse(setScanRecords(data))
...
}

method:

 def setScanRecords[A](data: List[A]) = 
     db withTransaction { data foreach ScanRecords.insert }

Type A will be a tuple of variable composition, for example:

(String, String, Long)

or

(String, String, String, String)

etc.

What's the best way to do this? Currently setScanRecords throws the following exception:

type mismatch; found : [TT](query: scala.slick.lifted.Query[TT,(String, String, Long)])(implicit session: scala.slick.session.Session)Int <and> (value: (String, String, Long))(implicit session: scala.slick.session.Session)Int required: A => ?

Edit1:

To elaborate, another type of error occurs when I explicitly call out the type in the method in the method call:

method:

def setScanRecords(data: List[(String, String, Long)]) = 
     db withTransaction { data foreach ScanRecords.insert }

error:

case QueryRequest(data) => sender ! QueryResponse(setScanRecords(data))

type mismatch; found : Any required: List[(String, String, Long)]

messages received in receive method have no type informations.

Doing pattern matching is to get the message of the types you want to deal with (which is a list of Tuple N ) in order to use the message in the following expressions. But, in InsertQueryRequest(data) , the type is still uncertain, which causes the error.

Maybe, you can send the data along with the tuple type message.

And I wonder how db insert records without knowing the tuple N is.

I ended up pattern matching data in setScanRecords in order to make sure the type / data being passed to the function conformed to the database insert criteria.

def setScanRecords[A](data: List[A]) =
    db withTransaction {
      data foreach {
        case (a: String, b: String, c: Long) => ScanRecords.insert(a, b, c)
        case s => throw new Exception(s"Expected (String, String, Long) but found something else: $s")
      }
    }

Until I find a more elegant solution, I've gone this route.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM