我收到了来自数据库的答案,需要先检查它是否null
,然后再将其设置为值。
我尝试了几种检查方式,但我的代码仍然是粉碎的:
foreach(i, point;myPointsLonLat)
{
try
{
carGPSPoint cargpspoint;
cargpspoint.id = point[0].coerce!ulong;
cargpspoint.recordDate = DateTime.fromSimpleString(point[1].coerce!string).toISOExtString(); // some magic to get string in 2016-10-31T15:37:24 format
if(point[2].hasValue) //check if we have some data
cargpspoint.velocity = point[2].coerce!double;
if(point[3].hasValue)
cargpspoint.lat = point[3].coerce!double;
if(point[4].hasValue)
cargpspoint.lon = point[4].coerce!double;
cargpspoints[i] = cargpspoint;
b.next();
}
catch(Exception e)
{
writeln("\n----------------------------ERRRRRR-----------------------");
writeln(point);
writeln("1111: ", point[2].coerce!double);
writeln("2222: ", point[3].coerce!double);
writeln("3333: ", point[4].coerce!double);
writeln(e.msg);
}
}
输出:
----------------------------ERRRRRR-----------------------
Row([1478698195002489886, 2016-Nov-09 13:29:55, 153, null, null], [false, false, false, true, true])
1111: 153
object.Exception@C:\D\dmd2\windows\bin\..\..\src\phobos\std\variant.d(823): Type typeof(null) does not convert to double
如您所见,打印1111: 153
。但是崩溃了其他的空变量。
我也尝试过:
if(point[2].type !is null) //check if we have some data
cargpspoint.velocity = point[2].coerce!double;
if(point[3].type !is null)
cargpspoint.lat = point[3].coerce!double;
if(point[4].type !is null)
cargpspoint.lon = point[4].coerce!double;
结果相同。我做错了什么?
答案 0 :(得分:1)
hasValue
检查它是否已初始化,并且数据库库确实初始化它,只是为空。
我建议直接检查类型:
if(auto pt = point[3].peek!double)
cargpspoint.lat = *pt;
peek
检查它是否具有该确切类型,并返回指向该值的指针。这是一个完全匹配,意味着如果它是float
或其他内容,这将无法正常工作,因此请确保您匹配数据库为您提供的内容('最好是性能和准确性,但是它会为空,因此跳过if
它不对,你可以设置它是否正确。
只需重复所有要点的模式。
答案 1 :(得分:1)
以下是以您希望的方式实现+-------+----------+-------------+-------+
| group | sequence | action | count |
+-------+----------+-------------+-------+
| 1 | 1 | promotion_1 | 1 |
| 1 | 2 | promotion_1 | 2 |
| 1 | 3 | promotion_2 | 3 |
| 1 | 4 | act1 | 3 |
| 1 | 5 | act1 | 3 |
| 1 | 6 | act2 | 3 |
| 1 | 7 | promotion_1 | 4 |
| 1 | 8 | act1 | 4 |
| 1 | 9 | act2 | 4 |
| 1 | 10 | promotion_1 | 5 |
| 1 | 11 | act1 | 5 |
| 2 | 1 | promotion_2 | 1 |
| 2 | 2 | act1 | 1 |
+-------+----------+-------------+-------+
函数和isNull
函数的解决方案:
hasValue2
结果:
import std.variant;
import std.stdio;
void main()
{
Variant v;
writefln("%s %s %s", v.hasValue, !v.isNull, v.hasValue2);
v = null;
writefln("%s %s %s", v.hasValue, !v.isNull, v.hasValue2);
v = "";
writefln("%s %s %s", v.hasValue, !v.isNull, v.hasValue2);
}
@property bool isNull(Variant v)
{
return v.type == typeid(typeof(null));
}
@property bool hasValue2(Variant v)
{
return v.hasValue && !v.isNull;
}
因此,在您的代码中,您应该检查false true false
true false false
true true true
。你可能也应该typeid(typeof(null))
检查hasValue
。 IIRC typeof(null)
早于Variant
,现在甚至可能只使用typeof(null)
并且永远不允许未初始化typeof(null)
。
请在https://forum.dlang.org/group/general开始讨论,或在https://issues.dlang.org提交错误报告,与相应的图书馆维护人员讨论。