函数指针(function)
function类型作为一个函数指针,类似于C++里面的(void*) func,它可以作为一个函数的对象,通过function进行传递。 我们可以通过(: function_name, function_args... :)的形式可以定义一个函数指针 并可以以(*ptr)(...)的形式进行调用。
例如:
function f = (: printf, "%s" :); // 使用 '(:' 和 ':)' 来定义,带参数
(*f)("abc"); // 输出 "abc"
function func = (: sizeof :) // 使用 '(:' 和 ':)' 来定义,不带参数
int size = func.call_local("hello world") // size = 11
当然我们可以定义自己的函数,举个例子:
maxer.gs
//计算两个数值的最大值
public int maxer(int x, int y)
{
return x > y ? x : y;
}
void test()
{
int x = 102;
int y = 32;
function fun = (: maxer :);
int ans = fun.call_local(x, y);
write(ans);
}
test();
上面函数执行完之后会输出x和y中的最大值,也就是102
函数指针的参数域(arg domain)
顾名思义,函数指针的参数域是指函数指针拥有的参数变量所在的域;
-
函数指针不带有参数变量时,参数域取决于函数原型是不是parallel
-
原型为parallel的,参数域为nil
-
原型为非parallel的,参数域为函数指针的owner(ob instance)所在的域
- 可以使用function.info().object查看函数指针的owner
f1.gs//
void create()
{
}
public void say()
{
}
public parallel void yell()
{
}test.gs#pragma parallel
import .f1;
void create()
{
}
public void test()
{
object ob = new_object(f1, domain.create());
// 对象的域
printf("ob domain: %O\n", ob.get_domain());
// 定义一个不带参数变量的函数指针: 函数原型为parallel
function f1 = (: ob.yell :);
printf("f1 arg domain: %O\n", f1.get_arg_domain());
// 定义一个不带参数变量的函数指针: 函数原型为非parallel
function f2 = (: ob.say :);
printf("f2 arg domain: %O\n", f2.get_arg_domain());
printf("f2 ob instance: %O\n", f2.info().object);
printf("f2 ob instance domain: %O\n", f2.info().object.get_domain());
}import test;
test.test();输出结果在此:
ob domain: domain[13:v1]d3
f1 arg domain: nil
f2 arg domain: domain[13:v1]d3
f2 ob instance: object[34:v2]/f1.gs
f2 ob instance domain: domain[13:v1]d3
-
-
函数指针带有参数变量时,参数域取决于参数列表中的参数类型
-
参数列表中拥有非read only的buffer/array/map/function参数时,参数域就是该参数所在的域
f1.gs//
void create()
{
}
public void say()
{
}
public parallel void yell(...)
{
}test.gs//
#pragma parallel
import .f1;
void create()
{
}
public void test()
{
object ob = new_object(f1, domain.create());
// 参数域中不带有非read only的buffer/array/map/function参数
int a1 = 1;
string a2 = "2";
map a3 = {};
array a4 = [];
printf("this domain: %O\n", this_domain());
// 带了buffer/array/map/function参数
// 参数域就是参数所在的域(也就是当前域 this_domain())
function f = (: ob.yell, a1, a2, a3, a4 :);
printf("f arg domain: %O\n", f.get_arg_domain());
}import test;
test.test();this domain: domain[0:v1]zero
f arg domain: domain[0:v1]zero -
参数列表中不拥有非read only的buffer/array/map/function参数时,参数域和该函数指针不带有参数变量时是一样的
f1.gs//
void create()
{
}
public void say()
{
}
public parallel void yell(...)
{
}test.gs
#pragma parallel
import .f1;
void create()
{
}
public void test()
{
object ob = new_object(f1, domain.create());
// 参数域中不带有非read only的buffer/array/map/function参数
int a1 = 1;
string a2 = "2";
map a3 = make_readonly({});
array a4 = make_readonly([]);
// 这里:通过类型转换获得的buffer是readonly的
buffer a5 = (buffer) "abc";
// 带了一堆非read only的buffer/array/map/function参数
// 参数域和不带参数相同
function f = (: ob.yell, a1, a2, a3, a4, a5 :);
printf("f arg domain: %O\n", f.get_arg_domain());
function nf = (: ob.yell :);
printf("nf arg domain: %O\n", nf.get_arg_domain());
}import test;
test.test();输出在此:
f arg domain: nil
nf arg domain: nil
-
改变函数指针的参数域
-
未绑定参数域的函数指针可以通过一些方法来绑定参数域
-
function.bind_arg_domain: 直接将函数指针绑定到指定的参数域中
test.gs#pragma parallel
void create()
{
}
public void test()
{
// 此时没有绑定参数域
function f = () {};
printf("f arg domain 1: %O\n", f.get_arg_domain());
// 绑定到指定的参数域上
domain d = domain.create();
f.bind_arg_domain(d);
printf("f arg domain 2: %O\n", f.get_arg_domain());
}import test;
test.test();输出在此:
f arg domain 1: nil
f arg domain 2: domain[11:v1]d1 -
function.append_arg_arr/function.append_arg:通过增加函数指针的非read only的buffer/array/map/function参数绑定参数域
test.gs
#pragma parallel
void create()
{
}
public void test()
{
// 此时没有绑定参数域
function f = () {};
printf("f arg domain 1: %O\n", f.get_arg_domain());
// 为函数指针增加一个buffer/array/map/function类型参数绑定参数域
array a1 = [];
f.append_arg(a1);
printf("f arg domain 2: %O\n", f.get_arg_domain());
// 此时没有绑定参数域
function f2 = () {};
printf("f2 arg domain 1: %O\n", f2.get_arg_domain());
// 为函数指针增加一组buffer/array/map/function类型参数绑定参数域
array arr = [ {}, [] ];
f2.append_arg_arr(arr);
printf("f2 arg domain 2: %O\n", f2.get_arg_domain());
}
-