[英]Inferring String value type in Groovy
我有一种情况,我会得到一个字符串,我需要确定什么Class<?>
最适合其值,给出以下约束:
"true"
或"false"
,则它是一个Boolean
Integer
,那么它就是一个Integer
Double
YYYY-MM-DD hh:mm:ss.sss
,那么它是一个Java Date
String
毕竟 我最好的尝试是讨厌的,涉及很多嵌套的try/catch
块:
// Groovy pseudo-code
Class<?> determineValueType(String value) {
Class<?> clazz
if(value.equalsIgnoreCase('true') || value.equalsIgnoreCase('false')) {
clazz = Boolean
} else {
try {
Integer.parse(value)
clazz = Integer
} catch(Exception ex1) {
try {
Double.parse(value)
clazz = Double
} catch(Exception ex2) {
try {
Date.parse('YYYY-MM-DD hh:mm:ss.sss', value)
clazz = Date
} catch(Exception ex3) {
clazz = String
}
}
}
}
clazz
}
是否有任何Groovier方法来实现这一点,也许某些模糊的Groovy反射API特有的东西?
在Groovy的扩展String类中有两种方法可以帮助你(实际上在CharSequence
):
但对于其他情况,AFAIK,您可以自己实现解析。 您可以尝试使用地图和一些闭包,以减少一些样板:
Class parse(val) {
def convert = [
(Integer) : { it.toInteger() },
(Double) : { it.toDouble() },
(Date) : { Date.parse('YYYY-MM-DD hh:mm:ss.sss', it) },
(Boolean) : { Boolean.parseBoolean it },
(String) : { it }
]
convert.findResult { key, value ->
try {
if (value(val)) return key
} catch (e) {}
}
}
assert parse('9.1') == Double
assert parse('9') == Integer
assert parse('1985-10-26 01:22:00.000') == Date // great scott!
assert parse('chicken') == String
assert parse('True') == Boolean
请注意,如果(Double)
在(Integer)
(Double)
之前,则测试将不起作用,因为9
既是double又是整数。
Groovy有一些功能可以让你使这个逻辑更加流畅。
isInteger
和isDouble
内置CharSequence方法。 可悲的是,没有严格的isBoolean
所以我们需要自己实现。 结合这些功能......
Class<?> determineValueType(String value) {
switch (value) {
case { ['true', 'false'].contains(value?.toLowerCase()) }:
return Boolean
case { value?.isInteger() }:
return Integer
case { value?.isDouble() }:
return Double
case ~/^\d{4}-\d{2}-\d{2} \d{1,2}:\d{2}:\d{2}\.\d{3}$/:
return Date
default:
return String
}
}
assert determineValueType('true') == Boolean
assert determineValueType('false') == Boolean
assert determineValueType('2039230') == Integer
assert determineValueType('203923.0') == Double
assert determineValueType('2016-07-26 12:00:00.000') == Date
assert determineValueType('foo') == String
我使用正则表达式而不是SimpleDateFormat来避免必须捕获异常。 它可能具有稍微不同的语义,但您可以创建一个辅助方法,如果Date.parse
抛出异常,则返回false。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.