stored-procedures - transact - stored procedure with return value sql
Fortran guardar procedimiento como propiedad en tipo derivado (1)
¿Es posible almacenar un procedimiento como una propiedad de un tipo derivado? Estaba pensando en algo como:
module funcs_mod
public :: add
contains
function add(y,z) result (x)
integer,intent(in) :: y,z
integer :: x
x = y + z
end function
end module
module type_A_mod
use funcs_mod
public :: type_A,set_operator
type type_A
procedure(),pointer,nopass :: operator
end type
contains
subroutine set_operator(A,operator)
external :: operator
type(type_A),intent(inout) :: A
A%operator => operator
end subroutine
function operate(A,y,z) result(x)
type(type_A),intent(in) :: A
integer,intent(in) :: y,z
integer :: x
x = A%operator(y,z)
end function
end module
program test
use type_A_mod
use funcs_mod
type(type_A) :: A
call set_operator(A,add)
write(*,*) operate(A,1,2)
end program
Pero esto no se compila correctamente. Se muestran varios errores, incluyendo:
1) Error de sintaxis en el componente de puntero de procedimiento
y
2) ''operator'' en (1) no es miembro de la estructura ''type_a''
Además de algunas declaraciones de uso sin éxito. ¿Hay alguna manera de hacer esto correctamente? Cualquier ayuda es muy apreciada.
ACTUALIZAR:
He modificado el procedure,pointer
a procedure(),pointer
y ahora los errores son
1) El atributo FUNCTION entra en conflicto con el atributo SUBROUTINE en ''operator''
y
2) No se puede convertir DESCONOCIDO en INTEGER (4)
Ambos se refieren a la línea x = A%operator(y,z)
Como ha descubierto, la sintaxis para declarar una declaración de puntero de procedimiento requiere procedure([interface]), pointer [, ...] :: ...
Usted eligió procedure(), pointer, nopass :: operator
.
La consecuencia del procedure()
es que no está declarando si el operator
es una función o una subrutina. No hay nada de malo en esto, pero luego queda más trabajo en convencer al compilador de que está utilizando las referencias de manera consistente. Parece que tu compilador no te cree.
En lugar de entrar en detalles de lo que el compilador cree que quiere decir, tomaré un enfoque diferente.
Hace referencia al A%operator
para una estructura A
de tipo con ese componente como resultado de la función de operate
. Usted dice claramente al declarar esta última función que su resultado es un número entero.
Ahora, suponiendo que no quiere hacer cosas emocionantes con la conversión tipo / tipo para llegar a ese resultado entero, consideraremos que siempre tiene la intención de que A%operator
sea una función con un resultado entero. Eso significa que puede declarar que el componente de puntero a procedimiento es una función con resultado entero.
Esto todavía te deja con opciones:
type type_A
procedure(integer),pointer,nopass :: operator
end type
siendo una función con resultado entero e interfaz implícita, y
type type_A
procedure(add),pointer,nopass :: operator
end type
siendo una función con interfaz explícita que coincide con la función add
.
Sus opciones de diseño en curso informan su decisión final.
Como nota final, no está utilizando implicit none
. Esto es importante cuando consideramos su línea
external :: operator
Si el operator
es una función, entonces (por reglas implícitas de tipado) tiene un resultado real (predeterminado). Entonces, quiere cambiar a uno de los siguientes
integer, external :: operator
o
procedure(integer) :: operator
o
procedure(add) :: operator
Para concluir, y hacerse eco del comentario de Vladimir F, piense detenidamente en su diseño. Actualmente tiene restricciones de la referencia de operate
(en el resultado de la función y sus argumentos) que parece que realmente sabe que el componente tendrá una interfaz específica. Si está seguro de eso, entonces use el procedure(add)
como la declaración /