【问题标题】:How to lock the variable type in Julia?如何在 Julia 中锁定变量类型?
【发布时间】:2021-07-30 21:16:16
【问题描述】:

我想在Julia中锁定一个变量的类型,怎么办?比如我定义了一个叫weight的数组,

weight = Array{Float64,1}([1,2,3])

现在我想将权重类型锁定为Array{Float64,1},可以吗?

我的意思是如果不锁定重量的类型,那么如果我错误地或随便地这样做了

weight = 1

那么weight就会变成一个Int64变量,所以不再是一维数组了。这显然不是我想要的。

我只想确保一旦我将权重定义为 1D Float64 数组,那么如果我更改权重类型,我希望 Julia 给我一个错误,指出权重类型已更改,这是不允许的。是否可以?谢谢!

这很有用,因为这样做可以防止我忘记重量是一维数组,从而防止错误。

【问题讨论】:

  • 你可以写[1.0, 2.0, 3.0]而不是Array{Float64,1}([1,2,3])。 Julia 根据数组元素计算出数组的类型。你写的方式先创建一个整数向量,然后再转换成浮点数向量,很浪费。
  • @DNF 你是对的人!是的,是的,是的,我可以写 1.0 2.0 3.0。问题是,一旦我写下这个数组,我想确保 weight 始终是一个浮点数组。有可能在代码中我可能忘记了权重是一个浮点数组,并且不小心做了诸如权重 = 1.0 之类的事情,它会使权重变成一个变量而不是一个数组。我想确保重量的类型永远不会改变。在 fortran 中,我们可以先定义类型。但是在 Julia 中,由于事情是动态的,我想做一些类型保护来防止偶然的错误,这些错误会改变变量或数组的类型。
  • 当然,但这些都是正交问题。你可以const weight = [1.0, 2.0, 3.0]

标签: julia


【解决方案1】:

对于global 变量使用const

julia> const weight = Array{Float64,1}([1,2,3])
3-element Vector{Float64}:
 1.0
 2.0
 3.0

julia> weight[1]=11
11

julia> weight=99
ERROR: invalid redefinition of constant weight

请注意,重新定义引用会引发警告:

julia> const u = 5
5

julia> u=11
WARNING: redefinition of constant u. This may fail, cause incorrect answers, or produce other errors

您可以使用Ref 类型绕过它:

julia> const z = Ref{Int}(5)
Base.RefValue{Int64}(5)

julia> z[] = 11
11

julia> z[] = "hello"
ERROR: MethodError: Cannot `convert` an object of type String to an object of type Int64

在函数中使用 local 和类型声明:

julia> function f()
           local a::Int
           a="hello"
       end;

julia> f()
ERROR: MethodError: Cannot `convert` an object of type String to an object of type Int64

【讨论】:

  • 非常感谢。快速提问,所以我发现通过执行 const weight = Array{Float64,1}([1,2,3]),我可以在没有警告的情况下重置其值,如 weight[1]=11。但是,为什么如果我对变量执行 const,例如 const a = 1.0,那么如果我进一步执行 i = 1.5,它会给我一个警告?警告说:“警告:重新定义常量 a。这可能会失败、导致错误答案或产生其他错误。”但是对于array,没有这样的警告?
【解决方案2】:

你通常会写:

weight::Vector{Float64} = Array{Float64,1}([1,2,3])

...但这在全球范围内似乎是不可能的:

julia> weight::Vector{Float64} = Array{Float64,1}([1,2,3])
ERROR: syntax: type declarations on global variables are not yet supported
Stacktrace:
 [1] top-level scope
   @ REPL[8]:1

但是,您可以在本地范围或struct

julia> function fun()
        weight::Vector{Float64} = Array{Float64,1}([1,2,3])
        weight = 1
       end
fun (generic function with 1 method)

julia> fun()
ERROR: MethodError: Cannot `convert` an object of type Int64 to an object of type Vector{Float64}
Closest candidates are:
  convert(::Type{T}, ::AbstractArray) where T<:Array at array.jl:532
  convert(::Type{T}, ::LinearAlgebra.Factorization) where T<:AbstractArray at /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.6/LinearAlgebra/src/factorization.jl:58
  convert(::Type{T}, ::T) where T<:AbstractArray at abstractarray.jl:14
  ...
Stacktrace:
 [1] fun()
   @ Main ./REPL[10]:3
 [2] top-level scope
   @ REPL[11]:1

您可以使用const,但是使用相同类型的值重新定义会导致警告:

julia> const weight = Array{Float64,1}([1,2,3]);

julia> weight = [2.]
WARNING: redefinition of constant weight. This may fail, cause incorrect answers, or produce other errors.
1-element Vector{Float64}:
 2.0

【讨论】:

  • 非常感谢!看起来 const 是一种方法。嗯,那么,另一方面,有没有办法在没有警告的情况下使类型稳定?
猜你喜欢
  • 2017-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-11
  • 1970-01-01
相关资源
最近更新 更多