如何在 julia 中传递类型安全的函数

How to pass a function typesafe in julia

比方说,我想将一个函数传递给另一个函数:

function foo()
    return 0;
end
function bar(func)
    return func();
end
print(bar(foo));

但是你可以使函数类型安全:

function func(t::Int)
    print(t);
end
func(0);                 #produces no error
func("Hello world");     #produces an error

我没有发现,我是如何将两者结合起来的,也就是说,我如何显式定义 bar 的参数,如 func,使其成为一个函数,可能具有特定的输入/ 输出参数类型。

在此先感谢您的帮助。

函数的类型为 Function。您可以轻松查看:

julia> foo() = 1;

julia> T = typeof(foo)
typeof(foo)

julia> supertype(T)
Function

julia> foo isa Function
true

这不一定涵盖所有可调用类型,因为您可以将任何类型设为可调用:

julia> struct Callable end

julia> (::Callable)(x::Number) = x + one(x)

julia> callable = Callable()
Callable()

julia> callable(5)
6

julia> callable isa Function
false

如果我没理解错的话,您想确保传递的函数 return 是特定类型?最简单的事情就是在运行时输入 return 值:

julia> function f(func)
           val = func()::Int # Error if the return value is not of type Int
           return val
       end
f (generic function with 1 method)

julia> f(() -> 1)
1

julia> f(() -> 1.0)
ERROR: TypeError: in typeassert, expected Int64, got Float64
Stacktrace:
 [1] f(::var"#7#8") at ./REPL[5]:2
 [2] top-level scope at REPL[8]:1

或者您可以使用 FunctionWrappers.jl 包(它将转换为指定的 return 类型,如果无法转换则出错):

julia> using FunctionWrappers: FunctionWrapper

julia> function f(func::FunctionWrapper{Int,<:Tuple})
           val = func()
           return val
       end;

julia> function f(func)
           fw = FunctionWrapper{Int,Tuple{}}(func)
           return f(fw)
       end;

julia> f(() -> 1)
1

julia> f(() -> 1.0) # Can convert to Int
1

julia> f(() -> 1.2) # Can not convert to Int
ERROR: InexactError: Int64(1.2)