gpt4 book ai didi

Julia - 创建 Union{Nothing,String} 与 Union{Nothing,Bool} 的矩阵

转载 作者:行者123 更新时间:2023-12-04 16:36:34 26 4
gpt4 key购买 nike

在我的程序中,我想用 Nothing 初始化一堆矩阵,然后如果满足某些条件,将单个元素更改为 Bool 类型的值或 String

这在我初始化时工作正常

Array{Union{Nothing,Bool},2}(undef,5,5)

产生的东西看起来像

5×5 Matrix{Union{Nothing, Bool}}:
nothing nothing nothing nothing nothing
nothing nothing nothing nothing nothing
nothing nothing nothing nothing nothing
nothing nothing nothing nothing nothing
nothing nothing nothing nothing nothing

但是当我初始化时不是

Array{Union{Nothing,String},2}(undef,5,5)

这给了我

5×5 Matrix{Union{Nothing, String}}:
#undef #undef #undef #undef #undef
#undef #undef #undef #undef #undef
#undef #undef #undef #undef #undef
#undef #undef #undef #undef #undef
#undef #undef #undef #undef #undef

现在我可以将第二个数组中的值更改为 String 以便我得到

5×5 Matrix{Union{Nothing, String}}:
#undef #undef #undef #undef #undef
#undef #undef #undef #undef #undef
#undef #undef #undef #undef "Look"
#undef #undef #undef #undef #undef
#undef #undef #undef #undef #undef

但是当我有第二个大数组构造为

Array{Union{Nothing, Bool, String}}(undef,10,5)

看起来像

10×5 Matrix{Union{Nothing, Bool, String}}:
#undef #undef #undef #undef #undef
#undef #undef #undef #undef #undef
#undef #undef #undef #undef #undef
#undef #undef #undef #undef #undef
#undef #undef #undef #undef #undef
#undef #undef #undef #undef #undef
#undef #undef #undef #undef #undef
#undef #undef #undef #undef #undef
#undef #undef #undef #undef #undef
#undef #undef #undef #undef #undef

我可以非常愉快地将前 5 行分配给由 NothingBool 构造的第一个数组,但我不能分配给由 Nothing 构造的第二个矩阵#undef/nothingString。相反,我得到了这个错误

UndefRefError: access to undefined reference

最初我认为这与从类型 Nothing#undefString 的转换有关,但我似乎能够做到这是当我在上面分配单个字符串时。

有什么想法吗?

最佳答案

首先让我从建议开始,该做什么。

一般来说,最好按以下方式创建矩阵:

julia> Array{Union{Nothing,String},2}(nothing,5,5)
5×5 Matrix{Union{Nothing, String}}:
nothing nothing nothing nothing nothing
nothing nothing nothing nothing nothing
nothing nothing nothing nothing nothing
nothing nothing nothing nothing nothing
nothing nothing nothing nothing nothing

通过这种方式,您可以确保它们被正确初始化。

现在解释你观察到的东西。 #undef 相对于 nothing 不是一个值。这意味着矩阵中的给定单元格未连接到任何值。你不能从这样的单元格中读取。您必须先写入它才能读取它:

julia> x = Vector{String}(undef, 3)
3-element Vector{String}:
#undef
#undef
#undef

julia> x[1]
ERROR: UndefRefError: access to undefined reference
Stacktrace:
[1] getindex(A::Vector{String}, i1::Int64)
@ Base .\array.jl:801
[2] top-level scope
@ REPL[6]:1

julia> x[1] = "a"
"a"

julia> x
3-element Vector{String}:
"a"
#undef
#undef

julia> x[1]
"a"

你可能会问为什么对于 Union{Bool, Nothing} 元素类型你得到一个数组中的值,而对于 Union{String, Nothing} code> 你确实得到了 #undef,即没有你可以读取的值。

答案是在 Julia 中有两种类型:

  • bits 类型,isbitstype 函数返回 true;这些数据是不可变的,不包含对其他值的引用;此类数据的一个示例是 Bool
  • 非位类型,它要么是可变的,要么包含引用;此类数据的一个示例是 String(从技术上讲,字符串表示为对存储字符串内容的内存中某个位置的引用)

如你所见:

julia> isbitstype(Bool)
true

julia> isbitstype(String)
false

现在 - 如果您的数组要存储一个位类型(或它们的联合),那么它会直接存储它,所以总会有一些值(不能保证它会是什么值,但您知道您会得到一个值) ,例如:

julia> Matrix{Int}(undef, 5, 5)
5×5 Matrix{Int64}:
260255120 260384864 260235344 260254240 0
260254240 260235344 260235344 260255120 0
261849744 260235344 260235344 260235344 0
260465792 260465440 260464224 260235344 0
260235344 260235344 260235344 260235344 0

如您所见,我们在其中存储了一些值,但未定义这些值是什么。

另一方面,如果您的数组要存储非位类型,它实际上存储对值的引用。这意味着当您在不初始化的情况下创建此类值的数组时,您会得到 #undef - 这意味着在此单元格中没有对有效值的引用。

只是为了向您展示它与字符串没有直接关系,让我向您展示例如String7 类型(例如由 CSV.jl 导出),它是位类型的固定宽度字符串(最大宽度为 7 个字节)。观察差异:

julia> using CSV

julia> isbitstype(String7)
true

julia> Matrix{String7}(undef, 5, 5)
5×5 Matrix{String7}:
"\0\0\0\0\x0f\x86_\x10\0\0\0\0\0\0\0\0" "\0\0\0\0\x0f\x86_\x10\0\0\0\0\0\0\0\0" "\0\0\0\0\x0f\x86_\x10\0\0\0\0\0\0\0\0" … "\0\0\0\0\x0f\x86_\x10\0\0\0\0\0\0\0\0"
"\0\0\0\0\x0f\x86_\x10\0\0\0\0\0\0\0\0" "\0\0\0\0\x0f\x86_\x10\0\0\0\0\0\0\0\0" "\0\0\0\0\x0f\x86_\x10\0\0\0\0\0\0\0\0" "\0\0\0\0\x0f\x86_\x10\0\0\0\0\0\0\0\0"
"\0\0\0\0\x0f\x86_\x10\0\0\0\0\0\0\0\0" "\0\0\0\0\x0f\x86_\x10\0\0\0\0\0\0\0\0" "\0\0\0\0\x0f\x86_\x10\0\0\0\0\0\0\0\0" "\0\0\0\0\x0f\x86_\x10\0\0\0\0\0\0\0\0"
"\0\0\0\0\x0f\x86_\x10\0\0\0\0\0\0\0\0" "\0\0\0\0\x0f\x86_\x10\0\0\0\0\0\0\0\0" "\0\0\0\0\x0f\x86_\x10\0\0\0\0\0\0\0\0" "\0\0\0\0\x0f\x86_\x10\0\0\0\0\0\0\0\0"
"\0\0\0\0\x0f\x86_\x10\0\0\0\0\0\0\0\0" "\0\0\0\0\x0f\x86_\x10\0\0\0\0\0\0\0\0" "\0\0\0\0\x0f\x86_\x10\0\0\0\0\0\0\0\0" "\0\0\0\0\x0f\x86_\x10\0\0\0\0\0\0\0\0"

julia> Matrix{String}(undef, 5, 5)
5×5 Matrix{String}:
#undef #undef #undef #undef #undef
#undef #undef #undef #undef #undef
#undef #undef #undef #undef #undef
#undef #undef #undef #undef #undef
#undef #undef #undef #undef #undef

在第一种情况下,您得到了一个已初始化的 String7 值矩阵,但它初始化的值是未定义的(这是一些垃圾)。在第二种情况下,您得到了一个 String 值矩阵,并且由于它们不是位,所以矩阵未初始化 - 它还不包含任何值。您首先必须分配一些值,然后才能读取它们。

最后有一个 isassigned 函数,它允许您检查容器是否具有与某个索引关联的值(即检查它是否不是 #undef 或索引超出范围)。这是一个例子:

julia> x = Vector{String}(undef, 3)
3-element Vector{String}:
#undef
#undef
#undef

julia> x[1] = "a"
"a"

julia> isassigned(x, 1) # we have a value here
true

julia> isassigned(x, 2) # no value
false

julia> isassigned(x, 3) # no value
false

julia> isassigned(x, 4) # out of bounds
false

如果有任何不清楚的地方,请发表评论,我可以扩展答案。

关于Julia - 创建 Union{Nothing,String} 与 Union{Nothing,Bool} 的矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69211745/

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