Originale-mail to me for new edition

 

With statements

 

A with statement is a shorthand for referencing the fields of a record or the fields, properties, and methods of an object. The syntax of a with statement is

with obj do statement

or

with obj1, ..., objn do statement

where obj is a variable reference denoting an object or record, and statement is any simple or structured statement. Within statement, you can refer to fields, properties, and methods of obj using their identifiers alone without qualifiers.

For example, given the declarations

type TDate = record

  Day: Integer;

  Month: Integer;

  Year: Integer;

end;

var OrderDate: TDate;

you could write the following with statement.

with OrderDate do

  if Month = 12 then

  begin

    Month := 1;

    Year := Year + 1;

  end

  else

    Month := Month + 1;

This is equivalent to

if OrderDate.Month = 12 then

begin

  OrderDate.Month := 1;

  OrderDate.Year := OrderDate.Year + 1;

end

else

  OrderDate.Month := OrderDate.Month + 1;

If the interpretation of obj involves indexing arrays or dereferencing pointers, these actions are performed once, before statement is executed. This makes with statements efficient as well as concise. It also means that assignments to a variable within statement cannot affect the interpretation of obj during the current execution of the with statement.

Each variable reference or method name in a with statement is interpreted, if possible, as a member of the specified object or record. If there is another variable or method of the same name that you want to access from the with statement, you need to prepend it with a qualifier, as in the following example.

with OrderDate do

  begin

    Year := Unit1.Year

    ...

  end;

When multiple objects or records appear after with, the entire statement is treated like a series of nested with statements. Thus

with obj1, obj2, ..., objn do statement

is equivalent to

with obj1 do

  with obj2 do

     ...

     with objn do

       statement

In this case, each variable reference or method name in statement is interpreted, if possible, as a member of objn; otherwise it is interpreted, if possible, as a member of objn-1; and so forth. The same rule applies to interpreting the objs themselves, so that, for instance, if objn is a member of both obj1 and obj2, it is interpreted as obj2.objn.

 

Topic groups

 

See also

Structured statements: Overview

 

 

译文

 

With语句

 

with语句是对记录中的字段或对象中的域、属性、方法等的简写。with语句的语法形式是

with obj do statement

with obj1, ..., objn do statement

这里的obj是表示一个对象或记录的引用,statement是任何简单语句或结构语句。在statement,中,可以通过使用相应的标识符来访问对象obj的域、属性和方法等,而不需要限定词。

例如,对于给出的声明

type TDate = record

  Day: Integer;

  Month: Integer;

  Year: Integer;

end;

var OrderDate: TDate;

可以写出如下的with语句:

with OrderDate do

  if Month = 12 then

  begin

    Month := 1;

    Year := Year + 1;

  end

  else

    Month := Month + 1;

上面的语句等价于:

if OrderDate.Month = 12 then

begin

  OrderDate.Month := 1;

  OrderDate.Year := OrderDate.Year + 1;

end

else

  OrderDate.Month := OrderDate.Month + 1;

如果obj的解释涉及对数组的索引或对指针的解除参照,那么在语句statement被执行之前,这些动作(索引或解除参照)会被执行一次。这使得with语句简捷高效。此外,在整个with语句执行过程中,在语句statement内部对变量的赋值不影响对obj的解释。

 

如果可能,with语句中的每个变量引用或方法名称都被作为指定对象或记录的成员解释。如果需要在with语句中访问另一个同名的变量或方法,那么需要为其冠以限定词,例如:

with OrderDate do

  begin

    Year := Unit1.Year

    ...

  end;

 

当多个对象或记录出现在with之后时,整个语句被视为一系列的嵌套with语句。如

with obj1, obj2, ..., objn do statement

等价于

with obj1 do

  with obj2 do

     ...

     with objn do

       statement

这时,对于语句statement中的每个变量引用或方法名,如果可能,都作为objn的成员解释;否则,如果可能,都作为objn-1的成员解释;以此类推。对with语句所有obj的解释,也适用这同样的规则,因此,如果objn既是obj1的成员也是obj2的成员(同名),那么将被解释成obj2.objn,而不是obj1.objn

 

主题组

 

相关主题

结构语句:概述

 

 

编者注

对于出现在with语句中的变量应用或其他标识符,除了上面列举的情况之外,还可能出现标识符不属于任何with的对象(objs)但也不与所有with的对象的成员同名的情况。这时如果没有在标识符前冠以限定词,那么将依照作用域的规则来解释。例如:

 

var

  MyVariable: string;

function DoTest: Boolean;

var

  Res: Boolean;

  AForm: TForm;

  Width: Integer;

begin

  Res := False;

  AForm := TForm.Create(Application);

with AForm do try

  ...

{ 下面的MyVariable不是AForm的成员,也不需要冠以限定词 }

  MyVariable := SomeStirng;

  { 下面的WidthAForm的成员,因此优先解释为AForm.Width }

  Width := 800;

  ...

finally

  Result := Res;

  Free;  { 调用AForm.Free }

end;

{ 下面语句已不在with语句中, 因此Width是指函数中声明的变量 }

Width := 1024;

...

end;

 

从另外的角度理解,可以认为,with语句超越了作用域规则,即优先于作用域规则对标识符逐一进行解释,而对那些没有成功冠以任何限定词(即找到with对象列表中合适的项)的标识符,将继续依照作用域的规则进行解释。