DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: cuiqingbo
今日帖子: 20
在线用户: 11
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 mp654kk (mp654kk) ▲△△△△ -
普通会员
2023/2/18 15:08:30
标题:
求助tarry<string>,array of string,tstringlist,tlist<string>四者如何互相转换 浏览:1834
加入我的收藏
楼主: var 
a:tarry<string>;
b:array of string;
c:tstringlist;
d:tlist<string>;
四者如何互相转换,最好用现成的方法或函数,谢谢.
----------------------------------------------
-
作者:
男 supermay (supermay) ★☆☆☆☆ -
盒子活跃会员
2023/2/18 15:30:27
1楼: TStringList.ToStringArray
TArray<string>与array of string是等价的,可以用copy
----------------------------------------------
链接:https://pan.baidu.com/s/12jzmECYKhGCsHBxz8tmB6w 提取码:pelr --来自百度网盘超级会员V9的分享
作者:
男 roadrunner (roadrunner) ★☆☆☆☆ -
盒子活跃会员
2023/2/18 15:54:21
2楼: tarray<string>和array of string完全一样,两个类型的变量可以直接互相赋值也可以直接写在参数里
tstringlist与tarray<string>的相互转换
c := tstringlist.create; c.addstrings(a); //copy a to c
a := c.tostringarray; //copy c to a

tlist<string>与Tarray<string>的相互转换
d := TList<string>.Create(a); //copy a to d
a := d.ToArray; //copy d to a

tlist<string>与TStringList的相互转换
d := TList<string>.Create(c); //copy c to d
c := TStringList.Create; c.AddStrings(d.ToArray); //copy d to c
----------------------------------------------
-
作者:
男 mp654kk (mp654kk) ▲△△△△ -
普通会员
2023/2/18 18:10:24
3楼: @supermay 谢谢,可否写一下copy的代码,我写出来报错呀,是在FMX里哦.
----------------------------------------------
-
作者:
男 mp654kk (mp654kk) ▲△△△△ -
普通会员
2023/2/18 18:12:54
4楼: @roadrunner 谢谢
tarray<string>和array of string完全一样,两个类型的变量可以直接互相赋值也可以直接写在参数里-----可否写一下,我的始终报错,是在FMX里哦.
----------------------------------------------
-
作者:
男 z_y_b_delphi (z_y_b_delphi) ★☆☆☆☆ -
普通会员
2023/2/18 21:34:41
5楼: tarray<string>和array of string用法一样,但不能copy,也不能直接互相赋值,参数也不能相互替代。
var
  TS:TArray<string>;
  Arr:array of string;
begin
 for var i := 0 to 99 do
      TS:=TS+[i.ToString];
  SetLength(Arr,100);
  Move(TS[0],Arr[0],Length(TS)*4);
  for var i := 0 to 99 do
    Memo1.Lines.Add(Arr[i]);
end;
----------------------------------------------
-
作者:
男 hs_kill (lzl_17948876) ★☆☆☆☆ -
普通会员
2023/2/18 21:42:51
5楼: tarray<string>和array of string的数据内存结构是一样的, 但是类型不一样
能否互相直接赋值要看delphi版本
我记得好像是从11开始支持直接赋值的 10的版本不行(也许是XE系列不行 10开始可以的 忘了)

还有另外一个类型TStringDynArray 和tarray<string>才是同一个类型
----------------------------------------------
http://www.cnblogs.com/lzl_17948876/
作者:
男 mp654kk (mp654kk) ▲△△△△ -
普通会员
2023/2/18 22:17:34
6楼: @z_y_b_delphi 谢谢 可是可以就是麻烦了点
@hs_kill 谢谢 我是11.2,直接a:=b或b:=a都报错呢
----------------------------------------------
-
作者:
男 hs_kill (lzl_17948876) ★☆☆☆☆ -
普通会员
2023/2/19 0:11:00
7楼: 刚试了一下, 确实不能直接赋值, 感觉像是编译器没有做完整

对于函数参数来说
var
  a: TArray<string>;
  b: array of string;

如果定义成array of string 是可以同时接受array of string和TArray<string>类型传入的:
procedure xx1(const s: array of string);

xx1(a) //正常
xx1(b) //正常

如果定义成TArray<string> 只能接受TArray<string>类型传入
procedure xx2(const s: TArray<string>);

xx2(a) //正常
xx2(b) //错误

但是对于变量 这2个类型无法互相赋值(直接move不算)
a := b //错误
b := a //错误

特别的是: 如果定义了2个变量 分别是array of string 也不能互相赋值
var
  b: array of string;
  c: array of string;

b := c //错误
c := b //错误

但是定义2个TArray<string> 是可以互相赋值的
var
  a1: TArray<string>;
  a2: TArray<string>;

a1 := a2 //正确

原因不明, 估计是编译器的处理问题吧
----------------------------------------------
http://www.cnblogs.com/lzl_17948876/
作者:
男 z_y_b_delphi (z_y_b_delphi) ★☆☆☆☆ -
普通会员
2023/2/19 7:52:31
8楼: Move在知道String数组长度的时候可用,string数组是不定长的,因此用起来也不方便。
用泛型copy是比较好的解决方案:
uses System.Generics.Collections;
var
  TS:TArray<string>;
  Arr:array of string;
begin
  for var i := 0 to 99 do
      TS:=TS+[i.ToString];
  SetLength(Arr,100);
  TArray.Copy<String>(TS,Arr,100);
end;
----------------------------------------------
-
作者:
男 mp654kk (mp654kk) ▲△△△△ -
普通会员
2023/2/20 13:41:06
9楼: @hs_kill 谢谢 我是11.2试了一下 
函数形参是array of string的时候传入array of string或者tarray<string>都可以 
函数形参是tarray<string>的时候传入array of string不行 
如果定义了2个变量 分别是array of string 如果都在函数内部定义是可以互相赋值的 如果一个是形参一个是实参就会提示'不兼容的类型,Dynmic array和array of string'

@z_y_b_delphi 谢谢 TS:=TS+[i.ToString]; 没想到还有这种添加元素的用法,神奇,TS这里是当指针用吗,岂不是list<string>都可以不用了.
----------------------------------------------
-
作者:
男 z_y_b_delphi (z_y_b_delphi) ★☆☆☆☆ -
普通会员
2023/2/20 14:31:27
10楼: 提醒一下,动态数组赋值是引用!
比如:
  Arr1,Arr2:TArray<string>;
  Arr1:=Arr2;
那么Arr1的元素发生改变,Arr2也随之一起变化,就像这样:
  Arr1[0]:='Test';
  Arr2[0]也随之变为'Test'。
如果想让Arr1与Arr2不相关联,只能用TArray.Copy。
----------------------------------------------
-
作者:
男 mp654kk (mp654kk) ▲△△△△ -
普通会员
2023/2/20 23:48:21
11楼: @z_y_b_delphi 这个确实 Copy相当于c#里面的clone
----------------------------------------------
-
作者:
男 hs_kill (lzl_17948876) ★☆☆☆☆ -
普通会员
2023/2/21 9:33:46
12楼: TS:=TS+[i.ToString] 这种写法尽量不要在循环内使用, 因为每一次+都是重新分配内存+copy
----------------------------------------------
http://www.cnblogs.com/lzl_17948876/
作者:
男 mp654kk (mp654kk) ▲△△△△ -
普通会员
2023/2/22 13:00:10
13楼: @hs_kill  如果用Tlist<String>的Add不也要重新分配内存和复制吗 效率不一样么
----------------------------------------------
-
作者:
男 pcplayer (pcplayer) ★☆☆☆☆ -
普通会员
2023/2/22 16:52:19
14楼: Delphi 里面的 string 对它的引用是引用的指针。比如:

A := 'abcd';  这里的 A 是指针;

B := A;  这里仅仅是把 A 的指针给了 B,原来的那个字符串只是多了一个引用。没有另外分配空间,复制字符串。

但是,如果是:

A := 'abcd';
B := A;
A := '1234';  《--- 到这里,因为 A 的内容被改了,但 B 仍然是以前的内容 abcd,因此,这里新分配了空间。分配空间比较消耗 CPU。


关于分配空间比较消耗 CPU 这个事情,不管是 Delphi 还是 C,都有一个技巧,就是预先分配一个比较大的空间。比如以下代码:

procedure TForm1.Button1Click(Sender: TObject);
var
  i: Integer;
begin
  List.Capacity := 100; //如果没有这行代码,那么,每次 add 可能都要重新分配空间。这行代码就预先分配足够空间。
  List := TStringList.Create;
  for i := 0 to 99 do
  begin
    List.Add(i.ToString);
  end;
end;


再说 TArray<string>,看看 Delphi 自己的代码:
function TStrings.ToStringArray: TArray<string>;
var
  I: Integer;
begin
  SetLength(Result, Count);
  for I := 0 to Count - 1 do
    Result[I] := Strings[I];
end;

上面那个代码,第一行,SetLength 就是预先分配空间。当然,这里分配的空间其实不是字符串的空间,而是字符串指针。

接下来的 Result[i] := Strings[i] 其实就是把里面的每一条字符串的指针复制过去。因为没有复制字符串,而是仅仅复制指针,效率还是很高的。
----------------------------------------------
-
作者:
男 hs_kill (lzl_17948876) ★☆☆☆☆ -
普通会员
2023/2/23 9:10:15
15楼: 拼接字符串, 重新分配内存和复制是无法避免
但是尽量减少次数
如果再循环内部用 A := A + B这种写法 相当于每次循环都要重新分配内存+复制, 因为这样写是增加数组长度, 成增加数组长度会触发重新申请内存

如果是list<string>, 相当于每次add都是添加了一个指针引用(string本质是个指针)
最后输出的时候再根据长度一次性申请内存做复制

所以简单点的理解,使用list循环添加只会触发一次内存分配, 而A := A+B会触发N次

  for var i := 0 to 99 do
      TS:=TS+[i.ToString];
  SetLength(Arr,100);

对于这段代码, 如果不想用list, 可以这样写
  setlength(TS, 100)
  for var i := 0 to 99 do
      TS[i]:= i.ToString;
这样只有最开始分配了一次内存, 后面都是指针引用
----------------------------------------------
http://www.cnblogs.com/lzl_17948876/
作者:
男 mp654kk (mp654kk) ▲△△△△ -
普通会员
2023/2/23 15:50:15
16楼: @pcplayer 如果设置List.Capacity := 90;添加100个还是可以添加进去呢.超额的10个又会重新分配是吗
@hs_kill 好的
----------------------------------------------
-
作者:
男 wuxiangyang (wxy) ★☆☆☆☆ -
盒子活跃会员
2023/2/23 16:04:16
17楼:
----------------------------------------------
-
作者:
男 pcplayer (pcplayer) ★☆☆☆☆ -
普通会员
2023/2/23 22:49:09
18楼: 16楼:是的,超过 100 个又会重新分配。

这里的策略是:
1. 一次分配一个大的内存空间,但也不要太大免得用不着还要占用内存。够大但不太大,这个得看你自己的程序具体面临的情况而定。假设 100 是一个合理的数字,那么,

2. 至少避免了在循环中,连续100次分配内存空间,而是只分配一次。

3. 如果超过 100,那你再次重新分配,给它 200,而不是 101,这样,就把 200 次 add 需要分配 200 次内存的操作,变成了只分配 2 次。

假设你知道你的具体应用环境是 1000 才够用,那你就不要分配 100,而是直接分配 1000 了。这样的策略,是多数软件都会采用的。这样会降低 CPU 消耗。
----------------------------------------------
-
作者:
男 mp654kk (mp654kk) ▲△△△△ -
普通会员
2023/7/13 14:09:41
19楼: @roadrunner 2楼的d := TList<string>.Create(c);会报错呢
----------------------------------------------
-
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2023/7/14 6:03:55
20楼: implementation

{$R *.dfm}

uses
  System.Generics.Collections;

type
  TdinArrStr1 = TArray<string>;
  TdinArrStr2 = array of string;

procedure TForm1.Button1Click(Sender: TObject);
var
  sTA: TdinArrStr1;
  sAS: TdinArrStr2;
  sTS: TStringList;
  sLS: TList<string>;
begin
  sTA        := ['a', 'b', 'c'];
  Memo1.Text := 'TArray<string>:';
  Memo1.Lines.AddStrings(sTA);
  //
  sAS := TdinArrStr2(sTA);
  Memo1.Lines.Add('array of string:');
  Memo1.Lines.AddStrings(sAS);
  //
  sTS := TStringList.Create;
  try
    sTS.AddStrings(sAS);
    sTS.AddStrings(sTA);
    Memo1.Lines.Add('TStringList: TArray<string>  + Array of String');
    Memo1.Lines.AddStrings(sTS);
    //
    sLS := TList<string>.Create;
    try
      sLS.AddRange(sTS.ToStringArray);
      Memo1.Lines.Add('TList<string>: TStringList');
      Memo1.Lines.AddStrings(sLS.ToArray);
    finally
      sLS.Free;
    end;
  finally
    sTS.Free;
  end;
end;

initialization

ReportMemoryLeaksOnShutdown := true;

end.
此帖子包含附件:
PNG 图像
大小:5.8K
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2023/7/14 6:08:29
21楼: "TArray<string>"  It's not compatible with "Array of String"

--->  sTA := sAS  --> does not works
--->  sAS := sTA  --> does not works

why:  Because the "Delphi" use:

1) first: the "type's name" to compatibility;
2) later, the "data's type" !!!

then...

1) we needs a "CAST" between objects/vars

type
  TdinArrStr1 = TArray<string>;
  TdinArrStr2 = array of string;
  ....

  sAS := TdinArrStr2(sTA);
  //
  sTA := TdinArrStr1(sAS);
  //
  sLS.AddRange(sTA);
  sLS.AddRange(sAS);
  sLS.AddRange(sTS.ToStringArray);
  //
  sTS.AddStrings(sTA);
  sTS.AddStrings(sAS);
  sTS.AddStrings(sLS.ToArray);
  //
  sTA := sLS.ToArray;
  sTA := sTS.ToStringArray;
  sAS := TdinArrStr2(sLS.ToArray);
  sAS := TdinArrStr2(sTS.ToStringArray);


NOTE: NO NEED ANY WORKAROUND TO RE-ALLOCATION OF MEMORY, like Setlenght() function
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 mp654kk (mp654kk) ▲△△△△ -
普通会员
2023/7/14 19:45:00
22楼: @emailx45  谢谢 看来只能用AddStrings的方法来实现了,不能直接转换
----------------------------------------------
-
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2023/7/14 23:08:40
23楼: you can many others methods to get it, for example

1)  a "string" has many helper functions like "SPLIT" and "JOIN"
2) all "STRINGLIST" has a "TEXT" property ( TStringList, TList, etc...)

ex.:

  var xxx : string; ....
  var  zzz: TArray<string>;

  xxx := TS.TEXT;
  zzz :=  xxx.SPLIT( .... )
  xxx := ''.JOIN(....);
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 mp654kk (mp654kk) ▲△△△△ -
普通会员
2023/7/14 23:27:09
24楼: @emailx45 是的 谢谢 方法基本上都说完了
----------------------------------------------
-
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行93.75毫秒 RSS