Julia 函数签名和子类型,特别是 String、ByteString
Julia function signatures and sub-types, specifically String, ByteString
(使用 Julia 0.3.11)
我无法正确地对我的一些代码进行类型注释,在初始版本中我们一直使用 ASCIIString
- 将任何字符串注释为 "avoid" 抽象类型,但让我们从示例开始,这可能与我在这里的一些讨论中看到的被称为 "triangular dispatch" 的内容有关:
# How to type annotate this (sortof "Dictionary with default)
function pushval!(dict, key, val)
key in keys(dict) ? push!(dict[key], val) : dict[key] = [val]
return dict
end
d1 = Dict{ASCIIString, Vector{Int}}()
d2 = Dict{String, Vector{Int}}()
pushval!(d1, "a", 1)
pushval!(d2, "a", 1)
好的(首先 - 如果有更惯用的方法来构造带有默认值的字典,在本例中是一个空数组,我很想听听)
所以现在,我尝试输入注释:
function pushval!{K, V} (dict::Dict{K, Vector{V}} , key, val)
更多的文档和工作。
但现在是更棘手的部分 - 我希望 'key' 是 K 的任何子类型,而 val - V 的任何子类型(对吗?)例如 - 我想制作一个字符串字典 - 这是一个抽象类型,但是使用具体的键- ASCIIString/ByteString/UTF8String,
我想我应该写以下内容之一:
function pushval!{K, V} (dict::Dict{K, Vector{V}} , key::KK <: K, val:: VV <: V)
function pushval!{K, V, KK <: K, VV <: V} (dict::Dict{K, Vector{V}} , key::KK, val::VV)
一个解决方案是在 ( ) 中建议的 'convert'.
但这整件事让我想知道我正在编写的 Julia 代码,当我实际尝试时,我已经开始编写一个系统 - 使用 String、FloatingPoint、Number 和此类抽象类型 运行它,我已经恢复将所有内容转换为具体类型只是为了现在 运行...
是否有推荐的代码库可供阅读以作为对惯用 Julia 代码的参考?
就像 Julia 的字典赋值运算符的实现一样。标准库中是否有一部分被认为可以作为参考?谢谢
虽然我不太喜欢这个解决方案(性能低下),但它会有所帮助:
function pushval!{K, V} (dict::Dict{K, Vector{V}} , key , val)
fun = function inner{tt1<:K,tt2<:V}(key::tt1,val::tt2)
key in keys(dict) ? push!(dict[key], val) : dict[key] = [val]
return dict
end
return fun(key,val)
end
# => pushval! (generic function with 1 method)
d1 = Dict{ASCIIString, Vector{Int}}()
# => Dict{ASCIIString,Array{Int32,1}} with 0 entries
d2 = Dict{String, Vector{Int}}()
# => Dict{String,Array{Int32,1}} with 0 entries
pushval!(d1, "a", 1)
# => Dict{ASCIIString,Array{Int32,1}} with 1 entry:
# "a" => [1]
pushval!(d2, "a", 1)
# => Dict{String,Array{Int32,1}} with 1 entry:
# "a" => [1]
我可以推荐看看 Julia Style Guide。有一些关于使用类型注释的建议。
对于您的情况,您根本不需要 pushval!
函数的类型注释。 Julia 将从 Dict
创建中获得足够的信息,并为 pushval!
个参数推断出适当的类型。
function pushval!(dict, key, val)
key in keys(dict) ? push!(dict[key], val) : dict[key] = [val]
return dict
end
d = Dict{String, Vector{Int} # Here is all annotations you need.
pushval!(d, "a", 1) # OK, "a" is ASCIIString which is subtype of AbstractString
pushval!(d, 1, 1) # ERROR, 1 is Int64 which is not subtype of AbstractString
我知道这只是您要求的一部分,但也许您觉得已经足够了。
你所说的 pushval!
可以使用 push!(get!(d1, "a", []), 1)
实现(尽管它将 return 附加到的字典值而不是字典本身)。如果你需要限制内部集合值的类型,你可以,例如,使用:
push!(get!(d1, "a", Number[]), 1)
如果您真的需要将其定义为函数,恐怕目前您无法按照您描述的方式定义类型。作为 to the question you referenced notes, Julia does not implement triangular dispatch yet, although it is targeted for 0.5.
(使用 Julia 0.3.11)
我无法正确地对我的一些代码进行类型注释,在初始版本中我们一直使用 ASCIIString
- 将任何字符串注释为 "avoid" 抽象类型,但让我们从示例开始,这可能与我在这里的一些讨论中看到的被称为 "triangular dispatch" 的内容有关:
# How to type annotate this (sortof "Dictionary with default)
function pushval!(dict, key, val)
key in keys(dict) ? push!(dict[key], val) : dict[key] = [val]
return dict
end
d1 = Dict{ASCIIString, Vector{Int}}()
d2 = Dict{String, Vector{Int}}()
pushval!(d1, "a", 1)
pushval!(d2, "a", 1)
好的(首先 - 如果有更惯用的方法来构造带有默认值的字典,在本例中是一个空数组,我很想听听)
所以现在,我尝试输入注释:
function pushval!{K, V} (dict::Dict{K, Vector{V}} , key, val)
更多的文档和工作。 但现在是更棘手的部分 - 我希望 'key' 是 K 的任何子类型,而 val - V 的任何子类型(对吗?)例如 - 我想制作一个字符串字典 - 这是一个抽象类型,但是使用具体的键- ASCIIString/ByteString/UTF8String,
我想我应该写以下内容之一:
function pushval!{K, V} (dict::Dict{K, Vector{V}} , key::KK <: K, val:: VV <: V)
function pushval!{K, V, KK <: K, VV <: V} (dict::Dict{K, Vector{V}} , key::KK, val::VV)
一个解决方案是在 (
但这整件事让我想知道我正在编写的 Julia 代码,当我实际尝试时,我已经开始编写一个系统 - 使用 String、FloatingPoint、Number 和此类抽象类型 运行它,我已经恢复将所有内容转换为具体类型只是为了现在 运行...
是否有推荐的代码库可供阅读以作为对惯用 Julia 代码的参考? 就像 Julia 的字典赋值运算符的实现一样。标准库中是否有一部分被认为可以作为参考?谢谢
虽然我不太喜欢这个解决方案(性能低下),但它会有所帮助:
function pushval!{K, V} (dict::Dict{K, Vector{V}} , key , val)
fun = function inner{tt1<:K,tt2<:V}(key::tt1,val::tt2)
key in keys(dict) ? push!(dict[key], val) : dict[key] = [val]
return dict
end
return fun(key,val)
end
# => pushval! (generic function with 1 method)
d1 = Dict{ASCIIString, Vector{Int}}()
# => Dict{ASCIIString,Array{Int32,1}} with 0 entries
d2 = Dict{String, Vector{Int}}()
# => Dict{String,Array{Int32,1}} with 0 entries
pushval!(d1, "a", 1)
# => Dict{ASCIIString,Array{Int32,1}} with 1 entry:
# "a" => [1]
pushval!(d2, "a", 1)
# => Dict{String,Array{Int32,1}} with 1 entry:
# "a" => [1]
我可以推荐看看 Julia Style Guide。有一些关于使用类型注释的建议。
对于您的情况,您根本不需要 pushval!
函数的类型注释。 Julia 将从 Dict
创建中获得足够的信息,并为 pushval!
个参数推断出适当的类型。
function pushval!(dict, key, val)
key in keys(dict) ? push!(dict[key], val) : dict[key] = [val]
return dict
end
d = Dict{String, Vector{Int} # Here is all annotations you need.
pushval!(d, "a", 1) # OK, "a" is ASCIIString which is subtype of AbstractString
pushval!(d, 1, 1) # ERROR, 1 is Int64 which is not subtype of AbstractString
我知道这只是您要求的一部分,但也许您觉得已经足够了。
你所说的 pushval!
可以使用 push!(get!(d1, "a", []), 1)
实现(尽管它将 return 附加到的字典值而不是字典本身)。如果你需要限制内部集合值的类型,你可以,例如,使用:
push!(get!(d1, "a", Number[]), 1)
如果您真的需要将其定义为函数,恐怕目前您无法按照您描述的方式定义类型。作为