【问题标题】:Assign a TArray to a array of T将 TArray 分配给 T 的数组
【发布时间】:2017-01-04 12:43:07
【问题描述】:

如何将TArray<Byte> 分配给array of Byte,反之亦然?

TEncoding.UTF8.GetBytes 返回一个TArray<Byte>TIdHashMessageDigest5.HashBytes 有一个 TIdBytes = array of Byte 作为参数。

我可以将这些类型分配给彼此吗?也许有副本?还是我需要循环?

【问题讨论】:

标签: arrays delphi generics


【解决方案1】:

这些类型不兼容赋值。在理想的世界中,您将专门使用TArray<T>,如果所有库都这样做会更好。我不明白为什么 Indy 坚持在这里使用自己独特的类型。

如果你不能,那么你可以制作一个副本。使用循环很容易。如果效率很重要,您可以使用Move 进行复制。

SetLength(Dest, Length(Source));
Move(Pointer(Source)^, Pointer(Dest)^, Length(Source));

我在这里使用Pointer(arr)^ 而不是arr[0] 以避免在空数组的情况下触发范围检查异常。

也可以通过使用类型转换来避免复制,因为所有动态数组都以相同的方式实现。所以你可以写

Hash := HashBytes(TIdBytes(TEncoding.UTF8.GetBytes(...)));

当然,这放弃了类型安全,但是上面对Move 的调用也是如此。

Remy's answer to another question 建议的另一种方法是使用TIdTextEncoding 而不是TEncoding。这样您就可以专门使用TIdBytes

【讨论】:

  • 我想 Indy 这样做是为了向后兼容没有 TArray 的 Delphi 版本?
  • @penarthur66 TIdBytes 可以很容易地有条件地定义来解决这个问题。
  • @penarthur66 实际上,TIdBytes 在可用时曾是 TBytes 的别名(可用时是 TArray<Byte> 的别名),但这样做会导致很多问题,尤其是在跨越 Delphi/C++ 边界的多个事件处理程序(Embarcadero RTTI 错误)。所以最终我别无选择,只能让TIdBytes 回到使用array of Byte 来维持正常的功能。这不是为了处理向后兼容性,而是为了处理 Embarcadero 错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-29
  • 1970-01-01
  • 1970-01-01
  • 2019-02-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多