String 摆脱朱莉娅';s`WARNING:为未更改的字符串重新定义常量`?
在我的julia代码中,我使用了一些常量。其中一些常量是字符串(它们用作标识符)。我的问题是,每当我运行julia脚本时,我总是会收到以下关于常量字符串的警告,,即使我没有更改常量:String 摆脱朱莉娅';s`WARNING:为未更改的字符串重新定义常量`?,string,warnings,constants,julia,String,Warnings,Constants,Julia,在我的julia代码中,我使用了一些常量。其中一些常量是字符串(它们用作标识符)。我的问题是,每当我运行julia脚本时,我总是会收到以下关于常量字符串的警告,,即使我没有更改常量: 警告:重新定义常量pot\u类型 为了说明我的问题,这里有一个MWE: const pot_type = "constant" const b = 12 println("Given parameters: Potential = $pot_type, b = $b .") 如果我运行这个脚本两次,就会得到前面提
警告:重新定义常量pot\u类型
为了说明我的问题,这里有一个MWE:
const pot_type = "constant"
const b = 12
println("Given parameters: Potential = $pot_type, b = $b .")
如果我运行这个脚本两次,就会得到前面提到的警告。
不仅如此,如果我只是在Julia控制台中键入两次const something=“something”
,同样的事情也会发生。我刚刚收到警告:重新定义常量
我知道这不会以任何方式影响我的代码,但是否有任何方法可以删除或修复此警告?在我的实际代码中,每次我提交一些东西时,它都会创建5行,这个空间可以用来显示以前提交的输出
编辑(让自己更清楚):问题是,即使我没有重新定义常量,也会显示此警告消息,这意味着我给了它相同的值。而且,这个问题(据我所知)只存在于String
,而不存在于Int64
或Float64
类型。例如:如果我写入const b=1.2
,然后写入const b=1.4
,我将得到预期的警告消息。现在,如果我写入const b=1.2
,然后写入const b=1.2
(相同的值),我将不会像预期的那样再次收到警告。但是,这不适用于字符串常量。即使在定义相同的值时,您也会收到警告。如果要将某个对象用作常量,那么您确实不希望多次定义它(毕竟,这是常量的要点),并且当您多次运行脚本时,这正是您要做的。此外,重新定义常量不会以任何方式影响您的代码也不是完全正确的——在某些情况下,它实际上会对性能造成相当大的影响。同样,这就是为什么要使用常量——通过明确表示计算机不需要担心特定对象的值发生更改来提高性能
即使给常数赋值相同的值,它对计算机来说仍然是一个新的赋值。也就是说,如果你不更明确地告诉计算机(正如我在下面描述的)执行一些额外的逻辑,计算机将不会看到“哦,我想这与之前分配给常数的值是一样的,我想这可能没问题。”
通常,在开发过程中会出现多次运行同一脚本的情况,我猜这就是您正在做的。因此,作为一个快速解决方案,您可以检查常量是否已经定义,如果没有定义,则只为其赋值。以下将实现这一目标:
isdefined(:b) || (const b = 12)
作为一个长期的解决方案,一旦您通过了开发阶段(在开发阶段,您不断地运行相同的代码来解决bug),那么您将真正希望编写脚本,这样就不会多次定义常量,因为否则,正如我提到的,在这种情况下,它实际上不是常量
另外,如果有帮助,对上述代码片段的解释如下。|
运算符意味着Julia将计算第一条语句已定义(:b)
,如果第一条语句为false,则只继续计算第二条语句(const b=12)
。我们在第一个语句中使用:
运算符来引用b的符号,即询问是否有任何东西分配给该符号,b
补充并详细说明@aireties的优秀答案,当您在同一模块中再次执行const x=a
和以后执行const x=b
时,Julia中目前有三种情况:
无警告:如果a===b
那么a
和b
在编程上是不可区分的,就像亨利·贝克的EGAL[,]:用b
替换a
不会影响任何程序的行为,因此,对常数x
的重新定义是不可操作的,不需要警告
警告:如果a!==b
但是typeof(a)==typeof(b)
那么在Julia的当前版本中,生成的代码仍然有效,因为它只取决于保持不变的x
的类型,但是程序的行为可能会受到x
的更改的影响,因为旧值a
和新值b
在编程上是可以区分的
错误:如果typeof(a)!=typeof(b)
重新分配x
将使先前使用x
生成的任何代码的假设无效。因此,不允许进行此分配
=
谓词将不可变值按类型和内容进行比较,因此1.5
始终与1.5
相同,因为无论有多少个该值的“实例”,它们都无法变异,因此无法以任何方式进行区分。另一方面,值1.5
(Float64)和Float32(1.5)
,是可以区分的,因为它们具有不同的类型,即使它们表示完全相同的数值。但是,对于可变值,==
谓词通过标识比较对象:除非它们是完全相同的对象,否则它们不会被视为=
。这是因为您可以通过更改其中一个并查看另一个是否更改,以编程方式区分两个可变值,即使它们以相等的值开始
在Julia中,字符串仅按约定是不可变的:String
类型包装一个字节数组,它
julia> const x = "foo"
"foo"
julia> const x = "foo"
WARNING: redefining constant x
"foo"
## in a new session ##
julia> foo = "foo"
"foo"
julia> const x = foo
"foo"
julia> const x = foo
"foo"
(@isdefined x) || (const x = 10)