gpt4 book ai didi

julia - Julia 中推断的类型差异

转载 作者:行者123 更新时间:2023-12-03 13:53:20 26 4
gpt4 key购买 nike

我正在尝试从 Python 中学习 Julia,我在 exercism.io 上发现了一段有趣的代码。 .用户做了一个优雅的技巧来创建包含函数的元组,因为它们是 Julia 中的一流对象。建立在我想尝试一些东西的基础上。

假设我有一个列表:

my_list = zip(0:3, ["wink", "double blink", "close your eyes", "jump"]) |> collect

我想创建一个由 2 元素元组组成的列表,其中第二个元素是一个函数:
codes = [(i, x -> push!(x,j)) for (i,j) in my_list]
append!(codes, (4, reverse!))

代码无法运行。检查 REPL 中的签名我意识到上面的第一行生成了一个带有签名的列表: 4-element Array{Tuple{Int64,var"#68#70"{String}},1}:
而如果我像在 linked code 中那样手动执行该程序:
    codes = 
[ (0, i -> push!(i, "wink"))
, (1, i -> push!(i, "double blink"))
, (2, i -> push!(i, "close your eyes"))
, (3, i -> push!(i, "jump"))
, (4, reverse!)]

我得到正确的类型: 5-element Array{Tuple{Int64,Function},1} .我无法理解差异以及为什么我尝试做的不是有效代码。

最佳答案

首先请注意,您应该使用 push!不是 append!在向量的末尾添加一个元素( append! 将集合的元素附加到另一个集合)。现在我将专注于主要问题,假设您会使用 push!在你的代码中。
code的所有元素具有相同的类型:

julia> typeof.(codes)
4-element Array{DataType,1}:
Tuple{Int64,var"#4#6"{String}}
Tuple{Int64,var"#4#6"{String}}
Tuple{Int64,var"#4#6"{String}}
Tuple{Int64,var"#4#6"{String}}

julia> unique(typeof.(codes))
1-element Array{DataType,1}:
Tuple{Int64,var"#4#6"{String}}

甚至更多 - 这种类型是具体的:
julia> isconcretetype.(typeof.(codes))
4-element BitArray{1}:
1
1
1
1

(这意味着事情将变得稳定和快速,这很好)

在这种情况下,推导式将此类型设置为 eltype的结果向量。

问题在于 (4, reverse!)元组有不同的类型:
julia> typeof((4, reverse!))
Tuple{Int64,typeof(reverse!)}

所以你不能把它添加到 codes向量,即:
julia> push!(codes, (4, reverse!))
ERROR: MethodError: Cannot `convert` an object of type typeof(reverse!) to an object of type var"#4#6"{String}

现在怎么解决?设置合适的 eltypecodes像这样创建时的向量:
julia> codes = Tuple{Int, Function}[(i, x -> push!(x,j)) for (i,j) in my_list]
4-element Array{Tuple{Int64,Function},1}:
(0, var"#7#8"{String}("wink"))
(1, var"#7#8"{String}("double blink"))
(2, var"#7#8"{String}("close your eyes"))
(3, var"#7#8"{String}("jump"))

julia> push!(codes, (4, reverse!))
5-element Array{Tuple{Int64,Function},1}:
(0, var"#7#8"{String}("wink"))
(1, var"#7#8"{String}("double blink"))
(2, var"#7#8"{String}("close your eyes"))
(3, var"#7#8"{String}("jump"))
(4, reverse!)

一切都会按预期工作。

让我举一个同样问题的更简单的例子,以便更清楚地看到问题:
julia> x = [i for i in 1:3]
3-element Array{Int64,1}:
1
2
3

julia> eltype(x)
Int64

julia> push!(x, 1.5)
ERROR: InexactError: Int64(1.5)
Stacktrace:
[1] Int64 at ./float.jl:710 [inlined]
[2] convert at ./number.jl:7 [inlined]
[3] push!(::Array{Int64,1}, ::Float64) at ./array.jl:913
[4] top-level scope at REPL[55]:1

julia> x = Float64[i for i in 1:3]
3-element Array{Float64,1}:
1.0
2.0
3.0

julia> push!(x, 1.5)
4-element Array{Float64,1}:
1.0
2.0
3.0
1.5

append!会像这样工作(继续最后一个例子):
julia> append!(x, [2.5, 3.5])
6-element Array{Float64,1}:
1.0
2.0
3.0
1.5
2.5
3.5

关于julia - Julia 中推断的类型差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61749318/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com