所以我想将一个可选字符串传递给子例程,如果该字符串不存在则设置一个回退字符串。但是,我不想在编译时设置回退字符串的长度。所以我有两个想法来整理doStufFirst和doStuffSecond
所以我有这个:
MODULE stuff
implicit none
contains
subroutine dostuffFirst (string)
implicit none
character(len=*),intent(in),optional :: string
character(len=min(8,len(string))) :: outString
if(present(string)) THEN
outString=string
else
outString="fallBack"
endif
call doStuff2(outString)
end subroutine dostuffFirst
subroutine dostuffSecond (string)
implicit none
character(len=*),optional :: string
character,dimension(:),allocatable :: outString
integer :: i
if(present(string)) THEN
ALLOCATE(outString(len(string)))
do i=1,len(string)
outString(i)=string(i:i)
end do
else
ALLOCATE(outString(8))
outString(1:8)=(/"f","a","l","l","B","a","c","k"/)
endif
call doStuff2(outString)
end subroutine dostuffSecond
subroutine doStuff2(str)
implicit none
character(len=*),intent(in) :: str
write(*,*) str
end subroutine doStuff2
end module stuff
PROGRAM prog
use stuff
implicit none
call dostuffFirst("123")
call dostuffSecond("123")
END program prog
但是doStuffFirst的问题是我不能在outString的声明中使用可选参数的len(string)。而dostuffSecond的问题是我现在已经成为一个排名第一的数组,但是doStuff2期待一个标量(并且之后更改所有内容以期望一个数组是不可行的)
有什么建议吗? 感谢
答案 0 :(得分:2)
考虑dostuffFirst
中的问题,尝试确定要传递给doStuff2
的字符变量的长度,您可以在PRESENT
本身执行doStuff2
逻辑吗?
subroutine doStuff2(str)
character(len=*), intent(in), optional :: str
if (PRESENT(str)) then
write(*,*) str
else
write(*,*) "fallback"
end if
emd subroutine doStuff2
如果不止一次,我会承认后者会变得有点麻烦,但是你的dostuffFirst
尝试确实可以使用包装器。一种方法是,如果你不需要一个接受输入字符串或后备字符串的变量,如下所示。
subroutine dostuffFirst (string)
character(len=*),intent(in),optional :: string
if(present(string)) THEN
call doStuff2(string)
else
call doStuff2("fallBack")
endif
end subroutine dostuffFirst
当然,如果你有很多可能的字符串,这也很快就会变得非常尴尬(很多嵌套的if
)。
subroutine dostuffFirst(string1, string2, string3)
character(len=*), intent(in), optional :: string1, string2, string3
if (PRESENT(string1)) then
if (PRESENT(string2)) then
if (PRESENT(string3)) then
call doStuff2(string1, string2, string3)
else
call doStuff2(string1, string2, "fallback3")
! etc
end subroutine dostuffFirst
解决这些问题的传统方法是选择一个非常长的str_to_use
s。
subroutine dostuffFirst(string1, string2, string3)
character(len=*), intent(in), optional :: string1, string2, string3
character(AS_LONG_AS_I_EVER_NEED) str_to_use1, str_to_use2, str_to_use3
if (PRESENT(string1)) then
str_to_use1 = string1
else
str_to_use1 = "fallback1"
end if
! etc
call doStuff2(str_to_use1, str_to_use2, str_to_use3)
end subroutine dostuffFirst
但是,如果您愿意转向更现代的编译器/编码标准,那么您可以使用延迟长度字符变量。
subroutine dostuffFirst(string1, string2, string3)
character(len=*), intent(in), optional :: string1, string2, string3
! Deferred length working variables
character(:), allocatable :: str_to_use1, str_to_use2, str_to_use3
if (PRESENT(string1)) then
str_to_use1 = string1
else
str_to_use1 = "fallback1"
end if
! etc
call doStuff2(str_to_use1, str_to_use2, str_to_use3)
end subroutine dostuffFirst
与前一种情况大致相同,但不必担心正确选择长度。