Кто-нибудь может дать мне краткий обзор использования "одинарной кавычки" в Ada? - PullRequest
5 голосов
/ 27 сентября 2011

Я только что прочитал «Программирование Ады», но я немного озадачен тем, как использовать ' (знак одинарной кавычки) в Аде.

Я могу понять, что ' используется для ссылки атрибут . AAA'Image (..), BBB'Value (..)

Однако, учитывая этот кусок кода:

   type Plain_Vector (Capacity : Capacity_Subtype) is record
      Elements : Elements_Array (1 .. Capacity);
      Last     : Extended_Index := No_Index;
      Busy     : Natural := 0;
      Lock     : Natural := 0;
   end record;
 ------------------------------------------------------------------
   new Plain_Vector'(2, (Left, Right), Last => Last, others => <>)

Q1: Как аргументы «нового» оператора совпадают с полями параметра типа и записи?

 I can GUESS "2" matched "Capacity", 
             "(Left, Right)" matched "Elements", 
             "Last => Last" matched "Last"
             "Others => <>" matched "Busy" and "Lock" to let them use default value.

Но это всего лишь УГАДА, есть ли официальное объяснение грамматики по этому поводу?

Q2: Что делает '? (в «новом» выражении)

Это атрибут или имеет ли он какие-либо другие значения?

Где я могу найти общее использование "одинарной кавычки" в Ada ?

Я потратил много времени, пытаясь найти эту информацию, но не повезло.

Заранее спасибо. Майлз.

Ответы [ 2 ]

7 голосов
/ 27 сентября 2011

Если у вас есть электронная копия Справочного руководства Ada, вы можете выполнить поиск символа ' в Синтаксической сводке (это Приложение P в последней имеющейся у меня версии; проверьте оглавление).

Символ ' используется для:

  • Литералы символов: 'x'
  • Ссылки на атрибуты: Foo'Size
  • Квалифицированные выражения: Some_Type'(expression), Some_Type'Aggregate

Он также используется в предложениях представления (теперь они называются «аспектами предложения»);они очень похожи на ссылки на атрибуты: for Foo'Size use 32;.

И, конечно, они могут появляться в комментариях или в строковом или символьном литерале.

Примером в опубликованном вами коде являетсяквалифицированное выражение.

Предложение: В контекстах, отличных от символьных литералов, символ ', вероятно, следует называть апострофом, поскольку он не действует как кавычка.Для атрибутов и квалифицированных выражений это иногда произносится как «tick»: я бы прочитал Foo'Size как «foo tick size».

new - это выражение, а не утверждение.)

4 голосов
/ 27 сентября 2011

Похоже, вы спрашиваете конкретно о квалифицированных выражениях (третий маркер Кейта в его ответе).

В Аде, если у вас есть два объекта разных типов, вы можете попытаться преобразовать их между собой, используя тип назначенияимя как имя функции, например так:

Foo: constant Integer: = Integer (2.35);

Обычно это работает, только если оба типа являются числовыми типами или один из производных отother (объявлено как type New_Type is new Old_Type ...).

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

Однако, когда вы имеете дело с выражениями, иногда вам нужно не просто преобразование , а, скорее, сообщить компилятору, какой типсделать выражение.Для этого не требуется код времени выполнения, просто сделайте выражение тем типом, который я вам говорю.

Компиляторы обычно могут понять это из контекста, но иногда они не могут.Вот тут-то и появляется этот апостроф. Он говорит компилятору не преобразовывать выражение в указанный тип, а скорее создавать его как этот тип.

Наиболее распространенныйиспользуйте для этого при выполнении динамического распределения, как показано в вашем примере.Иногда могут быть другие ситуации, когда это необходимо.Одним из примеров может быть передача литерального значения в перегруженную подпрограмму.Скажем, у вас есть две версии процедуры My_Routine, одна из которых принимает Integer, а другая принимает другой пользовательский целочисленный тип.Если вы передаете объекты в него, компилятор может просто посмотреть на тип объекта.Однако, если вы передадите литерал 1, скорее всего, вы получите ошибку компилятора из-за неоднозначности выражения.

Вы можете решить эту проблему, поместив ваш литерал 1 в постоянное целое число и передав егов (затем ворча о вашем дурацком компиляторе).Однако проще сделать следующее:

My_Routine (Integer'(1));

Это устраняет неоднозначность для вашего компилятора.Это не «преобразование», поэтому дополнительный код не требуется.Вы просто сообщаете компилятору, что следующее выражение имеет тип Integer.

...