Назначение типа Fortran
Скажем, что у меня есть производный тип Fortran
type :: atype
integer :: n
integer :: a(10)
integer, allocatable :: b(:)
end type
и у меня есть два экземпляра этого типа
type(atype) :: t1, t2
что происходит, когда я выполняю следующее задание?
t2 = t1
Мне интересно это, потому что я хотел бы правильно сделать копии переменных производного типа, скалярные компоненты должны быть равны, каждый элемент компонентов массива должен быть равным, а распределяемые массивы должны иметь одинаковый размер и элементы должны быть равны. На данный момент я просто напишу подпрограмму, которая копирует и правильно распределяет компоненты.
subroutine copy_atype(from, to)
type(atype) :: from, to
to%n = from%n
to%a = from%a
if (allocated(to%b)) deallocate(to%b)
if (allocated(from%b) then
allocate(to%b(size(from%b)))
to%b = from%b
end if
end subroutine
Я был бы признателен за соответствующие разделы в стандартах.
Я использую gfortran 4.7.
Ответы
Ответ 1
В отсутствии подходящей заданной процедуры назначения, доступной для назначения одного атипа другому, происходит присвоение собственного производного типа. Это описано в F2008 7.2.1.3. Для определения вашего типа встроенное присвоение производного типа в основном делает то, что делает ваша процедура:
-
Нераспределяемые компоненты (которые сами не имеют привязки с привязкой к типу) назначаются через использование внутреннего назначения. Если у них есть привязка к типу, это используется.
-
Выделяемые компоненты в назначаемом объекте освобождаются, если они уже выделены, перераспределены с теми же типами, параметрами типа и границами назначаемого выражения, а затем введите связанное ограничение (если применимо) или внутреннее назначение используется для передачи значения.
также:
-
Компоненты указателя назначаются указателем,
-
Компоненты coarray должны соответствовать статусу распределения между переменной и выражением и передаваться с использованием встроенного назначения.
Ответ 2
Это очень похоже на вопрос, заданный несколько дней назад: Вложенный производный тип с перегруженным присваиванием. См. Принятый ответ там для подробного объяснения.
Вы можете использовать вашу подпрограмму copy_atype
напрямую, чтобы сформировать оператор assignment
:
type :: atype
integer :: n
integer :: a(10)
integer, allocatable :: b(:)
contains
procedure :: copy_atype
generic :: assignment(=) => copy_atype
end type
Таким образом, вы можете напрямую присваивать значения одного и того же типа переменной типа atype
. Вы даже можете расширить назначение на другие типы переменных, предоставив список соответствующих подпрограмм, разделенных запятыми.