OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Пятница, 29 Март, 2024 01:57

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 6 ] 
Автор Сообщение
 Заголовок сообщения: Приёмник метода
СообщениеДобавлено: Понедельник, 18 Январь, 2021 14:08 

Зарегистрирован: Воскресенье, 06 Август, 2017 19:33
Сообщения: 79
В методах когда какой получающий параметр/приёмник (receiver) делать (pointer, VAR, IN), в каких случаях и для чего?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Приёмник метода
СообщениеДобавлено: Понедельник, 18 Январь, 2021 14:45 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 3774
По умолчанию Блэкбокс копирует данные, передаваемые в аргументах, чтобы защитить их от изменения при использовании после вызова.

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

Если же вы хотите специально, чтобы передаваемые данные изменились внутри процедуры, чтобы потом это изменённое значение как-то использовать, то тогда указываете VAR.

OUT - для выходных аргументов, чтобы записать в них результат вычислений.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Приёмник метода
СообщениеДобавлено: Понедельник, 18 Январь, 2021 15:53 
Аватара пользователя

Зарегистрирован: Суббота, 16 Февраль, 2008 02:47
Сообщения: 660
Как я понял, вопрос про приемник Receiver метода (типовой процедуры). Здесь правило проще: если ваш тип - POINTER, то приемник - параметр-значение, если ваш тип - RECORD, то параметр-переменная.
Код:
TYPE
   ObjPtr = POINTER TO ObjDesc;
   ObjDesc = RECORD ... END;

PROCEDURE (op: ObjPtr) P, NEW; END P;

PROCEDURE (VAR obj: ObjDesc) Q, NEW; END Q;


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Приёмник метода
СообщениеДобавлено: Вторник, 30 Март, 2021 15:25 
Аватара пользователя

Зарегистрирован: Среда, 22 Апрель, 2015 23:51
Сообщения: 248
Откуда: г. Рига, Латвийская ССР
Интересно, что в языке Go приёмники тоже можно указывать двояко. Как указатели и как значения. Но при указании по значению нельзя изменять данные в приёмнике.

Честно говоря, я даже не знал, что приёмник может быть VAR-параметром в Обероне, пока не прочитал соответствующее место в описании Go и не стал проверять. VAR-параметров в Go нет, а только указатели. Оформляются как обероновские, но вместо «POINTER TO» пишется сишная звёздочка (а порядок лексем обероновский).

Код:
package main

import (
   "fmt"
   "math"
)

type Vertex struct {
   X, Y float64
}

func (v *Vertex) Scale(f float64) {
   v.X = v.X * f
   v.Y = v.Y * f
}

func (v *Vertex) Abs() float64 {
   return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

func main() {
   v := &Vertex{3, 4}
   fmt.Printf("Before scaling: %+v, Abs: %v\n", v, v.Abs())
   v.Scale(5)
   fmt.Printf("After scaling: %+v, Abs: %v\n", v, v.Abs())
}


Вот как они это описывают:
Цитата:
Вы можете объявлять методы, где в качестве получателей выступают указатели.

Это означает, что получатель объявлен как `*T` для некоторого типа `T`.
(И еще, `T` не может быть указателем сам по себе, как, например, `*int`.)

Например, метод `Scale` в данном примере объявлен для `*Vertex`.

Методы с получателями-указателями могут модифицировать значение, на которое
указывает получатель (как делает `Scale` в данном примере).
Т.к. методам часто необходимо модифицировать получателя, то
использование указателей более частая практика, чем получатели как значения.

Попробуйте убрать `*` из объявления функции `Scale` на строке 16
и понаблюдайте, как изменяется поведение программы.

При использовании получателя-значения, метод `Scale` работает с копией оригинального
значения `Vertex`.
(Это такое же поведение, как и для любого другого аргумента функции.)
Метод `Scale` должен иметь указатель на получателя для того, чтобы изменить значение `Vertex`,
объявленное в функции `main`.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Приёмник метода
СообщениеДобавлено: Четверг, 01 Апрель, 2021 12:26 

Зарегистрирован: Воскресенье, 28 Май, 2006 22:12
Сообщения: 1693
adimetrius писал(а):
...
Код:
TYPE
   ObjPtr = POINTER TO ObjDesc;
   ObjDesc = RECORD ... END;
Интересно, что, дополнительно позволяет делать (или на что "нарываться") вот такой вариант (если он сейчас позволителен)?:
Код:
PROCEDURE (VAR op: ObjPtr) VP, NEW; END VP;


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Приёмник метода
СообщениеДобавлено: Четверг, 01 Апрель, 2021 12:47 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
Wlad писал(а):
adimetrius писал(а):
...
Код:
TYPE
   ObjPtr = POINTER TO ObjDesc;
   ObjDesc = RECORD ... END;
Интересно, что, дополнительно позволяет делать (или на что "нарываться") вот такой вариант (если он сейчас позволителен)?:
Код:
PROCEDURE (VAR op: ObjPtr) VP, NEW; END VP;


Нет, VAR для POINTER-приёмника непозволителен.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 6 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
cron
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2024, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB