我有各种函数接受相同的参数并返回相同的类型。他们做类似的事情(例如,使用不同的近似方法执行集成),并且仅在名称上有所不同。我想强制所有变体都有相同的签名。
可以通过将它们包装到类中来完成,但是没有概念上的理由。那么,是否存在类似abstract Double integration(Double[] xs, Double[] ys);
Double RiemmannIntegration implements integration(...) {...}
的函数概念?也就是说,有没有办法做类似
javax.naming.NameNotFoundException: com.ibm.mq.jms.MQConnectionFactory
at com.sun.jndi.fscontext.RefFSContext.getObjectFromBindings(RefFSContext.java:400)
at com.sun.jndi.fscontext.RefFSContext.lookupObject(RefFSContext.java:327)
at com.sun.jndi.fscontext.RefFSContext.lookup(RefFSContext.java:146)
at com.sun.jndi.fscontext.FSContext.lookup(FSContext.java:127)
at javax.naming.InitialContext.lookup(InitialContext.java:392)
at com.mercury.ws.jms.ConnectionManagerImpl.initialize(ConnectionManagerImpl.java:99)
at com.mercury.ws.jms.JMSSupportImpl.initialize(JMSSupportImpl.java:28)
at com.mercury.ws.jms.JMSBridge.init_jms(JMSBridge.java:154)
显然,这个问题只适用于函数是第一类对象的语言(我最感兴趣的是python / javascript)。
答案 0 :(得分:1)
您正在寻找的概念是该功能的类型。具体来说,这是一个更高级别的" type,因为它是一种类型而不是一种值。
在像Haskell这样的语言中,你必须传递像这样的函数的参数。如果您没有明确命名该类型,编译器将为您推断它。但是,如果您尝试传递接受不同类型的不同函数,那么您将收到编译错误。
C#有一种特殊的语法来声明一种函数类型,称为委托类型。 Java 8+具有功能接口的概念,或者只有一种方法的接口,并且具有一些语言特性,可以更容易地传递代表给定类型函数的对象。 / p>
在JavaScript和Python中,对象实际上没有接口,至少没有明确说明。但是你可以实现的是 protocols ,你要求参数是一个接受某些参数并以某种方式运行的函数。 Python标准库中的一个很好的例子是key
函数的sorted()
参数:它需要是一个函数,它接受要排序的一个iterable项并返回一个可比较的对象用作排序键。
答案 1 :(得分:0)
在python中,可以强制执行类型检查
def type_check_decorator(args_types):
def real_decorator(func):
def wrapper(*args):
# type checking
for i, (a, t) in enumerate(zip(args, args_types)):
if not isinstance(a, t):
raise ValueError('Type error on argument {}, should be {} but {} given'
.format(i, t, type(a)))
# execute real function
return func(*args)
return wrapper
return real_decorator
my_interface = type_check_decorator([int, int])
@my_interface
def func1(a, b):
return a + b
使用这个装饰器你可能有
func1(1, 2) # OK
func1(1.1, 2) # ValueError: Type error on argument 0, should be <type 'int'> but <type 'float'> given
要使用此装饰器,请将args_types中所需参数的类型作为数组,并将结果接口应用于您定义的函数。您可能仍然需要使用typing
库来获取诸如“无法”参数之类的效果,或者通过修改此代码来实现您自己的库。事实上,这个装饰器的优点是让你能够定义一个任意的类型检查例程(否则typing
会更好)。
如果您的所有功能的输入要求完全相同,您可以删除最外面的装饰器并使用硬编码的arg_types
。