我正在尝试实现一个简单的验证器方法 一个类型作为其第一个参数,一个String作为第二个参数,并始终返回传入类型的实例。没有进一步的麻烦 - 这是方法:
def validateType[T](taip: T, input: String):T = taip match {
case Boolean => {
val simplifiedInput = input.replaceAll("[ \\n]", "").toLowerCase()
if(simplifiedInput.matches("[yn]")){
simplifiedInput match {
case "y" => true
case "n" => false
}
} else{
validateType(Boolean, StdIn.readLine("$simplifiedInput is not a valid "
+"answer, please try again"))
}
}
}
但是我收到编译错误(我的IDE中的红色下划线)说: “类型不匹配;找到所需的布尔值(true):T
我意识到T
这里是type
,但是如何指定我想要返回该类型的实例?我也尝试使用ClassTag,但没有成功。谢谢。
答案 0 :(得分:3)
您可以使用TypeTag,例如:
import scala.reflect.runtime.universe._
def validateType[T](input: String)(implicit typeTag: TypeTag[T]): T = {
typeTag.tpe match {
case t if t =:= typeOf[Boolean] => {
val simplifiedInput = input.replaceAll("[ \\n]", "").toLowerCase()
if (simplifiedInput.matches("[yn]")) {
simplifiedInput match {
case "y" => true.asInstanceOf[T]
case "n" => false.asInstanceOf[T]
}
} else {
validateType(StdIn.readLine("$simplifiedInput is not a valid "
+ "answer, please try again"))
}
}
}
}
validateType[Boolean]("y") //set Boolean type for `T`
>true
用于测试=:=
是否相等的Type
。更多比较器见参考。对于返回类型到T
,您需要asInstanceOf[T]
强制。
答案 1 :(得分:3)
由于您需要给定类型的行为,而不是给定的对象或值,因此类型类将是相关的。
trait Validable[T] {
def validate(input: String): T
}
object Validable {
implicit val boolean = new Validable[Boolean] {
def validate(input: String): Boolean = {
val simplifiedInput = input.replaceAll("[ \\n]", "").toLowerCase()
if(simplifiedInput.matches("[yn]")){
simplifiedInput match {
case "y" => true
case "n" => false
}
} else {
validate(StdIn.readLine("$simplifiedInput is not a valid "
+"answer, please try again"))
}
}
//if you want to write a validator for another type, simply add a new instance.
implicit val otherTypeValidable = new Validable[OtherType] {
def validate(input: String): OtherType = ...
}
}
def validateType[T](input: String)(implicit validable: Validable[T]): T =
validable.validate(input)
validateType[Boolean]("y") // returns true
当然,您可以为每个相关类型实现类型类的实例。如果您将其与没有隐式Validable[T]
实例的类型一起使用,则会抛出编译错误,因此它比使用反射更安全。