我可以在Julia中拥有值类型的实例吗?
当我尝试在REPL控制台上输入isa(3, Val{3})
时,它会返回false
。
那么three = Val{3}()
给了我什么?
答案 0 :(得分:7)
正如您所观察到的,确实可以创建Val
类型的实例,但它们与构造它们的“值”几乎没有关系。例如,
julia> 3 == Val{3}()
false
Val
类型(或Val
个实例)实际上只有一个目的:将信息传递给Julia的编译器,该编译器可以看到类型但通常不是实例。例如,您无法调度特定值的整数:
julia> check_for_three(x::Int) = false
check_for_three (generic function with 1 method)
julia> check_for_three(x::3) = true
ERROR: ArgumentError: invalid type for argument x in method definition for check_for_three at REPL[3]:1
in eval(::Module, ::Any) at ./boot.jl:234
in macro expansion at ./REPL.jl:92 [inlined]
in (::Base.REPL.##1#2{Base.REPL.REPLBackend})() at ./event.jl:46
但是,您可以使用Val
类型发送:
julia> check_for_three_val{N}(::Val{N}) = false
check_for_three_val (generic function with 1 method)
julia> check_for_three_val(::Val{3}) = true
check_for_three_val (generic function with 2 methods)
julia> check_for_three_val(Val{2}())
false
julia> check_for_three_val(Val{3}())
true
您可以使用类型而不是实例编写相同的代码:
julia> check_for_three_valtype{N}(::Type{Val{N}}) = false
check_for_three_valtype (generic function with 1 method)
julia> check_for_three_valtype(::Type{Val{3}}) = true
check_for_three_valtype (generic function with 2 methods)
julia> check_for_three_valtype(Val{2})
false
julia> check_for_three_valtype(Val{3})
true
后者对你的函数作者来说有点困难(你必须输入Type{}
)但在调用者上稍微容易一些(你可以跳过()
)。一般惯例是采用后者,以便对来电者更好,但这只是一个惯例;要么可以选择。
最后,Val
是一个有趣的技巧,有时它可以用来解决性能问题,但它也很容易误解它,确实会使性能变差。请参阅手册的这些部分