在众多编程语言中,在函数的参数中进行函数的传递,都能极大地提高编程的效率。但是,不同的语言有不同的风格和实现方式,在Matlab中是通过传递函数的句柄来实现的。
1 Why
在讲述具体问题之前,我们来思考一下为什么要传递函数呢?请看下面这个例子:
有一天老板告诉我们,我需要一个函数,用来从csv文件中读取数据,你赶紧交出来吧,于是按照老板的要求,写出了这样一个函数:
function result = read_from_csv(path)
result = csvread(path);
end
写完这个函数之后,老板又说了,读取的数据要更新到GUI页面上,你调用一下updateGUI函数(暂时不用管updateGUI的具体实现,你可以理解为这是其他人写好的一个API)吧。于是新版的函数变成了下面这个样子:
function result = read_from_csv(path)
result = csvread(path);
updateGUI(result);
end
老板看了你新写的函数,感觉还是挺满意的,不过作为老板不提些意见总是不科学的,于是老板又说了:“小盆友,做的不错,可是我们的产品又需要新功能了,就是要把你读取出的数据做一个转置,你赶紧写吧”。
这时候你就要思考了,老板要对result进行转置,当然我们可以这样写:
function result = read_from_csv(path)
result = csvread(path)';
updateGUI(result);
end
但是如果老板在此基础上又提出了新的要求该怎么办呢,比如把result中的所有0元素替换为1,是不是就要重新修改了呢?因此,为了更好的灵活处理,我们可能就需要把这种对result进行处理的操作,封装为一个函数,然后通过参数传递进来:
function result = read_from_csv(path, funcPreprocess)
result = csvread(path)';
result = funcPreprocess(result);
updateGUI(result);
end
这样一来,不管老板提什么样的要求,你都可以灵活地修改传递的函数即可,而不需要对read_from_csv
进行修改了。
此时怎么传递函数呢,就是需要用我们之前提到的传递函数句柄了。
2 传递函数句柄
传递函数句柄的方式其实非常简单,主要有以下三种方式:
2.1 直接加@
句柄定义方式如下所示:
<handle name> = @<function name>;
例如
f = @sin;
r = f(1:100);
如果需要固定部分参数,可以这样
f = @(y)plot(y, sin(y));;
r = f(0:0.1:2*pi);
2.2 str2func函数
f2 = str2func('plot');
f2(0:0.1:2*pi, sin(0:0.1:2*pi));
2.3 匿名函数
handle = @(arglist)anonymous_function
例如网上最常见的那个例子:
f3 = @(x, y)x.^2 + y.^2;
以上就是关于在Matlab函数的参数中,传递函数的一点小小心得,目前还没想明白一个,就是如何直接传递值本身,也就是如果不在funcPreprocess传递任何函数的时候,如何在内部生成一个直通函数,来避免编写if...else...,如果有哪位大神知道的话,望不吝赐教。
网友评论