简体   繁体   English

我可以在Delphi / Pascal中一次性分配数组中的项目吗?

[英]Can I assign items in an array all at once in Delphi/Pascal?

I want to do something like in PHP, Python and most other programming languages: 我想做一些像PHP,Python和大多数其他编程语言的东西:

my_array_name = [128, 38459, 438, 23674...] 

So I tried to replicate this in Delphi/Pascal the best I could: 所以我尽力在Delphi / Pascal中复制它:

HSVtoRGB := [0, 0, 0];

(this is for a function which returns an RGB array given HSV values.) (这是针对给定HSV值返回RGB数组的函数。)

But I am getting errors: 但是我收到了错误:

[DCC Error] Unit2.pas(44): E2001 Ordinal type required
[DCC Error] Unit2.pas(45): E2010 Incompatible types: 'HSVRealArray' and 'Set'

Any idea? 任何的想法? This is school work - but my teacher didn't know the answer. 这是学校的工作 - 但我的老师不知道答案。

When it comes to dynamic arrays, yes: 说到动态数组,是的:

type
  TIntArray = array of integer;

procedure TForm1.Button1Click(Sender: TObject);
var
  MyArr: TIntArray;
begin
  MyArr := TIntArray.Create(10, 20, 30, 40);
end;

When it comes to static arrays, you need to write a helper function: 说到静态数组,你需要编写一个辅助函数:

type
  TIntArray = array[0..2] of integer;

function IntArray(const A, B, C: integer): TIntArray;
begin
  result[0] := A;
  result[1] := B;
  result[2] := C;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  MyArr: TIntArray;
begin
  MyArr := IntArray(10, 20, 30);
end;

This resembles how the Point function creates a TPoint record. 这类似于Point函数如何创建TPoint记录。 (Records and arrays are not the same thing, though.) (但记录和数组并不是一回事。)

This is an area where Delphi turns something that is a simple one-line assignment statement in most languages into something more complicated. 在这个领域,Delphi将大多数语言中简单的单行赋值语句转换为更复杂的东西。

One approach would to declare the value as a typed constant: 一种方法是将值声明为类型常量:

type
  HSVRealArray = array[1..3] of real;
const
  constHSVVal: HSVRealArray = (0, 0, 0);
var
  currentValue: HSVRealArray;
begin
  currentValue := constHSVVal;
end;

Another approach is to create utility functions that return the type you need: 另一种方法是创建返回所需类型的实用程序函数:

function MakeHSVRealArray(H, S, V: Real): HSVRealArray;
begin
  Result[1] := H;
  Result[2] := S;
  Result[3] := V;
end;

currentValue := MakeHSVRealArray(0,0,0);

With some extra work, you can achieve a clean implementation: 通过一些额外的工作,您可以实现一个干净的实现:

var
    x: TRGB;
begin
    x := TRGB.Init(0,0,0);
end;

TRGB = record
    Red, Green, Blue: real;
    class function Init(r,g,b: real): TRGB; static;
end;

class function TRGB.Init(r, g, b: real): TRGB;
begin
    Result.Red := r;
    Result.Green := g;
    Result.Blue := b;
end;

For array handling, array initialization and array constant declarations, Delphi doesn't make simple things simple. 对于数组处理,数组初始化和数组常量声明,Delphi并不简单。

In some situations similar to yours, I initialize the array with a utility function taking one open array parameter and returning the appropiate static string. 在某些类似于你的情况下,我使用实用程序函数初始化数组,获取一个打开的数组参数并返回适当的静态字符串。

const
    MaxArray = 10;
type
    TRealStaticArray = array[0..MaxArray] of Real;

function RealArray(const AnArray: array of real):TRealStaticArray;
    const DefaultValue=0.0;
    var i: integer;
    begin
        // EDIT: commented out, thanks Serg. for i:= 0 to low(AnArray)-1 do result[i]:=DefaultValue;
        for i:= High(AnArray)+1 to MaxArray do
            result[i]:=DefaultValue;
        for i:= Low(AnArray) to High(AnArray) do
            if (i>=0) and (i<=MaxArray) then
                result[i]:=AnArray[i];
    end;

Use it this way: 用这种方式:

 var MyArray: TRealStaticArray;
 ...
 MyArray := RealArray([10.0, 20.0, 30.0]);

Delphi-XE7 introduced a new syntax for dynamic array initialization. Delphi-XE7为dynamic array初始化引入了一种新语法。

// compile time const declaration of dynamic array
const
  my_ConstArray_name: TArray<Integer> = [128, 38459, 438, 23674];

// compile time var declaration of dynamic array
var
  my_VarArray_name: TArray<Integer> = [128, 38459, 438, 23674];

Runtime assignment of dynamic arrays: 动态数组的运行时分配:

var
  a : TArray<Integer>;
begin
  a := [1,2,3];

Unfortunately this syntax cannot be used on ordinary static arrays: 不幸的是,这种语法不能用于普通的静态数组:

Type
  TMyArray = array[0..3] of Integer;  

const
  cMyArray: TMyArray = [0,1,2,3]; // E2010 Incompatible types: 'TMyArray' and 'Set'
  cMyArray: TMyArray = (0,1,2,3); // Works, as in all Delphi versions

var
  MyArray: TMyArray;
begin
  // This fails as well
  MyArray := [0,1,2,3]; // E2010 Incompatible types: 'TMyArray' and 'Set'
  MyArray := (0,1,2,3); // E2029 ')' expected but ',' found  
  //-----------^-------

  // This works in all Delphi versions !
  MyArray := cMyArray;

I know this is an old post, but I came across this while looking into the auto-assignment technique for Delphi. 我知道这是一个老帖子,但我在研究Delphi的自动分配技术时遇到了这个问题。 This post has a very nice explanation, along with a way to auto-assign an array of records: 这篇文章有一个非常好的解释,以及一种自动分配记录数组的方法:

http://delphi.about.com/od/adptips2006/qt/const_array.htm http://delphi.about.com/od/adptips2006/qt/const_array.htm

Unfortunately, the initialization can only be done with native or record types. 不幸的是,只能使用本机或记录类型进行初始化。 Class objects need a helper function as others have shown above. 类对象需要辅助函数,如上所示。

Can you try something like that: 你可以尝试这样的事情:

TRGB = record
      Red  : integer;
      Green: integer;
      Bklue: integer;
  end;

var Variable:TRGB;

Variable.Red:=0;
Variable.Green:=0;
Variable.Blue:=0;

Putting aside the general question, I'd like to point out that the specific use-case was never going to work anyway: Delphi can't return on the stack the contents of an array of unknown length. 抛开一般性问题,我想指出具体的用例无论如何都不会起作用:Delphi无法在堆栈上返回未知长度数组的内容。

The return type of a function needs to be known by the calling code. 调用代码需要知道函数的返回类型。 It may be a pointer to the heap: it may even be a memory-managed object on the stack: but it is not permitted to be an undefined number of bytes on the stack, decided dynamically by the target function. 它可能是指向堆的指针:它甚至可能是堆栈上的内存管理对象:但它不允许是堆栈上未定义的字节数,由目标函数动态决定。

And in many other languages, the example 在许多其他语言中,例子

return (0,0,0)  //return pointer to automatic allocation

would be undefined, even if the compiler lets you do it. 将是未定义的,即使编译器允许您这样做。

A common method of defining, using and returning const values is 定义,使用和返回const值的常用方法是

int myarray[8] = {128, 38459, 438 ... 23674};
memcpy (myparam, myArray, sizeof (myArray)); 

... and you can do that in Delphi ......你可以在Delphi中做到这一点

[0, 0, 0] is a set in Delphi. [0, 0, 0]是Delphi中的一个集合。 (0, 0, 0) is an array constant in Delphi! (0, 0, 0)是Delphi中的数组常量! Just use: 只需使用:

HSVtoRGB := (0, 0, 0);

(Unless HSVtoRGB is a dynamic array. Did you declare it as var HSVtoRGB: array[1..3] of integer; or something similar? (除非HSVtoRGB是动态数组。你是否将它声明为var HSVtoRGB: array[1..3] of integer;或类似的东西?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM