正如您所观察到的,确实可以创建Val类型的实例,但它们与构造它们的"值"几乎没有关系.例如,
julia> 3 == Val{3}()
false
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
但是,您可以调度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
Run Code Online (Sandbox Code Playgroud)
您可以使用类型而不是实例编写相同的代码:
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
Run Code Online (Sandbox Code Playgroud)
后者对你的函数作者来说有点困难(你必须输入Type{}),但在调用者上稍微容易一点(你可以跳过()).一般惯例是采用后者,以便对来电者更好,但这只是一个惯例; 要么可以选择.
最后,这Val是一个有趣的技巧,有时它可以用来解决性能问题,但它也很容易误解它,确实会使性能变差.请参阅本手册的这些部分