首页 > 解决方案 > 函数返回一个关联数组

问题描述

如何让函数在 Chapel 中返​​回关联数组?这是自然的,但似乎不起作用:

type keys = domain(int);
type arr = [keys] int;

proc factor(q): arr {
...
}

我得到的错误输出是:

error: unresolved call 'chpl__ensureDomainExpr(type DefaultAssociativeDom(int(64),true))'
$CHPL_HOME/modules/internal/ChapelArray.chpl:642: note: candidates are: chpl__ensureDomainExpr(const ref x: domain)
$CHPL_HOME/modules/internal/ChapelArray.chpl:649: note:                 chpl__ensureDomainExpr(x ...)

标签: chapel

解决方案


这是一个执行此操作的工作程序:

proc returnsAssocArray() {
  var AssocDom:domain(int);
  var AssocArray:[AssocDom] int;
  AssocArray[1] = 100;
  return AssocArray;
}

var A = returnsAssocArray();
for (key,value) in zip(A.domain, A) {
  writeln("A[", key, "] = ", value);
}

以上是我会使用的模式,并且可能会做你想要的。

请注意,Chapel 中的数组和域具有运行时关系,并且数组的类型包括运行时域。因此,虽然您发布的代码有一天可能会起作用,但一般来说,要指定一个数组类型,需要指定一个在运行时可用的域。

假设您希望在所有返回的关联数组中共享一个域(也就是一组键),您可以这样做:

var AssocDom:domain(int);
AssocDom += 1; // add index 1 to the associative domain
type AssocArrayType = [AssocDom] int;

proc returnsAssocArray(): AssocArrayType {
  var AssocArray:AssocArrayType;
  AssocArray[1] = 100;
  return AssocArray;
}

var A = returnsAssocArray();
for (key,value) in zip(A.domain, A) {
  writeln("A[", key, "] = ", value);
}

但是,如果returnsAssocArray想添加2到域中(比如说),事情可能不会像你期望的那样工作:

  • 添加2到 AssocDom 将调整在该域上创建的任何其他数组的大小
  • AssocArray[2] = 100当没有其他阵列共享该域时,才会添加到域中。

未来版本的 Chapel 很可能会有一种Map类型来简化此类用例并提供更熟悉的地图界面。此外,如果没有其他数组共享它,则添加到关联域的规则很可能会消失。


推荐阅读