假设我有1000个函数定义如下
void func dummy1(int a);
void func dummy2(int a, int aa);
void func dummy3(int a, int aa, int aaa);
.
.
.
void func dummy1000(int a, int aa, int aaa, ...);
我想编写一个函数,它接受一个整数,n(n <1000)并调用第n个虚函数(如果是10,dummy10),只有n个参数(参数可以是任何整数,假设为0)需要。我知道这可以通过写一个包含1000个案例的switch case语句来实现。
在我看来,如果没有在运行时重新编译就无法实现这一点,因此像java,c,c ++这样的语言永远不会让这样的事情发生。
希望有一种方法可以做到这一点。如果是这样,我很好奇。
注意:这不是我将要使用的东西,我问的只是因为我的好奇心。
答案 0 :(得分:2)
在现代函数式语言中,您可以创建一个以列表作为参数的函数列表。这可以说可以解决你的问题,但它也可以说是作弊,因为它不是你的问题似乎暗示的静态类型实现。但是,当使用“手动”参数处理时,它几乎就是Python,Ruby或Perl等动态语言...
无论如何,以下是在Haskell中:它为n
函数(来自其第一个参数fs
)提供了第二个参数n
个副本的列表({{1} }),并返回结果。当然,您需要以某种方式将函数列表放在一起,但与switch语句不同,此列表将作为第一类参数重用。
x
当然,如果selectApplyFunction :: [ [Int] -> a ] -> Int -> Int -> a
selectApplyFunction fs x n = (fs !! (n-1)) (replicate n x)
dummy1 [a] = 5 * a
dummy2 [a, b] = (a + 3) * b
dummy3 [a, b, c] = (a*b*c) / (a*b + b*c + c*a)
...
myFunctionList = [ dummy1, dummy2, dummy3, ... ]
-- (myfunction n) provides n copies of the number 42 to the n'th function
myFunction = selectApplyFunction myFunctionList 42
-- call the 666'th function with 666 copies of 42
result = myFunction 666
大于函数数,或者函数无法处理列表,则会出现异常。请注意,它是糟糕的Haskell风格 - 主要是因为它滥用列表的方式(滥用)解决你的问题......
答案 1 :(得分:0)
不,你不对。大多数现代语言支持某种形式的反射,它允许您通过名称调用函数并将params传递给它。
答案 2 :(得分:0)
您可以在大多数现代语言中创建函数数组。 在伪代码中,
var dummy = new Array();
dummy[1] = function(int a);
dummy[2] = function(int a, int aa);
...
var result = dummy[whateveryoucall](1,2,3,...,whateveryoucall);
答案 3 :(得分:0)
在函数式语言中你可以这样做,在强类型语言中,比如Haskell,函数必须具有相同的类型,但是:
funs = [reverse, tail, init] -- 3 functions of type [a]->[a]
run fn arg = (funs !! fn) $ args -- applies function at index fn to args
答案 4 :(得分:0)
在面向对象语言中,您可以同时使用function objects和反射来实现您想要的效果。通过将适当的POJO(调用C stucts)传递给函数对象来解决可变参数数量的问题。
interface Functor<A,B> {
public B compute(A input);
}
class SumInput {
private int x, y;
// getters and setters
}
class Sum implements Functor<SumInput, Integer> {
@Override
public Integer compute(SumInput input) {
return input.getX() + input.getY();
}
}
现在想象一下,你有很多这些“仿函数”。您将它们收集在一个配置文件中(可能是一个XML文件,其中包含有关每个仿函数的元数据,使用方案,说明等...)并将列表返回给用户。
用户选择其中一个。通过使用反射,您可以看到所需的输入和预期输出。用户填写输入,并使用反射实例化仿函数类(newInstance()
),调用compute()
函数并获取输出。
添加新仿函数时,只需更改配置文件中的仿函数列表即可。