我有一个Scala类,它读取JOSN模板文件中的格式信息,以及来自不同文件的数据。目标是格式化为模板文件指定的JSON对象。我正在使布局工作,但现在我想将输出的类型设置为我的模板中的类型(即如果我在模板中有一个字段值作为字符串,它应该是输出中的字符串,甚至如果它是原始数据中的整数)。
基本上,我正在寻找一种快速简便的方法:
output = dataValue.asInstanceOf[templateValue.getClass]
该行给出了一个错误,即类型getClass不是Any的成员。但我还没有找到任何其他成员或方法在运行时给我一个变量类型。这是可能的,如果是的话,怎么样?
澄清
我应该在我的代码中添加,我知道我只处理一个键/值对。我想要的是价值的类型。
具体来说,给定下面的JSON模板,我希望将名称转换为String,将age转换为整数,并将输出的工资转换为输出小数,而不管它在原始数据文件中的显示方式(它可以是所有字符串,年龄和工资都可以是整数,等等。我希望的是一个简单的强制转换,它不需要我进行模式匹配来专门处理每种数据类型。
示例模板:
people: [{
name: "value",
age: 0,
salary: 0.00
}]
答案 0 :(得分:3)
类型参数必须在编译时知道(类型符号),而templateValue.getClass
只是一个普通值(类型为Class
),因此它不能用作类型参数。
该怎么做 - 这取决于你的目标,这对我来说尚不清楚......但它可能看起来像
output = someMethod(dataValue, templateValue.getClass)
,
并且在该方法中,您可以根据类型Class
的第二个参数进行不同的计算。
答案 1 :(得分:3)
如何获取对象的类型并将其传递给Scala中的asInstanceOf?
方法scala.reflect.api.JavaUniverse.typeOf[T]
要求调用者或类型推断对其类型参数进行硬编码。要进行类型推断,请创建如下所示的实用程序方法(适用于所有类型,甚至是泛型 - 它通过在使用类型标记元数据进行编译期间扩充T来抵消java运行时类型arg擦除):
// http://www.scala-lang.org/api/current/index.html#scala.reflect.runtime.package
import scala.reflect.runtime.universe._
def getType[T: TypeTag](a: T): Type = typeOf[T]
这里有3项要求:
TypeTag
(但之前通过Manifest
实现仍然可用...)您可以在不指定T(它是类型推断)的情况下调用:
import scala.reflect.runtime.universe._
def getType[T: TypeTag](a: T): Type = typeOf[T]
val ls = List[Int](1,2,3)
println(getType(ls)) // prints List[Int]
但是,asInstanceOf只会将类型转换为层次结构中的(二进制一致)类型,而不会转换数据或格式。即数据必须已经采用正确的二进制格式 - 这样才能解决您的问题。
数据转换
一些方法在整数和字符串之间进行转换:
// defined in scala.Any:
123.toString // gives "123"
// implicitly defined for java.lang.String via scala.collection.immutable.StringOps:
123.toHexString // gives "7b"
123.toOctalString // gives "173"
"%d".format(123) // also gives "123"
"%5d".format(123) // gives " 123"
"%05d".format(123) // gives "00123"
"%01.2f".format(123.456789) // gives "123.46"
"%01.2f".format(123.456789) // gives "0.46"
// implicitly defined for java.lang.String via scala.collection.immutable.StringOps:
" 123".toInt // gives 123
"00123".toInt // gives 123
"00123.4600".toDouble // gives 123.46
".46".toDouble // gives 0.46
直接从文件解析到目标类型(无投射或转换):
不幸的是,scala没有一种方法来读取流中的下一个标记为整数/浮点数/短/布尔/等。但是你可以通过获取java FileInputStream
,将其包裹在DataInputStream
然后调用readInt
,readFloat
,readShort
,readBoolean
来实现等等
答案 2 :(得分:0)
在类型级别上下文中,值级别的术语仍然具有一些访问器。第一个和您要求的是值本身的类型(type
):
output = dataValue.asInstanceOf[templateValue.type]
如果值的类型具有内部成员,那么它们也可用:
class A {
class B {}
}
val a: A = new A
val b: a.B = new a.B
注意b: a.B
。
我还必须提到如何在没有价值级术语的情况下访问这些成员:
val b: A#B = new a.B