函数返回关联数组

时间:2018-10-31 06:08:10

标签: chapel

如何让函数在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 ...)

1 个答案:

答案 0 :(得分:4)

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

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中的数组和域具有 runtime 关系,并且数组的类型包括 runtime 域。因此,尽管您发布的代码可能有一天的工作时间,但通常来说,指定一种数组类型需要指定一个在运行时可用的域。

假设您希望在所有返回的关联数组中共享一个域(即一组密钥),则可以执行以下操作:

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类型来简化此类用例并为地图提供更熟悉的界面。另外,如果没有其他数组共享,则添加到关联域的规则很可能会消失。