2013-10-30 90 views
5

我想創建一個將函數作爲輸出返回的子例程。我怎樣才能做到這一點?我把(我知道這是寫的不好)的如何,我認爲它應該是一個例子作爲輸出參數的函數

module fun_out 

contains 

subroutine exponential(F,a) 
    interface, intent(out) 

     function f(x) 
     real, intent(in)::x 
     real :: f(2) 
     end function 
    end interface 
    real,intent(in):: a 

    F=exp(a*x) 

end subroutine exponential 

end module 

有了這個,我應該採取一個函數從指數族輸出。

回答

2

你將不得不返回一個函數指針。這可以在Fortran 2003中完成。

procedure(name_of_interface), pointer :: f 

然而,您不能期望完全的詞法範圍關閉,只是純粹的指針。

你必須有一個正常的外部模塊或F2008甚至內部程序製備(有一些限制)的程序,只是指向它:

f => my_function 

你的情況,你有說法a,和你似乎想使用它捕獲的閉包變量。在Fortran中是不可能的。您必須每次都將函數傳遞給函數,或者使用Functor模式(持有捕獲的參數的派生類型),或者使用內部過程(但僅在其主機過程內有效)。

1

你可以基本上做到這一點(同樣在Vladimir's answer中提到)定義了函子對象。它們有一個返回值的特定函數(例如getvalue()),並且根據它們的初始化,它們可以返回自定義的函數值。

以下示例詳細說明。泛函函數的定義見functor_module,在expfunc_module中具體實現了對指數函數族的推導。然後,在主程序中,然後用指數中的不同前導因子初始化不同的實例,並使用它們的getvalue()方法獲得相應的函數值。:

module functor_module 
    implicit none 

    integer, parameter :: wp = kind(1.0d0) 

    type, abstract :: functor 
    contains 
    procedure(getvalue_iface), deferred :: getvalue 
    end type functor 

    interface 
    function getvalue_iface(self, xx) result(yy) 
     import 
     class(functor), intent(in) :: self 
     real(wp), intent(in) :: xx 
     real(wp) :: yy 
    end function getvalue_iface 
    end interface 

end module functor_module 


module expfunc_module 
    use functor_module 
    implicit none 

    type, extends(functor) :: expfunc 
    real(wp) :: aa 
    contains 
    procedure :: getvalue 
    end type expfunc 

contains 

    function getvalue(self, xx) result(yy) 
    class(expfunc), intent(in) :: self 
    real(wp), intent(in) :: xx 
    real(wp) :: yy 

    yy = exp(self%aa * xx) 

    end function getvalue 

end module expfunc_module 


program test_functors 
    use expfunc_module 
    implicit none 

    type(expfunc) :: func1, func2 
    real(wp) :: xx 

    func1 = expfunc(1.0_wp) 
    func2 = expfunc(2.0_wp) 
    xx = 1.0_wp 
    print *, func1%getvalue(xx) ! gives exp(1.0 * xx) = 2.718... 
    print *, func2%getvalue(xx) ! gives exp(2.0 * xx) = 7.389... 

end program test_functors