Delphi 需要指针变量
Delphi pointer variable required
我正在尝试创建一个全局过程,它可以动态地将 JSON 字段附加到主 JSON 对象。
procedure TJSONAdapter.addField(Key, Field: String);
var
i: Integer;
strArr: TStringList;
j: Integer;
pJSONObj: ^TJSONObject;
begin
strArr:= TStringList.Create;
Split('.', Key, strArr);
pJSONObj:= @STATICJSON;
i:= 0;
repeat
begin
if IsSimpleJsonValue(STATICJSON.GetValue(strArr[i])) then
begin
Exit;
end;
if STATICJSON.GetValue(strArr[i]) is TJSONObject then
begin
pJSONObj:= @(STATICJSON.GetValue(strArr[i]) as TJSONObject); -> error in this line
if i + 1 = strArr.Count then
begin
我将我的值存储在名为 STATICJSON
的 JSON 对象中,直到程序关闭,然后将其保存到文件中。
我正在尝试在 STATICJSON
中的某处添加一个字段。例如;
{
"colors" :
{
"id": "F00",
"color": "red",
"details" : [
{
"name_en": "Red",
},
{
"name_de": "Rot"
}
]
},
{
"id": "0F0",
"color": "green",
"details" : [
{
"name_en": "Green",
},
{
"name_de": "Grün"
}
]
}
}
如果我想在 colors
数组中第一个对象的每个 details
中添加一个 code
字段:
obj.addField('colors.0.details.X', 'code');
我的预期:
{
"colors" :
{
"id": "F00",
"color": "red",
"details" : [
{
"name_en": "Red",
"code": ""
},
{
"name_de": "Rot",
"code": ""
}
]
},
{
"id": "0F0",
"color": "green",
"details" : [
{
"name_en": "Green",
},
{
"name_de": "Grün"
}
]
}
}
所以我尝试使用指针转到第一种颜色的 details
数组和 addField
。
我正在使用:
STATICJSON:= STATICJSON.GetValue(strArr[i]) as TJSONObject;
效果不错,但是STATICJSON
内容改成这样:
"details" : [
{
"name_en": "Red",
"code": ""
},
{
"name_de": "Rot",
"code": ""
}
]
所以我丢失了所有其他 JSON 内容。这就是我要使用指针的原因。但我在这一行收到错误:
pJSONObj:= @(STATICJSON.GetValue(strArr[i]) as TJSONObject);
Variable required
更新:
procedure TJSONAdapter.addField(Key, Field: String);
var
i: Integer;
strArr: TStringList;
j: Integer;
begin
strArr:= TStringList.Create;
Split('.', Key, strArr);
i:= 0;
repeat
begin
if IsSimpleJsonValue(STATICJSON.GetValue(strArr[i])) then
begin
Exit;
end;
if STATICJSON.GetValue(strArr[i]) is TJSONObject then
begin
STATICJSON:= STATICJSON.GetValue(strArr[i]) as TJSONObject;
if i + 1 = strArr.Count then
begin
STATICJSON.AddPair(TJSONPair.Create(Field, ''));
Exit;
end;
end;
if STATICJSON.GetValue(strArr[i]) is TJSONArray then
begin
if strArr[i + 1] = 'X' then
begin
for j := 0 to (STATICJSON.GetValue(strArr[i]) as TJSONArray).Size -1 do
begin
((STATICJSON.GetValue(strArr[i]) as TJSONArray).Get(j) as TJSONObject).AddPair(TJSONPair.Create(Field, ''));
end;
Exit;
end;
STATICJSON:= (STATICJSON.GetValue(strArr[i]) as TJSONArray).Get(StrToInt(strArr[i+1])) as TJSONObject;
i:= i+1;
end;
Inc(i);
end;
until i = strArr.Count;
strArr.Free;
end;
有效,但由于这些行:
STATICJSON:= STATICJSON.GetValue(strArr[i]) as TJSONObject;
STATICJSON:= (STATICJSON.GetValue(strArr[i]) as TJSONArray).Get(StrToInt(strArr[i+1])) as TJSONObject;
主要的JSON内容丢失了,所以不想赋值STATICJSON
,只是想把它的地址赋给一个指针,这样内容就不会丢失了。
Delphi 对象是引用类型。 TJSONObject
已经是一个指针了,所以没必要再用^TJSONObject
.
试试像这样的东西:
var
STATICJSON: TJSONObject = nil;
procedure TJSONAdapter.addField(Key, Field: String);
var
I, J, Index: Integer;
strArr: TStringList;
pJSONVal: TJSONValue;
begin
strArr := TStringList.Create;
try
Split('.', Key, strArr);
if STATICJSON = nil then begin
STATICJSON := TJSONObject.Create;
end;
pJSONVal := STATICJSON;
For I := 0 to strArr.Count-1 then
begin
if TryStrToInt(strArr[I], Index) then
begin
if not (pJSONVal is TJSONArray) then Exit;
pJSONVal := TJSONArray(pJSONVal).Get(Index);
end
else if strArr[I] = '*' then
begin
if I <> (strArr.Count-1) then Exit;
if not (pJSONVal is TJSONArray) then Exit;
with TJSONArray(pJSONVal) do
begin
For J := 0 to Count-1 do
begin
pJSONVal := Get(Index);
if pJSONVal is TJSONObject then
TJSONObject(pJSONVal).AddPair(Field, '');
end;
end;
end
else if pJSONVal is TJSONObject then
begin
pJSONVal := TJSONObject(pJSONVal).Get(strArr[I]);
if pJSONVal = nil then Exit;
end
else Exit;
end;
if pJSONVal is TJSONObject then
TJSONObject(pJSONVal).AddPair(Field, '');
finally
strArr.Free;
end;
end;
obj.addField('colors.0.details.*', 'code');
我正在尝试创建一个全局过程,它可以动态地将 JSON 字段附加到主 JSON 对象。
procedure TJSONAdapter.addField(Key, Field: String);
var
i: Integer;
strArr: TStringList;
j: Integer;
pJSONObj: ^TJSONObject;
begin
strArr:= TStringList.Create;
Split('.', Key, strArr);
pJSONObj:= @STATICJSON;
i:= 0;
repeat
begin
if IsSimpleJsonValue(STATICJSON.GetValue(strArr[i])) then
begin
Exit;
end;
if STATICJSON.GetValue(strArr[i]) is TJSONObject then
begin
pJSONObj:= @(STATICJSON.GetValue(strArr[i]) as TJSONObject); -> error in this line
if i + 1 = strArr.Count then
begin
我将我的值存储在名为 STATICJSON
的 JSON 对象中,直到程序关闭,然后将其保存到文件中。
我正在尝试在 STATICJSON
中的某处添加一个字段。例如;
{
"colors" :
{
"id": "F00",
"color": "red",
"details" : [
{
"name_en": "Red",
},
{
"name_de": "Rot"
}
]
},
{
"id": "0F0",
"color": "green",
"details" : [
{
"name_en": "Green",
},
{
"name_de": "Grün"
}
]
}
}
如果我想在 colors
数组中第一个对象的每个 details
中添加一个 code
字段:
obj.addField('colors.0.details.X', 'code');
我的预期:
{
"colors" :
{
"id": "F00",
"color": "red",
"details" : [
{
"name_en": "Red",
"code": ""
},
{
"name_de": "Rot",
"code": ""
}
]
},
{
"id": "0F0",
"color": "green",
"details" : [
{
"name_en": "Green",
},
{
"name_de": "Grün"
}
]
}
}
所以我尝试使用指针转到第一种颜色的 details
数组和 addField
。
我正在使用:
STATICJSON:= STATICJSON.GetValue(strArr[i]) as TJSONObject;
效果不错,但是STATICJSON
内容改成这样:
"details" : [
{
"name_en": "Red",
"code": ""
},
{
"name_de": "Rot",
"code": ""
}
]
所以我丢失了所有其他 JSON 内容。这就是我要使用指针的原因。但我在这一行收到错误:
pJSONObj:= @(STATICJSON.GetValue(strArr[i]) as TJSONObject);
Variable required
更新:
procedure TJSONAdapter.addField(Key, Field: String);
var
i: Integer;
strArr: TStringList;
j: Integer;
begin
strArr:= TStringList.Create;
Split('.', Key, strArr);
i:= 0;
repeat
begin
if IsSimpleJsonValue(STATICJSON.GetValue(strArr[i])) then
begin
Exit;
end;
if STATICJSON.GetValue(strArr[i]) is TJSONObject then
begin
STATICJSON:= STATICJSON.GetValue(strArr[i]) as TJSONObject;
if i + 1 = strArr.Count then
begin
STATICJSON.AddPair(TJSONPair.Create(Field, ''));
Exit;
end;
end;
if STATICJSON.GetValue(strArr[i]) is TJSONArray then
begin
if strArr[i + 1] = 'X' then
begin
for j := 0 to (STATICJSON.GetValue(strArr[i]) as TJSONArray).Size -1 do
begin
((STATICJSON.GetValue(strArr[i]) as TJSONArray).Get(j) as TJSONObject).AddPair(TJSONPair.Create(Field, ''));
end;
Exit;
end;
STATICJSON:= (STATICJSON.GetValue(strArr[i]) as TJSONArray).Get(StrToInt(strArr[i+1])) as TJSONObject;
i:= i+1;
end;
Inc(i);
end;
until i = strArr.Count;
strArr.Free;
end;
有效,但由于这些行:
STATICJSON:= STATICJSON.GetValue(strArr[i]) as TJSONObject;
STATICJSON:= (STATICJSON.GetValue(strArr[i]) as TJSONArray).Get(StrToInt(strArr[i+1])) as TJSONObject;
主要的JSON内容丢失了,所以不想赋值STATICJSON
,只是想把它的地址赋给一个指针,这样内容就不会丢失了。
Delphi 对象是引用类型。 TJSONObject
已经是一个指针了,所以没必要再用^TJSONObject
.
试试像这样的东西:
var
STATICJSON: TJSONObject = nil;
procedure TJSONAdapter.addField(Key, Field: String);
var
I, J, Index: Integer;
strArr: TStringList;
pJSONVal: TJSONValue;
begin
strArr := TStringList.Create;
try
Split('.', Key, strArr);
if STATICJSON = nil then begin
STATICJSON := TJSONObject.Create;
end;
pJSONVal := STATICJSON;
For I := 0 to strArr.Count-1 then
begin
if TryStrToInt(strArr[I], Index) then
begin
if not (pJSONVal is TJSONArray) then Exit;
pJSONVal := TJSONArray(pJSONVal).Get(Index);
end
else if strArr[I] = '*' then
begin
if I <> (strArr.Count-1) then Exit;
if not (pJSONVal is TJSONArray) then Exit;
with TJSONArray(pJSONVal) do
begin
For J := 0 to Count-1 do
begin
pJSONVal := Get(Index);
if pJSONVal is TJSONObject then
TJSONObject(pJSONVal).AddPair(Field, '');
end;
end;
end
else if pJSONVal is TJSONObject then
begin
pJSONVal := TJSONObject(pJSONVal).Get(strArr[I]);
if pJSONVal = nil then Exit;
end
else Exit;
end;
if pJSONVal is TJSONObject then
TJSONObject(pJSONVal).AddPair(Field, '');
finally
strArr.Free;
end;
end;
obj.addField('colors.0.details.*', 'code');