如何检查Variant为null?

时间:2017-05-02 11:50:05

标签: null d variant

我收到了来自数据库的答案,需要先检查它是否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;

结果相同。我做错了什么?

2 个答案:

答案 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提交错误报告,与相应的图书馆维护人员讨论。