【问题标题】:How to pass a function typesafe in julia如何在 Julia 中传递类型安全的函数
【发布时间】:2020-04-10 23:42:34
【问题描述】:

假设我想将一个函数传递给另一个函数:

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,可能具有某些输入/输出参数类型。

提前感谢您的帮助。

【问题讨论】:

  • 上次我检查时,这些在 Julia 中是不可能的,但已经有几年了,所以现在可能是。
  • 感谢@setholopolus 提供的信息。我会等待其他答案。

标签: functional-programming julia typesafe


【解决方案1】:

函数的类型为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

【讨论】:

  • 是的,但是……你能指定函数的参数和返回类型吗?
  • 谢谢你这么傻。很抱歉之前没有尝试过。
【解决方案2】:

如果我对您的理解正确,您想确保传递的函数返回特定类型吗?最简单的方法是在运行时对返回值进行类型断言:

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 包(它将转换为指定的返回类型,如果无法转换则错误):

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)

【讨论】:

  • 那么语言中没有办法指定被传递函数的参数和返回类型?
  • 嗯,我看到了两点。当您定义一个函数时,将一个数组应用于该函数 n 次,并且该数组为空,那么,当该函数返回另一种类型时,将不会有错误,但应该有。此外,函数的定义应该始终在函数附近,而不是在函数的每个应用程序中。但是,感谢您提供的代码。哈哈我想接受你们俩。
猜你喜欢
  • 1970-01-01
  • 2019-08-07
  • 2018-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多