首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >String函数的Scala泛型转换

String函数的Scala泛型转换
EN

Stack Overflow用户
提问于 2015-06-03 18:09:38
回答 3查看 1.6K关注 0票数 1

如何编写函数将字符串转换为泛型类型(Double、Int、Float等)?

下面是我要寻找的功能的伪代码:

代码语言:javascript
复制
def castFromString[A: Manifest](value: String): A = {
  if (A == Double) {
    parseDouble(value)
  } else if (A == Int) {
    parseInt(value)
  } else {
    value.toString()
  }
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-06-03 22:50:11

我认为没有一种方法可以用ManifestClassTagTypeTag编写函数,因为它们只能在运行时告诉您类型。要使伪代码函数工作,必须在编译时知道返回类型。

但是,可以通过定义类型类并为希望转换的类型编写实例来实现该函数。下面是一个例子:

代码语言:javascript
复制
import java.lang.Double.parseDouble
import java.lang.Integer.parseInt

trait CastableFromString[A] {
  def fromString(string: String): A
}

object CastableFromString {
  implicit object DoubleCastableFromString extends CastableFromString[Double] {
    override def fromString(string: String): Double =
      parseDouble(string)
  }

  implicit object IntCastableFromString extends CastableFromString[Int] {
    override def fromString(string: String): Int =
      parseInt(string)
  }

  implicit object IntListCastableFromString extends CastableFromString[List[Int]] {
    override def fromString(string: String): List[Int] =
      string.split(',').map(parseInt).toList
  }

  def castFromString[A](string: String)(implicit cast: CastableFromString[A]): A =
    cast.fromString(string)
}

object Main {
  import CastableFromString._

  def main(args: Array[String]): Unit = {
    val d = castFromString[Double]("4.5")
    val i = castFromString[Int]("42")
    val li = castFromString[List[Int]]("1,2,3")
    println(s"d=$d i=$i li=$li")
  }
}

或者,为了更接近于类似伪代码的东西,您可以使用。下面是一个示例(不适用于任何比Scala2.11更早的版本):

代码语言:javascript
复制
import scala.language.experimental.macros
import scala.reflect.macros.blackbox.Context

class StringCasterImpl(val c: Context) {
  def castFromStringImpl[A: c.WeakTypeTag](string: c.Expr[String]): c.Tree = {
    import c.universe._
    val t = c.weakTypeOf[A]
    if (t =:= typeOf[Double]) {
      q"java.lang.Double.parseDouble($string)"
    } else if (t =:= typeOf[Int]) {
      q"java.lang.Integer.parseInt($string)"
    } else if (t =:= typeOf[List[Int]]) {
      q"$string.split(',').map(java.lang.Integer.parseInt).toList"
    } else {
      c.abort(c.enclosingPosition, s"Don't know how to cast $t to String")
    }
  }
}

object StringCaster {
  def castFromString[A](string: String): A =
    macro StringCasterImpl.castFromStringImpl[A]
}

// note that this object must be in a separate compilation unit
object Main {
  import StringCaster._

  def main(args: Array[String]): Unit = {
    val d = castFromString[Double]("4.2")
    val i = castFromString[Int]("42")
    val li = castFromString[List[Int]]("1,2,3")
    println(s"d=$d i=$i li=$li")
  }
}
票数 3
EN

Stack Overflow用户

发布于 2015-06-03 19:46:17

可以定义将字符串转换为特定类型的隐式函数。

然后,当需要时,它将自动铸造。

代码语言:javascript
复制
math.max(1,"3") // throws error

但现在

代码语言:javascript
复制
implicit def StringToInt(x: String): Int = x

math.max(1,"3")  //>> 3
票数 0
EN

Stack Overflow用户

发布于 2015-06-04 13:46:26

如果您想要这样做,可以在runtimeClass中匹配ClassTag

代码语言:javascript
复制
def castFromString[A: ClassTag](value: String): A = {
  val c = implicitly[ClassTag[A]].runtimeClass
  if(c == classOf[Double]) parseDouble(value).asInstanceOf[A]
  else ...
}

注意对asInstanceOf强制转换的需要。@Olli建议的典型方法更安全、更地道。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30627573

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档