#julia
Вопрос:
Я хочу заблокировать тип переменной в Julia, как это сделать? Например, я определяю массив с именем weight,
weight = Array{Float64,1}([1,2,3])
Теперь я хочу зафиксировать тип веса как массив{Float64,1}, это возможно?
Я имею в виду, если не заблокировать тип веса, то, если я по ошибке или случайно это сделаю
weight = 1
Тогда вес станет переменной типа Int64, поэтому он больше не будет 1D-массивом. Это явно не то, чего я хочу.
Я просто хочу убедиться, что, как только я определил вес как массив 1D Float64, затем, если я изменю тип веса, я хочу, чтобы Джулия выдала мне ошибку, сказав, что тип веса был изменен, что недопустимо. Возможно ли это? Спасибо!
Это полезно, потому что, поступая таким образом, это может помешать мне забыть, что вес является 1D массивом, и, следовательно, предотвратить ошибки.
Комментарии:
1. Вместо
Array{Float64,1}([1,2,3])
этого вы можете просто писать[1.0, 2.0, 3.0]
. Джулия определяет тип вашего массива на основе его элементов. То, как вы это написали, сначала создает вектор int, а затем преобразует его в вектор поплавков, что является расточительным.2. @DNF Ты прав, парень! Да, да, да, я могу написать 1.0 2.0 3.0. Дело в том, что как только я запишу этот массив, я хочу убедиться, что вес всегда является плавающим массивом. Возможно, в коде я могу забыть, что вес-это массив с плавающей запятой, и случайно сделать что-то вроде weight = 1.0, и это сделает вес просто переменной вместо массива. Я хочу быть уверен, что тип веса никогда не изменится. В фортране мы можем сначала определить тип. Но в Джулии, поскольку все динамично, я хотел сделать некоторую защиту типов, чтобы предотвратить случайные ошибки, которые изменяют тип переменной или массива.
3. Конечно, но это ортогональные проблемы. Вы можете сделать
const weight = [1.0, 2.0, 3.0]
Ответ №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
Комментарии:
1. Большое спасибо!. Быстрый вопрос, поэтому я обнаружил,что, выполнив const weight = Массив{Float64, 1}([1,2,3]), я могу сбросить его значение, например, weight[1]=11 без предупреждения. Однако, почему, если я сделаю const для переменной, такой как, const a = 1.0, то это выдаст мне предупреждение, если я продолжу делать i = 1.5? В предупреждении говорится: «ПРЕДУПРЕЖДЕНИЕ: переопределение константы a. Это может привести к сбою, неправильным ответам или другим ошибкам». Но для массива такого предупреждения нет?
Ответ №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
Комментарии:
1. Большое спасибо! Похоже, что const-это способ сделать. Хм, так, с другой стороны, есть ли способ сделать тип стабильным без предупреждения?