在Julia中,可以指定可调用函数参数的参数和返回值吗



在Python中,您可以为传递给另一个函数(引用(的可调用函数指定参数和返回值。例如:

def foo(
bar: Callable[[str],int], # a function that takes a string as an argument and returns an int 
baz: List[str] # a list of strings
) -> List[int]: # returns a list of ints
return [bar(s) for s in baz]
foo(len,["hello","world!"]) # apply the len function to the list of strings
# [5, 6]

我如何在Julia中编写Callable[[str],int]的等价物?

Julia中没有这样做的机制。Julia和Python都没有静态地强制执行函数的类型签名。在Julia中,倾向于让函数参数尽可能通用,所以大多数时候,你还不如让函数以外的参数通用,比如:

foo(f, s) = map(f, s)

尽管有时人们会这样注释f论点:

foo(f::Union{Function, Type}, s) = map(f, s)

Type包含在并集中,因为并非所有可调用对象都是Function的子类型,例如,请参阅手册中的类似函数的对象。

可以对函数的输出类型进行注释,但实际所做的只是尝试将返回值转换为指定的输出类型,因此,如果函数没有返回已注释的类型,则可能会出现运行时转换错误。

输出类型的注释通常是多余的。考虑这个代码:

bar(x::Int)::Int = 2x

如果我们查看降低的代码,我们可以看到添加到代码中的额外类型转换:

julia> @code_lowered bar(42)
CodeInfo(
1 ─ %1 = Main.Int
│   %2 = 2 * x
│   %3 = Base.convert(%1, %2)
│   %4 = Core.typeassert(%3, %1)
└──      return %4
)

然而,在这种情况下,编译器足够聪明,可以计算出当输入是整数时,输出将是整数,并且不需要转换:

julia> @code_llvm bar(42)
;  @ REPL[1]:1 within `bar'
define i64 @julia_bar_788(i64) {
top:
; ┌ @ int.jl:87 within `*'
%1 = shl i64 %0, 1
; └
ret i64 %1
}

事实上,我们看到bar已经被简化为左比特移位操作。

julia> bar(42)
84
julia> 42 << 1
84

相关内容

  • 没有找到相关文章

最新更新