2017-05-02 5 views
2

Ich bekomme Antwort von DB und muss prüfen, ob es nicht null ist, bevor es auf Wert gesetzt wird.Wie man Variante für Null prüft?

Ich habe versucht, einige Varianten der Überprüfung, aber mein Code zerquetschen noch:

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); 
    } 
} 

Ausgang:

----------------------------ERRRRRR----------------------- 
Row([1478698195002489886, 2016-Nov-09 13:29:55, 153, null, null], [false, false, false, true, true]) 
1111: 153 

[email protected]:\D\dmd2\windows\bin\..\..\src\phobos\std\variant.d(823): Type typeof(null) does not convert to double 

Wie Sie es drucken 1111: 153 sehen. Aber Absturz auf andere Null-Variablen.

ich auch versucht:

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; 

gleiches Ergebnis. Was mache ich falsch?

Antwort

1

hasValue überprüft, ob es initialisiert wurde und die Datenbankbibliothek es initialisiert, nur um null zu setzen.

würde ich vorschlagen, die Art Überprüfung direkt:

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

peek überprüft, ob es hat, dass genaue Art und einen Zeiger auf den Wert zurückgibt, wenn es funktioniert. Es ist ein genau übereinstimmen, was bedeutet, wenn es float oder etwas anderes ist, wird dies nicht funktionieren, so stellen Sie sicher, dass Sie übereinstimmen, was die Datenbank Ihnen gibt (das ist für Leistung und Genauigkeit sowieso am besten), aber dann wird es null sein und so überspringen Sie die if es ist nicht richtig, und Sie können einstellen, wenn es ist.

Wiederholen Sie einfach dieses Muster für alle Ihre Punkte.

+0

Es sieht aus wie ein bisschen hacky. Wie löst dieses Problem in anderen Sprachen? Vielleicht sollte ich das im Bug-Tracker erwähnen? –

+0

Was ist "hacky" über die Überprüfung der tatsächlichen Daten im Vergleich zu Ihren tatsächlichen Erwartungen? –

+0

Ich erwarte etwas wie '.isNull' oder andere Methoden. Oder zumindest, dass '.hasValue 'false auf' null 'zurückgibt. Es scheint, dass es in C# so gemacht wird. Korrigiere mich, wenn ich falsch liege. –

1

Hier ist eine Lösung, die die isNull Funktion und eine hasValue2 Funktion in der Art und Weise implementieren Sie wollten:

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; 
} 

Ergebnis:

false true false 
true false false 
true true true 

Also in Ihrem Code sollten Sie für typeid(typeof(null)) überprüfen statt. Sie könnten Recht haben, dass hasValue auch nach typeof(null) überprüfen sollte. IIRC Variant älter als typeof(null), heutzutage könnte es sogar sinnvoll sein, nur typeof(null) zu verwenden und niemals uninitialisierte Variants zuzulassen.

Bitte starten Sie eine Diskussion unter https://forum.dlang.org/group/general oder reichen Sie einen Fehlerbericht unter https://issues.dlang.org ein, um dies mit den entsprechenden Bibliotheksbetreuern zu besprechen.