【问题标题】:Native Fortran type signature for "list of variable length strings"?“可变长度字符串列表”的本机 Fortran 类型签名?
【发布时间】:2020-03-17 04:09:00
【问题描述】:

在 Fortran 中,是否有任何方法可以声明“可分配数组的数组”,而不需要将可分配数组包装成派生类型?

我的主要用例是允许调用具有可变长度字符串数组的函数,即我正在寻找与文字匹配的类型签名

["Hello", &
 "World.",  &
 "How are you?"]

动机

在 Fortran 中,字符串本机表示为固定大小的字符数组,右侧用空格填充。字符串数组通常表示为(等长)字符数组的数组,我假设这是为了使它们表现得像字符矩阵。

然而,这也意味着做类似的事情

CALL mySubroutine(["Hello","World.","How are you?"])

将导致编译器错误,如

Error: Different CHARACTER lengths (5/4) in array constructor at (1)

通常建议的解决方法(参见例如Return an array of strings of different length in Fortran)是使用派生类型的数组,例如

TYPE string
   CHARACTER(LEN=:), ALLOCATABLE :: chars
END type string
! ...
CALL myStringSubroutine([string("Hello"), &
                         string("World."),  &
                         string("How are you?")])

但是,由于没有此类标准化的 string 类型,我更经常看到 API 使用本机支持的“解决方法”,例如使用固定大小的字符串,并在使用时对其进行修剪。在这种情况下,调用看起来像

CALL myFixedSubroutine(["Hello       ", &
                        "World.      ", &
                        "How are you?"])

虽然原则上这没有问题,但如果其中一个字符串比其他字符串长得多,它可能会变得笨拙且效率低下。它还对版本控制有影响,现在将 "... you?" 更改为 "... you??" 意味着必须更改其他行的填充,从而产生虚假差异。

(在 cmets 中,给出了至少自动化空白填充的建议。)

【问题讨论】:

  • Fortran 中没有本机列表类型。只有 Fortran 数组。数组不是列表。互联网上提供了派生列表类型的实现,甚至在这里也经常出现。
  • 另请注意,数组构造函数[character(135):: 'Hello', 'World.', 'How are you?'] 解决了您的一些问题。
  • @VladimirF 可能没有原生列表类型,但当不需要可变长度时,通常可以以相同的方式使用数组。我正在寻找的基本上归结为使用“数组数组”而不是“2 级数组”。虽然后者显然更适合矩阵性能,但前者通常更适合围绕计算的基础架构代码。
  • @kdb arrays of arrays 在这里也被多次处理。还有使用几乎相同的包装器的指针数组。只需将指针组件与字符组件切换即可。它真的是一样的,非常简单。 stackoverflow.com/questions/8900336/arrays-of-pointers 我看到你称其为解决方法,但通常情况下,这确实是要去做的事情。如果您已经知道,不确定问题是什么。
  • @VladimirF 包装器编写起来很简单,但它们使代码更难阅读,所以我试图找到一个不需要它们的解决方案。对于指针,虽然TYPE(string) 用于此类变量参数的性能会更高,但它在任何其他地方都会变得不那么有用,因为指针最终可能指向已释放的内存。我正在寻找改进静态检查能力的方法,所以使用POINTER 将是一个倒退。

标签: arrays string fortran


【解决方案1】:

不,没有办法禁止包装器类型。

该语言的一个基本概念是数组中的元素只能在值上有所不同。对象的分配状态不属于该对象的值。

(组件的分配状态是拥有该组件的对象的值的一部分。)

Fortran 标准的第 2 部分描述了可变长度的字符串类型。

【讨论】:

  • 您能否详细说明“基本概念”部分?我知道,为了提高数值性能,该语言将适当的 rank-N 数组放在前面和中心。但是我不明白,为什么这会排除创建可分配数组或指针数组的能力。 (除此之外:感谢参考to iso_varying_string,虽然我不明白为什么它是可选的。)
  • 基本操作如何工作?序列关联如何工作?
  • 当将数组视为“指针数组”而不是多维值数组时,序列关联可以正常工作。元素操作可以递归地应用于数组的最内层,尽管我可以看到这如何使实现变得更加复杂;但它有点忽略了一点:与多维数组相比,“指针数组”的使用场景会有很大不同,所以虽然元素操作会“很高兴”,但与避免使用相比,我几乎不会认为它们很重要临时包装器。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多