OberonCore
https://forum.oberoncore.ru/

Приёмник метода
https://forum.oberoncore.ru/viewtopic.php?f=29&t=6715
Страница 1 из 1

Автор:  Александр К [ Понедельник, 18 Январь, 2021 14:08 ]
Заголовок сообщения:  Приёмник метода

В методах когда какой получающий параметр/приёмник (receiver) делать (pointer, VAR, IN), в каких случаях и для чего?

Автор:  Иван Денисов [ Понедельник, 18 Январь, 2021 14:45 ]
Заголовок сообщения:  Re: Приёмник метода

По умолчанию Блэкбокс копирует данные, передаваемые в аргументах, чтобы защитить их от изменения при использовании после вызова.

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

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

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

Автор:  adimetrius [ Понедельник, 18 Январь, 2021 15:53 ]
Заголовок сообщения:  Re: Приёмник метода

Как я понял, вопрос про приемник 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;

Автор:  kekc_leader [ Вторник, 30 Март, 2021 15:25 ]
Заголовок сообщения:  Re: Приёмник метода

Интересно, что в языке 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`.

Автор:  Wlad [ Четверг, 01 Апрель, 2021 12:26 ]
Заголовок сообщения:  Re: Приёмник метода

adimetrius писал(а):
...
Код:
TYPE
   ObjPtr = POINTER TO ObjDesc;
   ObjDesc = RECORD ... END;
Интересно, что, дополнительно позволяет делать (или на что "нарываться") вот такой вариант (если он сейчас позволителен)?:
Код:
PROCEDURE (VAR op: ObjPtr) VP, NEW; END VP;

Автор:  Илья Ермаков [ Четверг, 01 Апрель, 2021 12:47 ]
Заголовок сообщения:  Re: Приёмник метода

Wlad писал(а):
adimetrius писал(а):
...
Код:
TYPE
   ObjPtr = POINTER TO ObjDesc;
   ObjDesc = RECORD ... END;
Интересно, что, дополнительно позволяет делать (или на что "нарываться") вот такой вариант (если он сейчас позволителен)?:
Код:
PROCEDURE (VAR op: ObjPtr) VP, NEW; END VP;


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

Страница 1 из 1 Часовой пояс: UTC + 3 часа
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/