2017-05-02 23 views
2

私はDBから回答を得ており、それが値にする前にnullでないかどうかを確認する必要があります。 nullのVariantをチェックする方法は?

私はチェックのいくつかのバリエーションを試してみましたが、私のコードはまだ鎮圧さ:

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 

[email protected]:\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; 

同じ結果に。私が間違っていることは何ですか?

答えて

1

hasValueが初期化されていて、データベースライブラリがそれを初期化するかどうか、つまりnullになるかどうかをチェックします。

私は直接の種類を確認することをお勧めしたい:

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

peekチェックをそれは正確な型を持っており、それがない場合は、値へのポインタを返す場合。 正確なと一致しています。つまり、floatなどの場合は動作しません。したがって、データベースが提供するものと一致していることを確認してください(ただし、パフォーマンスと正確性には最適です)。したがって、ifをスキップして、正しくない場合は設定することができます。

すべてのポイントについてそのパターンを繰り返してください。

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

結果:あなたの代わりにtypeid(typeof(null))をチェックする必要があり、あなたのコード内ので

false true false 
true false false 
true true true 

ここ

+0

ちょっとハッキーな感じです。どのようにこの問題が別の言語で解決さ​​れていますか?たぶん私はバグトラッカーでそれについて言及すべきでしょうか? –

+0

実際のデータを実際の期待と照らし合わせてチェックすることについて「ハッキー」とは何ですか? –

+0

私は '.isNull'や他の方法のようなものを期待しています。あるいは最後に '.hasValue'は' null'でfalseを返します。それはC#のような方法で行われているようです。私が間違っているなら、私を訂正してください。 –

1

は、あなたが望む方法でisNull機能とhasValue2機能を実現するソリューションです。 hasValuetypeof(null)もチェックしてくださいIIRC Variantより前のtypeof(null)では、typeof(null)のみを使用し、未初期化は許可しないこともあります。Variants

https://forum.dlang.org/group/generalでディスカッションを開始するか、https://issues.dlang.orgでバグレポートを提出して、適切なライブラリのメンテナーに相談してください。

関連する問題