在 Julia 的嵌套字典中键入匿名函数

问题描述 投票:0回答:1

我有一个像这样的嵌套字典

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}}

这一切都不起作用。

输入该变量的正确方法是什么?

julia anonymous-function typing
1个回答
0
投票
function_dict_1::Dict{Symbol, <:Dict{Symbol, <:Function}}

您还可以使用显式通用参数来解决此问题:

function_dict_1::Dict{Symbol, Dict{Symbol, F}} where F <: 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})
!),我们确实 not 有那个
Dict{Symbol, Dict{Symbol, var"#1#2"}} <: Dict{Symbol, Dict{Symbol, <:Function}}

那么为什么我上面给出的两个答案有效,而

Dict{Symbol, Dict{Symbol, <:Function}}
却不起作用?因为隐式泛型参数的作用域是包含
{}
的最里面
<:Function
,所以 outer 字典类型是具体类型,而不是
UnionAll

julia> dump(Dict{Symbol, Dict{Symbol, <:Function}})
Dict{Symbol, Dict{Symbol, <:Function}} <: AbstractDict{Symbol, Dict{Symbol, <:Function}}
  slots::Memory{UInt8}
  keys::Memory{Symbol}
  vals::Memory{Dict{Symbol, <:Function}}
  ndel::Int64
  count::Int64
  age::UInt64
  idxfloor::Int64
  maxprobe::Int64

由于

function_dict_1
不是完全这种类型,所以它不能是它的子类型。

现在,将其与我们得到的其他类型进行比较。为了使子类型起作用(元组除外),我们需要

UnionAll
或抽象类型作为最外层类型。

julia> dump(Dict{Symbol, <:Function})
UnionAll
  var: TypeVar
    name: Symbol #s66
    lb: Union{}
    ub: Function <: Any
  body: Dict{Symbol, var"#s66"<:Function} <: AbstractDict{Symbol, var"#s66"<:Function}
    slots::Memory{UInt8}
    keys::Memory{Symbol}
    vals::Memory{var"#s66"}
    ndel::Int64
    count::Int64
    age::UInt64
    idxfloor::Int64
    maxprobe::Int64

julia> dump(Dict{Symbol, Dict{Symbol, F where F <: Function}})
Dict{Symbol, Dict{Symbol, Function}} <: AbstractDict{Symbol, Dict{Symbol, Function}}
  slots::Memory{UInt8}
  keys::Memory{Symbol}
  vals::Memory{Dict{Symbol, Function}}
  ndel::Int64
  count::Int64
  age::UInt64
  idxfloor::Int64
  maxprobe::Int64

julia> dump(Dict{Symbol, Dict{Symbol, F}}  where F <: Function)
UnionAll
  var: TypeVar
    name: Symbol F
    lb: Union{}
    ub: Function <: Any
  body: Dict{Symbol, Dict{Symbol, F<:Function}} <: AbstractDict{Symbol, Dict{Symbol, F<:Function}}
    slots::Memory{UInt8}
    keys::Memory{Symbol}
    vals::GenericMemory{:not_atomic, Dict{Symbol, F<:Function}, Core.AddrSpace{Core}(0x00)}
    ndel::Int64
    count::Int64
    age::UInt64
    idxfloor::Int64
    maxprobe::Int64

julia> dump(Dict{Symbol, <:Dict{Symbol, <:Function}})
UnionAll
  var: TypeVar
    name: Symbol #s67
    lb: Union{}
    ub: UnionAll
      var: TypeVar
        name: Symbol #s68
        lb: Union{}
        ub: Function <: Any
      body: Dict{Symbol, var"#s68"<:Function} <: AbstractDict{Symbol, var"#s68"<:Function}
        slots::Memory{UInt8}
        keys::Memory{Symbol}
        vals::Memory{var"#s68"}
        ndel::Int64
        count::Int64
        age::UInt64
        idxfloor::Int64
        maxprobe::Int64
  body: Dict{Symbol, var"#s67"<:(Dict{Symbol, <:Function})} <: AbstractDict{Symbol, var"#s67"<:(Dict{Symbol, <:Function})}
    slots::Memory{UInt8}
    keys::Memory{Symbol}
    vals::Memory{var"#s67"}
    ndel::Int64
    count::Int64
    age::UInt64
    idxfloor::Int64
    maxprobe::Int64

julia> 
© www.soinside.com 2019 - 2024. All rights reserved.