Каковы правила для того, использовать или нет, чтобы указать значение?

Ниже приведен простой пример использования указателя в delphi.

Type

TRecord1 = Record
field1 : String;

end; 

procedure TForm1.Button2Click(Sender: TObject);
var
   Rec : TRecord1;
   Ptr: ^TRecord1;

begin
   Rec.field1:= 'field1';
   Ptr := @Rec;
   memo1.Lines.Add (Ptr^.field1); 
   memo1.Lines.Add (Ptr.field1); // it also works.

 end;

В этом случае работают Ptr ^ и Ptr. Кажется, delphi позволяет пользователю более гибко указывать на значение. Но просто читая две строки, они синтаксически разные и могут означать по-разному. В таком случае обе работают. Но мой вопрос:

  • как пользователь может узнать в других ситуациях, где ^ может или не может быть опущено или, где с ^ или без ^ означает одно и то же или иначе?
  • Что это за ситуации? Примеры будут оценены.
  • Почему? (Необязательно)

Большое спасибо заранее.

Ответ 1

как пользователь может узнать в других ситуациях, где ^ можно или не может быть опущено или, где с ^ или без ^ означает то же или по-другому?

Что это за ситуации? Примеры будут оценены.

Простой Pointer не имеет никаких полей или свойств, поэтому игнорируя умения Delphi, синтаксис Pointer.Field не имеет смысла. Из-за этого не может быть конфликта между Pointer^.Field и Pointer.Field, просто потому, что простой синтаксис . не имеет смысла, если вы не разыщите указатель.

Если тип, на который указывает указатель, не имеет никаких полей, вы должны использовать синтаксис ^. То есть, когда указатель является указателем на базовый тип или является нетипизированным указателем.

Почему? (Необязательно)

Ссылки на экземпляр класса (то, что большинство людей назвали бы "объектами" ) также являются указателями в Delphi, я предполагаю, что был введен синтаксис, чтобы сделать работу с Pointers менее подробной и больше похожей на использование классов. Это также безвредно, потому что, как упоминалось выше, компилятор не может ошибиться.

Я лично предпочитаю синтаксис ^., потому что он ясно показывает, что я работаю с указателем, а не с записью или классом.

Ответ 2

Единственное отличие состоит в том, что

Ptr1 := Ptr2 

не равно

Ptr1^ := Ptr2^

Первая строка заставит Ptr1 и Ptr2 указывать на одну и ту же область памяти, вторая назначит значение, на которое указывает Ptr2, на "переменную", на которую указывает Ptr1.

По этой причине я полагаю, что синтаксис значения Ptr.Field должен быть ошибкой, потому что, даже если из-за компилятора не возникает неоднозначности, он вводит ленивый способ написания кода, который может иметь неприятные последствия в ситуациях, подобных описанным выше.

Ответ 3

ptr.property никогда не действует и явно отличается от ptr ^.property, поэтому Delphi позволяет вам исключить ^. если ptr не набирается (или является базовым типом данных), тогда всегда требуется ^.

Ответ 4

Это очень просто. Если использование ptr.field является однозначным, т.е. Если оно не может иметь никакого другого значения, кроме ptr ^.field, то ^ можно опустить.

Но только тогда. В случаях, когда опускание ^ создает неоднозначную конструкцию (т.е. Где она может иметь разные значения), ее нельзя опустить.