我有一个像这样的嵌套字典
function_dict_1 = Dict(
:f => Dict(
:func1 => x -> x^2
)
)
我想调用一个强类型函数,它接收这个字典作为参数。
我的第一个想法是像这样输入:
dict_arg::Dict{Symbol, Dict{Symbol, <:Function}}
但是,我收到不匹配的函数调用错误。
我很困惑,因为它似乎可以与其他数据类型一起使用:
string_dict = Dict(
:s => Dict(
:string1 => "a"
)
)
typeof(string_dict) <: Dict{Symbol, Dict{Symbol, String}}
>> true
以及非嵌套的字典:
function_dict_2 = Dict(
:func1 => x -> x^2
)
typeof(function_dict_2) <: Dict{Symbol, <:Function}
>> true
我尝试过以下类型:
Dict{Symbol, Dict{Symbol, <:Function}}
Dict{Symbol, Dict{Symbol, Function}}
AbstractDict{Symbol, AbstractDict{Symbol, <:Function}}
AbstractDict{Symbol, AbstractDict{Symbol, Function}}
但这一切都没有起作用。
该变量的正确输入方式是什么?
您还可以使用显式通用参数来解决这个问题:
你可能想知道为什么这两个都有效,而 却
Dict{Symbol, Dict{Symbol, <:Function}}
不行;毕竟, 不是Dict{Symbol, Dict{Symbol, <:Function}}
和 一样吗Dict{Symbol, Dict{Symbol, F}} where F <: Function
? 不是,因为隐式泛型参数的作用域始终是{}
包含 的最内层<:
,所以Dict{Symbol, Dict{Symbol, <:Function}}
实际上与 相同Dict{Symbol, Dict{Symbol, F where F <: Function}}
。现在,除了元组之外,
T1 <: T2
并不意味着SomeType{T1} <: SomeType{T2}
。因此,即使typeof(function_dict_1).parameters[2]
是Dict{Symbol, var"#1#2"}
(其中是匿名var"#1#2"
函数类型的名称),并且Dict{Symbol, var"#1#2"} <: Dict{Symbol, <:Function}
(但是!(Dict{Symbol, var"#1#2"} <: Dict{Symbol, Function})
!),我们也没有。Dict{Symbol, Dict{Symbol, var"#1#2"}} <: Dict{Symbol, Dict{Symbol, <:Function}}
那么,为什么我上面给出的两个答案有效而
Dict{Symbol, Dict{Symbol, <:Function}}
无效呢? 因为隐式泛型参数的作用域是{}
包含的最内层<:Function
,所以外层dict 类型是具体类型,而不是UnionAll
。由于不完全
function_dict_1
是这种类型,所以它不能是它的子类型。现在,将其与其他类型的结果进行比较。为了使子类型化工作(元组除外),我们需要一个
UnionAll
或一个抽象类型作为最外层类型。简而言之,第一个
<:
是Dict{Symbol, <:Dict{Symbol, <:Function}}
必须的,才能让第二个<:
自己脱颖而出{}
,这样整个类型才能成为一个UnionAll
。