提问人:blue_note 提问时间:12/17/2017 更新时间:12/18/2017 访问量:68
函数有没有像*接口*这样的概念?
Is there a concept like *interface* for functions?
问:
我有各种函数接受相同的参数并返回相同的类型。它们做类似的事情(例如,使用不同的近似方法进行集成),只是名称不同。我想强制所有变体具有相同的签名。
这可以通过将它们包装到类中来完成,但没有概念上的理由。那么,有没有类似于函数的概念呢?也就是说,有没有办法做类似的事情interface
abstract Double integration(Double[] xs, Double[] ys);
Double RiemmannIntegration implements integration(...) {...}
显然,这个问题只对函数是第一类对象的语言有意义(我最感兴趣的是python / javascript)。
答:
在 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中的参数所需的类型作为数组,并将生成的接口应用于定义的函数。您可能仍然需要将库用于效果,例如“None-able”参数,或者通过修改此代码来实现自己的效果。事实上,这个装饰器的优点是使您能够定义任意类型检查例程(否则可能会更好)。typing
typing
如果所有函数的键入要求完全相同,则可以删除最外层的装饰器并使用硬编码的 .arg_types
评论
typing
你要寻找的概念是函数的类型。具体来说,这是一种“更高级”的类型,因为它是一种类型,而不是一种值类型。
在像 Haskell 这样的语言中,你必须传递这样的函数参数。如果未显式命名类型,编译器将为您推断该类型。但是,如果您尝试传递接受不同类型的不同函数,则会出现编译错误。
C# 具有用于声明函数类型的特殊语法,称为委托类型。Java 8+ 具有函数式接口的概念,或者只有一种方法的接口,并且具有一些语言特性,可以更轻松地传递表示给定类型函数的对象。
在 JavaScript 和 Python 中,对象实际上没有接口,至少没有显式接口。但是,您可以实现的是协议,在这些协议中,您要求参数是接受某些参数并以某种方式运行的函数。Python 标准库中的一个很好的例子是函数的参数:它必须是一个接受要排序的可迭代对象中的一个项目并返回一个可比较对象用作排序键的函数。key
sorted()
评论
typing