我想对scala变量进行动态转换,转换类型存储在其他变量或数据库中,或者由用户提供。
我是Scala的新手,主要在python上进行编码。在这里,我们尝试采用Any type输入,并根据数据库中保存的类型查询变量的类型,例如:“ String / Int”和用户定义的类,并在将来进行任何处理之前将其强制转换。
在python中:
eval("str('123')")
在我尝试过的Scala中
var a = 123.05
a.asInstanceOf['Int']
给我错误
错误:应该有标识符,但是找到了字符串文字。
我希望代码如下:
var a = 123.05
var b = "Int"
a.asInstanceOf[b]
给我错误
错误:未找到:键入b
答案 0 :(得分:2)
好吧,在这里我必须要详尽无遗,因为由于scala和python在静态和动态类型上的差异,您要尝试做的事情很棘手。
首先,您在Python中所做的不是 类型转换,而是转换。
str(12)
python中的取整数值12并将其转换为(UTF-8?python中的dunno)字符串。 Scala中的同一件事是
12.toString
同时,类型转换基本上是对编译器typechecker的一个粉红色承诺,即您知道的更多,它应该相信您。还应避免这种情况,例如害虫,因为您基本上会放弃静态类型检查为您提供的所有安全性。但是在某些情况下这是不可避免的
更基本的术语。假设您有以下Scala代码段
sealed trait Foo
final case class Bar(i:Int) extends Foo
final case class Baz(s:String) extends Foo
val f:Foo = Bar(2)
//won't work because the compiler thinks f is of type Foo due to the type ascription bove
println(f.i)
//will work
println(f.asInstanceOf[Bar].i)
Foo类型可以是Bar或Baz(由于是密封的和最终的,因此称为ADT),但是我们专门告诉编译器将f视为Foo,这意味着我们忘记了特定于 输入是。在这种情况下,您可以使用类型转换,请注意,我们不进行转换,而是告诉编译器它实际上是Bar
现在,这一切都发生在编译时,这意味着您无法根据这样的运行时值进行转换
var a = 123.05
var b = "Int"
a.asInstanceOf[b]
现在,据我了解,您有某种类型的字符串输入,需要根据某种模式进行转换。下面的scalafiddle举了一个如何执行此操作的示例:https://scalafiddle.io/sf/i97WZlA/0
但是请注意,这在scala中利用了一些相当高级的概念来确保类型对齐。
这也将https://scalafiddle.io/sf/i97WZlA/1起作用,但是请注意,如果我们想对out
做任何有意义的事情,我们将丢失所有需要进行类型转换的类型信息
EDIT / ADDENDUM:我想我也应该做一个例子,说明如何使用这些值并使模式动态化。
https://scalafiddle.io/sf/i97WZlA/2
作为最后一条警告,请注意,这已经接近编译器可以执行的限制,并且需要进行大量装箱和拆箱以携带类型信息(在SchemaValue
中),而且它不是堆栈安全的,并且具有错误的错误处理。该解决方案需要进行认真的工程设计才能使其可行,但它应该可以使想法得以传播
答案 1 :(得分:0)
如果您有一个1 dup ...
值,则可以使用String
或toInt
来解析该字符串:
toDouble
如果您有一个val s = "123.05"
val i = s.toInt
val d = s.toDouble
值,那么最好使用Any
进行转换:
match
如果其他所有方法都失败,则可以显式选择一个类型,但这不是一个好习惯:
val a: Any = ...
a match {
case i: Int => // It is an Int
case d: Double => // It is a Double
case _ => // It is a different type
}
任何体面的数据库框架都将使您能够读写特定类型的值,因此正确的库应该不是问题。