假设我正在生成元组,我想在它们出现时将它们连接起来。我该怎么做?以下内容执行逐元素添加:
如果ts = ("foo", "cat")
,则t = ("bar", "dog")
ts += t
给ts = ("foobar", "catdog")
,
但我真正想要的是ts = (("foo","cat"),("bar","dog"))
.
所以我想第一个问题是"Chapel 是否支持元组连接?",然后是"是否有二进制运算符/函数?",然后是"如果没有,有什么好方法?",最后是"如果你知道更好的生活方式,让我的生活更轻松"。
请按顺序回答问题。
我感谢您的帮助!!
第一个问题是"Chapel 支持元组连接吗?
我相信这里的答案是否定的,原因如下:(1)Chapel变量具有在其生命周期内无法更改的单个静态类型,以及(2)元组的类型定义为其静态元素数以及每个元素的类型。 因此,鉴于您的变量ts
ts = ("foo", "cat")
它的类型是2*string
("字符串的 2 元组"),这将阻止它能够存储值(("foo","cat"),("bar","dog"))
,因为它的类型是2*(2*string)
("2 元组字符串")。 因此,虽然这两个元组具有相同数量的元素 (2),但它们的元素类型不同("字符串"与"字符串的 2 元组"),因此不是同一类型(不兼容)。
"它有二进制运算符/函数吗?">
由于上述原因,没有。
然后"如果没有,有什么好方法可以做到?
我想到了几件事,但根据您的具体情况可能会有所帮助,也可能没有帮助。 与其尝试重新分配ts
,不如创建一个新的元组,
const ts2 = (ts, t);
你甚至可以在例程中递归地执行此操作,尽管如果元组增长到任何重要的长度,这最终可能会放大你的代码大小(因为每次调用函数都会生成一个不同类型和唯一代码的元组)。
从我在你的问题中看到的,我认为你可能想使用元组列表或元组的一维数组(向量)。 下面是基于列表的方法:
use List;
var listOfTups: list(2*string);
listOfTups.append(("foo", "cat"));
listOfTups.append(("bar", "dog"));
writeln(listOfTups);
下面是一种基于阵列的方法:
var arrOfTups: [1..0] 2*string;
arrOfTups.push_back(("foo", "cat"));
arrOfTups.push_back(("bar", "dog"));
writeln(arrOfTups);
在两者中,我会推荐基于数组的方法,因为数组在 Chapel 中更加一流和强大(它们享有语法支持,允许数据并行,支持标量函数和运算符的推广等),而列表只是一个方便的库。
最后是"如果你知道更好的生活方式,让我的生活更轻松"。
如果您不知道,我可以想到的另一件相关事情是,Chapel 中的"varargs"函数有效地将这些参数转换为元组。 所以给定:
proc myFunc(x...) {
writeln(x.type:string);
}
myFunc(("foo", "cat"), ("bar", "dog"));
输出为:
2*2*string