Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi中的非类型化/无类型参数_Delphi_Parameters_Typing - Fatal编程技术网

Delphi中的非类型化/无类型参数

Delphi中的非类型化/无类型参数,delphi,parameters,typing,Delphi,Parameters,Typing,TStringStream类中没有类型的参数是什么类型: function Read(var Buffer; Count: Longint): Longint; override; 缓冲区参数的类型是什么(它是指针的类型吗?)查看Delphi帮助中的“非类型参数” 您可以传入任何类型,但必须在实现中强制转换它。帮助说明您不能向其传递数字或非类型化的数字常量。所以,基本上,您必须知道预期的类型,而编译器不能帮助您,所以您需要一个很好的理由来这样做。我想如果您需要该方法来处理不兼容的类型,那么它可

TStringStream类中没有类型的参数是什么类型:

function Read(var Buffer; Count: Longint): Longint; override;

缓冲区参数的类型是什么(它是指针的类型吗?)

查看Delphi帮助中的“非类型参数”


您可以传入任何类型,但必须在实现中强制转换它。帮助说明您不能向其传递数字或非类型化的数字常量。所以,基本上,您必须知道预期的类型,而编译器不能帮助您,所以您需要一个很好的理由来这样做。我想如果您需要该方法来处理不兼容的类型,那么它可能会有用,但是您也可以为每个预期类型编写多个重载版本,我建议作为更好的解决方案。

var
在参数列表中是的Delphi语法。它可以类型化,例如Listview的onChange处理程序中的AllowChange参数:

procedure TSomeForm.LVOnChanging(Sender: TObject; ...; var AllowChange: Boolean);
begin
  if SomeProblemOccurred then
    AllowChange := False;
end;

或者像你的例子中那样取消键入。

几年前我就写了一篇关于这个主题的文章:

少数情况下使用非类型化参数;您询问的
TStream.Read
方法与我写的
Move
过程最为匹配。这里有一段摘录:

Move
过程从任意变量复制数据 转换为任何其他变量。它需要接受数据的来源和目的地 所有类型,这意味着它不需要任何单一类型。程序 不修改为
源传递的变量的值,以便
参数的声明使用
const
而不是
var
,后者是 非类型化参数的更常见修饰符

TStream.Read
的情况下,源是流的内容,因此您不会将其作为参数传入,但目标是问题中显示的
缓冲区
参数。您可以为该参数传递任何想要的变量类型,但这意味着您需要小心。确保流的内容确实是您提供的参数类型的有效值是您的工作,而不是编译器的工作


有关Delphi使用非类型化参数的更多情况,请阅读本文的其余部分。

也许令人惊讶的是,将取消引用的指针作为非类型化参数传递是合法的。指针本身甚至不必有类型

procedure SomeMethod(var aParameter);
  ∶

procedure CallSomeMethod(aIsInteger : Boolean);
type
  buffer    : Pointer;
  intValue  : Integer;
  realValue : Single;
begin
  if aIsInteger then
  begin
    buffer := @intValue;
  end
  else
  begin
    buffer := @realValue;
  end;
  SomeMethod(buffer^);

当然,如果SomeMethod()的参数是指针,可能会更简单,但这可能不在您的控制之下。

缓冲区
参数不是指针。把它当作一个指针,事情就会崩溃。它是要更改的实际缓冲区,而不是指向缓冲区的指针。参数的地址是缓冲区的地址。
procedure SomeMethod(var aParameter);
  ∶

procedure CallSomeMethod(aIsInteger : Boolean);
type
  buffer    : Pointer;
  intValue  : Integer;
  realValue : Single;
begin
  if aIsInteger then
  begin
    buffer := @intValue;
  end
  else
  begin
    buffer := @realValue;
  end;
  SomeMethod(buffer^);