人工智能算法36节讲解(人工智能之Julia变量的作用域你真的理解吗)

百度百科中将Julia描绘成是一个面向科学计算的高性能动态高级程序设计语言。是说Julia在科学计算和人工智能领域有很大优势,如今这两个领域可是热门中的热门。所以学习Julia前景还是不错的。

人工智能算法36节讲解(人工智能之Julia变量的作用域你真的理解吗)(1)

对于任何语言了解变量的作用域都是很基础而且是十分重要的。Julia的作用域是否和你熟知的其他语言一样呢?

Julia1.0对于变量的作用域做了比较大的修改,本文只关注Julia1.0的变量作用域。

我们要讨论的问题和下面的代码有关:

人工智能算法36节讲解(人工智能之Julia变量的作用域你真的理解吗)(2)

上面这段代码如果执行下去,a,b 的值会发生什么变化?大家不妨先自己试一试,是否和自己理解的一样。

答案是: 这段代码会在运行func_a()的时候抛出异常:ERROR: UndefVarError: b not defined,换句话说代码是有问题的。

我们首先来分析func_b, 然后再来分析func_a,然后再来总结,最后抛出两个小问题,有兴趣的朋友可以试一试想一想,然后在评论区说出你的答案,我鼓励大家交流。

注:为了方便说明,我们假设下面的代码都是在REPL中执行的,即全局变量都属于模块Main。

一。 分析 func_b()

我们的理解(当然现在证明是错误的):

对于 b = 100, 我们的理解是等价于 b = Main.b 100。

右边的Main.b应该是全局变量b,也就是1,变量有模块前缀,表明它是某个模块中的全局变量; 左边的b因为在函数中被赋值,那么它应该是一个局部变量。最后func_b()运行应该返回101,而Main.b不会发生改变,仍然是1。

实际的情况:

我们要看清楚,Julia是怎么处理的,需要借助Julia为我们提供的工具,这里我们用@code_lowered 宏,它生成一个CodeInfo对象,有助于我们查看Julia是怎么处理一个表达式的。

人工智能算法36节讲解(人工智能之Julia变量的作用域你真的理解吗)(3)

%1是可以认为是临时变量,那么上面的CodeInfo表达的意思就是 b = b 100 ,然后返回 %1。这里的b没有任何前缀,说明左边和右边的b都是局部变量。那么显然b 100是不对的,因为b在这里是未定义先使用了。

二。分析 func_a()

我们的理解:

a . = 100 等价于 a = Main.a . 100。 “. ”是一个广播操作,意思是对Main.a中的每一个元素加100。那么最后赋值给一个局部变量a并返回,Main.a 不会发现改变。

实际情况:

人工智能算法36节讲解(人工智能之Julia变量的作用域你真的理解吗)(4)

上述CodeInfo可以表示为:

materialize!(Main.a, broadcasted(Main.: , Main.a, 100))

broadcasted(Main.: , Main.a, 100) 即 Main.a . 100。

而materialize!()则表示上面. 操作后的结果直接覆盖Main.a。注意函数名称是带有"!"后缀的,在Julia中,调用这类函数,通常会改变原参数的。

最后的结果就是在函数func_a()中, a . = 100 等价于 Main.a = Main.a . 100,即全局变量a会被改变成:[101, 102]

三。结论:

在Julia中:

对于不可变对象,行为都类似func_b()

对于可变对象,行为都类似func_a() 。

在《Julia 字符串是可变的还是不可变的?》中我提到过,Julai中的字符串是可以修改的,但是注意,Julia仍然是将字符串作为不可变对象看待的

最后的两小问题是:

问题1: 如果将func_a做如下的改写,会怎么样?

function func_a() a = a . 100 end

问题2: 如果我想让func_b() 可以修改全局的变量b,func_b()应该怎么写?

,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页