Общая функция для создания параметров - PullRequest
0 голосов
/ 03 мая 2019

Предполагается, что приведенная ниже функция принимает value типа String и возвращает Option, который соответствует типу второго аргумента функции, например,

toOption[Double]("10", classOf[Double])

def toOption[A](value: String, classType: A): Option[A] = {
    classType match {
        case _: Int => {
            try {
                Some(value.trim().toInt)
            } catch {
                case e: NumberFormatException => None
            }
        }
        case _: Double => {
            try {
                Some(value.trim().toDouble)
            } catch {
                case e: NumberFormatException => None
            }
        }
        case _: java.sql.Timestamp => {
            try {
                Some(java.sql.Timestamp.valueOf(value.trim()))
            } catch {
                case e: NumberFormatException => None
            }
        }
        case _ => None
    }
}

Однако, поскольку функция в настоящее время есть, я получаю ошибки ниже. Как я могу / должен устранить эти ошибки?

<console>:15: error: type mismatch;
 found   : Int
 required: A
                       Some(value.trim().toInt)
                                         ^
<console>:22: error: type mismatch;
 found   : Double
 required: A
                       Some(value.trim().toDouble)
                                         ^
<console>:29: error: type mismatch;
 found   : java.sql.Timestamp
 required: A
                       Some(java.sql.Timestamp.valueOf(value.trim()))

Ответы [ 2 ]

4 голосов
/ 03 мая 2019

Да, вы должны разыграть его: Some(value.trim.toInt).asInstanceOf[A]. Он не знает, что A как Int.

Вот лучший способ:

 trait FromString[T] { 
   def convert(s: String): T
   def apply(s: String): Option[T] = Try(convert(s.trim)).toOption
 }

 implicit object IntFromString extends FromString[Int] {
   def convert(s: String) = s.toInt
 }
 implicit object DoubleFromString extends FromString[Double] {
   def convert(s: String) = s.toDouble
 } 
 // etc.

Итак, теперь вы можете написать:

def toOption[T : FromString](s: String): Option[T] = implicitly[FromString[T]](s)

Или, если вы хотите получить None обратно, когда преобразование не определено:

def toOption[T](s: String)(implicit conv: FromString[T] = null) = Option(conv)
 .flatMap(_.apply(s))
0 голосов
/ 03 мая 2019

Приведение решает вашу проблему, потому что компилятор не может связать отображение с типом, который вы получаете из сопоставления с образцом.

import scala.util.Try

def toOption[A](value: String, classType: A): Option[A] = {
classType match {
  case _: Int =>
    Try {
      value.trim().toInt.asInstanceOf[A]
    } toOption
  case _: Double =>
    Try {
      value.trim().toDouble.asInstanceOf[A]
    } toOption
  case _: java.sql.Timestamp =>
    Try {
      java.sql.Timestamp.valueOf(value.trim()).asInstanceOf[A]
    } toOption
  case _ => Option.empty[A]
 }
}

Редактировать: решение Димы с классом типов более элегантно

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...