将Varargs输入与一个固定类型的元素配对

Mag*_*eek 4 julia

我可以构建以下内容:

foo(p::Pair...) = dostuff
Run Code Online (Sandbox Code Playgroud)

这适用于对列表.我想做以下事情:

foo{N}(p::Pair{Symbol,N}...) = dostuff
Run Code Online (Sandbox Code Playgroud)

其中每对的第一个条目是一个符号,但第二个条目是不受约束的.上面的构造要求所有第二个条目都是相同的类型,但我想允许任何第二个条目:

foo(:a=>1, :b=>"hi")
Run Code Online (Sandbox Code Playgroud)

有没有办法做到这一点?我是否需要使用第一个版本并在函数本身中强制执行参数类型并抛出错误?

Ste*_*ski 5

由于具有未指定的尾随类型参数的参数类型被视为抽象超类型,匹配指定的类型,因此该类型Pair{Symbol}匹配任何对,其中第一个参数Symbol与任何第二个参数匹配.因此,您可以像这样编写所需的方法签名:

foo(p::Pair{Symbol}...) = "pairs from symbols"
Run Code Online (Sandbox Code Playgroud)

如果要分配第二个类型参数而不是第一个参数,则无效.要实现这一点,您需要一个类型别名:

typealias Riap{B,A} Pair{A,B}

foo(p::Riap{Symbol}...) = "pairs to symbols"
Run Code Online (Sandbox Code Playgroud)

我们可以看到这两种方法的实际应用:

julia> foo(:a => 1.5, :b => "x")
"pairs from symbols"

julia> foo(1.5 => :a, "x" => :b)
"pairs to symbols"

julia> foo(:a => :b, :c => :d)
ERROR: MethodError: foo(::Pair{Symbol,Symbol}, ::Pair{Symbol,Symbol}) is ambiguous. Candidates:
  foo(p::Pair{A<:Any,Symbol}...) at REPL[5]:1
  foo(p::Pair{Symbol,B<:Any}...) at REPL[1]:1
 in eval(::Module, ::Any) at ./boot.jl:231
 in macro expansion at ./REPL.jl:92 [inlined]
 in (::Base.REPL.##1#2{Base.REPL.REPLBackend})() at ./event.jl:46

julia> foo()
ERROR: MethodError: foo( is ambiguous. Candidates:
  foo(p::Pair{A<:Any,Symbol}...) at REPL[5]:1
  foo(p::Pair{Symbol,B<:Any}...) at REPL[1]:1
 in eval(::Module, ::Any) at ./boot.jl:231
 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)