【问题标题】:Assigning values of an array all at once in Delphi without using a loop [closed]在不使用循环的情况下在Delphi中一次分配数组的值[关闭]
【发布时间】:2014-11-12 00:47:35
【问题描述】:

是否可以一次分配相同类型的值?

在我的例子中,我有一个从 TComponent 派生的自定义组件,我称之为 TBox。

TBox 中有 Left 属性。

我有一个 TBox 数组,是否可以将属性 Left 分配给所有 不使用循环同时使用 TBox 组件?

使用 for 循环设置 Left 值:

  var BoxArray: array [0..9] of TBox;
      i: integer;
begin
  for i := 0 to 9 do
  begin
    BoxArray[i] := TBox.Create(nil);
    BoxArray[i].Left := 0;
  end;
end;

我想在没有 for 循环或任何类型的循环的情况下执行上述操作。 我想将新值应用到 Left 而不遍历每个 TBox 但只需立即将新值应用于所有这些。

【问题讨论】:

  • 立即是什么意思?如果它的意思是我认为的意思,那么你会失望的。如果您不说TBox 是什么,我们将很难回答您的问题。如果我们知道为什么要避免循环,这也可能会有所帮助。人们还想知道如何在没有某种形式的迭代的情况下多次调用Random。从本质上讲,这个问题似乎暗示了某处的一些误解。我想你需要澄清一下。
  • 好的,抱歉。我不知道我是否应该同时使用这个词。是的。这听起来更好。同时地。 TBox 只是一个虚拟图形组件。无需深入了解它。这是一些OpenGL的东西。我以值 Random 为例。也可能是 BoxArray[i].Left:=0;
  • 您不想告诉我们细节?美好的。这是否意味着我们可以回答并省略所有细节?你高兴我写一个回答说,你不能这样做,但不要担心细节,你不需要知道。我非常怀疑。当然,您可以看到分配相同值和为每个项目分配不同值之间的区别,该值是函数调用的结果。你怎么能在没有迭代的情况下多次调用Random?我还是不明白你为什么害怕 10 次迭代循环。
  • TBox的细节对问题很重要。
  • @xaid - GetLeft 应该是 Left 属性的 getter。如果你一次分配所有的Left,你会不会遇到同样的问题?以后不用再看Lefts了?

标签: arrays delphi properties assign


【解决方案1】:

我想在没有 for 循环或任何类型的循环的情况下执行上述操作。我想在不遍历每个 TBox 的情况下将新值应用于 Left,而只需立即将新值应用于所有这些。

如果您需要写入多个内存位置,则需要某种形式的迭代。即使您找到了一种编写高级代码的方法,以使循环或迭代不可见,但在此过程中的某个地方仍需要进行迭代。

如果您的目标是提高性能,那么恐怕我们需要了解更多细节才能提供具体帮助。

【讨论】:

  • 是否可以使用 1 个指针指向多个方法地址之类的?我记得在 TComponent 中使用 MethodAddress() 将返回相同的地址,无论它来自哪个 TComponent,只要方法名称相同。也许这可以通过使用指针演变成一个解决方案?
  • 没有。一个指针指向内存中的一个地址。我真的不想详细说明,因为您坚持认为这个问题是非常笼统的。
【解决方案2】:

正如 David Heffernan 已经很难过的那样,一次写入多个内存位置是不可能的,这意味着一次修改多个变量或多个字段是不可能的。 从技术上讲,您可以一次更改多个属性,但前提是所有这些属性都读取相同的字段,因为更改字段值会影响读取它的所有属性。

现在,为了让您的代码看起来更好看,您可以修改 TBox 构造函数,使其也接受初始变量的附加可选参数。

type
  TBox = class(TComponent)
  ...
  public
    consturctor Create(AOwner: TComponent; Left: Integer = 0; Top: Integer = 0); override;
  ...
  end;

...

implementation

...

constructor TBox.Create(AOwner: TComponent; ALeft: Integer = 0; ATop: Integer = 0);
begin
  inherited Create(AOwner);
  self.Left := ALeft;
  self.Top := ATop;
end;

所以现在您可以通过两种方式创建您的 TBox:

BoxArray[i] := TBox.Create(nil);

将使用构造函数方法实现中定义的默认位置参数创建您的 TBox。

BoxArray[i] := TBox.Create(nil, 5, 10);

将使用您传递给构造方法的位置参数创建您的 TBox。

注意:可选参数从左到右读取,中间不能跳过一个。

BoxArray[i] := TBox.Create(nil, 5); //Is valid and top will be 0 (default value)

BoxArray[i] := TBox.Create(nil, , 10); //Is not valid and will raise compiler error

【讨论】:

    【解决方案3】:

    如果使用 TArray 和构造函数而不是 TBox 数组,则可以这样做;

    TBox = class
        left, right : Integer;
        constructor Create(l,r : Integer);
    end;
    
    constructor TBox.Create(l,r : Integer);
    begin
        left := l;
        right := r;
    end;
    
    procedure TForm2.FormCreate(Sender : TObject);
    var
        boxes : TArray<TBox>;
    begin
        boxes := TArray<TBox>.Create(TBox.Create(1,2),TBox.Create(5,10));
    end;
    

    【讨论】:

    • 这需要迭代
    猜你喜欢
    • 2013-05-19
    • 1970-01-01
    • 2015-03-06
    • 2019-12-01
    • 1970-01-01
    • 2020-04-10
    • 2018-06-02
    • 2011-07-25
    • 2013-06-25
    相关资源
    最近更新 更多