问题
I tried to rely on type inference for a function with signature:
proc mode(data: [?]int)
but the compiler said it could not resolve the return type (which is a warning in in itself I guess given there are only two return statements). I tried:
proc mode(data: [?]int): [?]int
but the compiler then said there was an internal error:
internal error: CAL0057 chpl Version 1.13.1.518d486
What is the correct way of specifying that the length of an array returned by a function can only be known at run time?
回答1:
If the domain/size of the array being returned cannot be described directly in the function prototype, I believe your best bet at present is to omit any description of the return type and lean on Chapel's type inference machinery to determine that you're returning an array (as you attempted). For instance, here is a procedure that reads in an array of previously unknown size and returns it:
proc readArrFromConsole() {
var len = stdin.read(int);
var X: [1..len] real;
for x in X do
x = stdin.read(real);
return X;
}
var A = readArrFromConsole();
writeln(A);
Running it and typing this at the console:
3 1.2 3.4 5.6
Generates:
1.2 3.4 5.6
Your question mentions multiple return statements, which opens up the question about how aggressively Chapel unifies types across distinct arrays. A simple example with multiple arrays of the same type (each with a unique domain, size, and bounds) seems to work:
proc createArr() {
var len = stdin.read(int);
if (len > 0) {
var X: [1..len] real;
return X;
} else {
var Y: [-1..1] real;
return Y;
}
}
var A = createArr();
writeln(A);
To understand why the compiler couldn't resolve the return type in your example may require more information about what your procedure body / return statements contained.
回答2:
I've come across this from time to time in recursive functions, in situations where omitting the return type fails; in this case I create a record
which is an array with its domain, e.g.:
record stringarray {
var D: domain(1);
var strs : [D] string;
}
and then define the recursive array to return one of those records:
proc repeats() : stringarray {
var reps: stringarray;
//...
for child in children do {
childreps = child.repeats();
for childrep in childreps do
reps.push_back(childrep);
}
//...
return reps;
}
来源:https://stackoverflow.com/questions/39387763/how-to-specify-a-return-of-an-array-of-unknown-size-in-chapel