如何检查Variant是否为空?

3

我从数据库获取答案并需要检查它是否为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个回答

2

hasValue检查它是否已被初始化,数据库库确实对其进行了初始化,但只是将其初始化为null。

我建议直接检查类型:

 if(auto pt = point[3].peek!double)
                cargpspoint.lat = *pt;

peek检查是否有与其完全匹配的类型,如果有,则返回值的指针。这是一个精确匹配,也就是说,如果它是float或其他类型,则无法正常工作,因此请确保您匹配数据库提供的内容(这样可以获得最佳性能和准确性),否则将返回空值并跳过if语句,您可以设置正确的值。

对于所有要点,请重复该模式。


这看起来有点像是hack的。在其他语言中,这个问题是如何解决的?也许我应该在bug跟踪器中提及它? - Dmitry Bubnenkov
检查实际数据是否符合您的实际期望有什么“hacky”的地方? - Adam D. Ruppe
我期望有像.isNull或其他方法。或者至少.hasValuenull上返回false。似乎在C#中是这样做的。如果我错了,请纠正我。 - Dmitry Bubnenkov

2

这里提供了实现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也应该检查typeof(null)。如果我没记错,Variant早于typeof(null),现在甚至只使用typeof(null)并且永远不允许未初始化的Variants可能是有意义的。
请在https://forum.dlang.org/group/general开始讨论或在https://issues.dlang.org提交错误报告以与适当的库维护人员讨论此问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接