Вопрос

Here is my code :

JSONValue generateJsonValue(Value input)
{
    JSONValue ret;
    switch (input.type)
    {
        case ValueType.numberValue      :   ret.type = JSON_TYPE.UINTEGER; ret.uinteger = input.content.i; return ret;
        case ValueType.realValue        :   ret.type = JSON_TYPE.FLOAT;    ret.floating = input.content.r; return ret;
        case ValueType.stringValue      :   ret.type = JSON_TYPE.STRING;   ret.str = input.content.s; return ret;
        case ValueType.booleanValue     :   ret.type = JSON_TYPE.INTEGER;  ret.integer = to!int(input.content.b); return ret;
        case ValueType.arrayValue       :   {
            ret.type = JSON_TYPE.ARRAY;
            for (int i=0; i<input.content.a.length; i++)
            {
                ret[i] = generateJsonValue(input.content.a[i]);
            }
            return ret;
        }
        case ValueType.dictionaryValue  :   {
            ret.type = JSON_TYPE.OBJECT;
            foreach (Value kv, Value vv; input.content.d)
            {
                ret[kv.str()] = generateJsonValue(vv);
            }
            return ret;
        }
        default : break;
    }

    return ret; // won't reach here
}

The error : The compiler complains of my trying to set the type property.

Error: function std.json.JSONValue.type () const is not callable using argument types (JSON_TYPE)

What am I doing wrong? Isn't it how it is to be used? (I've had a look at the official std.json documentation and in the forums, as well - and still cannot figure this one out)

Это было полезно?

Решение

If you are using DMD2.065+, you change JSONValue directly without setting the type. This change was made to provide a memory safe API. Example:

import std.json, std.stdio;

void main() {
    JSONValue nJ = 5;
    JSONValue sJ = "hello";
    JSONValue bJ = true;
    JSONValue aJ = [1, 2];
    JSONValue oJ1 = ["i": JSONValue(2), "s": JSONValue("str"), "arr": JSONValue([1, 2, 3])]; // different value types
    JSONValue oJ2 = ["a": 1, "b": 2, "c": 3]; // same value type
    writeln(nJ.toString());
    writeln(sJ.toString());
    writeln(bJ.toString());
    writeln(aJ.toString());
    writeln(oJ1.toString());
    writeln(oJ2.toString());
}

Другие советы

I'm not sure if my approach is right (well, it works fine anyway), but after having a good look into std/json.d (the implementation of the module), this is what I ended up with :

JSONValue generateJsonValue(Value input)
{
    JSONValue ret;
    switch (input.type)
    {
        case ValueType.numberValue      :   ret = input.content.i; return ret;
        case ValueType.realValue        :   ret = input.content.r; return ret;
        case ValueType.stringValue      :   ret = input.content.s; return ret;
        case ValueType.booleanValue     :   ret = to!int(input.content.b); return ret;
        case ValueType.arrayValue       :   {
            JSONValue[] result;
            for (int i=0; i<input.content.a.length; i++)
            {
                result ~= generateJsonValue(input.content.a[i]);
            }
            ret = result;
            return ret;
        }
        case ValueType.dictionaryValue  :   {
            JSONValue[string] result;
            foreach (Value kv, Value vv; input.content.d)
            {
                result [kv.str()] = generateJsonValue(vv);
            }
            ret = result;
            return ret;
        }
        default : break;
    }

    return ret; // won't reach here
}

Hint : If you can't directly set the type, nor have access to the private type_tag, make it... guess the type... lol.


P.S. I suppose a ret = input.content.i, etc (where an int value is inferred) would also work fine. (FIXED)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top