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

时间:2016-06-22 16:09:34

标签: julia

我可以构建以下内容:

foo(p::Pair...) = dostuff

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

foo{N}(p::Pair{Symbol,N}...) = dostuff

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

foo(:a=>1, :b=>"hi")

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

1 个答案:

答案 0 :(得分:5)

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

foo(p::Pair{Symbol}...) = "pairs from symbols"

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

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

foo(p::Riap{Symbol}...) = "pairs to symbols"

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

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