从 C / MATLAB 过来的同学注意!

Julia / Python 中使用的参数传递变量方式是不一样的。(以C的眼光看)在语法上细微的差别就会产生完全不一样的内容。(至少我被坑了很多次)。这篇文章的主要作用是逃坑以及方便各种从不同语言过来的人投奔我们Julia!/狗头

变量的传输方式

对于从 C 和 MATLAB 中转移过来的同学,必须非常注意的一个问题是Julia 中变量的传输机制是Python 党最好跳过这一小节。

此处有两个概念:values:真实的数据

variables: 变量名,在这个语境下我认为这个“名”字非常重要。在编程语言中,用变量名bind(链接)到 values

Pass and share 机制中,在传递的过程中values不会被复制。函数内部中产生了新的变量名。这些变量名

Example 1 & 2

PS: 这两个例子必须连起来看!

y = [1 1]

function f!(z) # there is a "!" mark: see link Tip1 Tip2 below

z[1] = 2 * z[2]

z

# this function return z

end

f!(y)

# 1×2 Array{Int64,2}:

# 2 1

## guess what !!!!!

y

# 1×2 Array{Int64,2}:

# 2 1

这里变量y变化了!C和MATLAB的用户看见会觉得这颠覆了当年我们对于函数穿参的根本守则。

原因是:y作为数组,是mutable(可变的)的。传入的时候,实际上只是用z的refer to 一组数据,即y也refer to 的那一组。当我们去改动z[1],实际上是通过这个z变量名,找到了一组数据的第一个元素,并赋值为等号右面的结果。 所以,当我们用y来访问数据时,自然数据是更改过的。

下面再来看一个例子

y = [1 1]

function g(z) # note that there is no ! here

z = 2*z

z

end

g(y)

# 1×2 Array{Int64,2}:

# 2 2

# guess what!

y

# 1×2 Array{Int64,2}:

# 1 1

这里的y又不变了。这里发生了什么?明明在函数g里,我们也改变了z。 这里似乎又颠覆了刚刚建立的认识。

为了说明到底发生了什么,我们做一个类比,把variables(变量名)比作标签,values(真实的数据)比作物品。变量名就像一个标签贴在了实际的物品(数据)上:传入函数前,我们可以理解为,标签y贴在一组数据value1上,value1的实际数值是[1 1]。

y作为参数传入函数g后,此时只是多生成了一个标签z,同样贴在数据value1上。

z = 2*z的第一步:现在我们通过标签z访问value1,并且根据里面的内容计算2*z也就生成了一组新的数据,我们命名为value2。 这得到了我们右面的运算结果。

z = 2*z的第二步:把标签z挪动位置,贴在value2上。

... (略)

上述的1-4过程进行完了以后,我们就可以看出来分别有value1, value2 对应标签 y, z。y所贴着的数据value1从来没有改变过。因此在此处y又不变了。

Excercise: 为了巩固此处发生了什么,最好用标签物品概念把上一个y改变的例子说明一下,并对比其中的不同。 并且把两个例子串起来重新表述一遍。题外话:这个变化对我来说实际上非常不习惯,我写过很长一段时间的C,后来写过一段时间Python ,这个转换可以说是狠狠坑我了一把,甚至直接导致了我相当不喜欢Python。现在有了一些铺垫,我在 Julia 中已经基本适应了。

有人可能会说,这个机制 Julia 也用,Python 也用为什么你这样吹 Julia 而讨厌 Python 呢,说不定你先用Julia后会喜欢Python。答曰:我依然要吹Julia 。原因如下:1. 文档标注:虽然Julia这一点上面使用了一样的机制,Julia的官方文档在非常显眼的地方是详细的写了这一点的不同(Noteworthy Differences),而且在编程风格中甚至针对这一点进行了强烈的风格建议,以改良你的代码,以防你写和阅读代码的时候忘记了这一点,参阅: Tips 1,Tips 2。(个人偏好,并未引战,只希望用Julia的人如果进入了这个坑,看了我这篇文章能熄灭你的怒火)。2. Julia 真的关心你的代码效率,他是一门跟 C 进行性能比较的语言。

C 用户可能会用“指针”来理解这个过程了。但可能出现一个疑惑了,这样的代码有危险。函数在C和数学中都给人一种“单向性”的感觉:输入只是用来确定输出的东西。输入怎么能够改变呢?C 中如果要完成类似的行为,需要显式传入“指针”。但是在Pass and Share机制下,即使不显式传入,也会把数据暴露在危险当中了!。

我只能承认这确实是我们需要承担这样的风险。(可能关于传入参数这件事情可以有其他的理解方式吗?请知友指教了)所以在Julia 的代码风格(Tips 1)当中(不强制)建议道,当我们的函数有可能改变参数中的mutable变量时,我们需要尊崇convention在函数名中以!结尾,如Example 1。

在本小节最后,必须讲一下如何才能写出一个返回值与上述例子之中f!相同但是不改变输入参数y的函数了,代码如下:使用copy()

function f(w)

z = copy(x)

f!(z)

end

copy函数会生成一个新的数据,是(C的意义下的)真正的复制了一次变量。

实际上这里展示的写法:写一个f!,

再用一个f包装起来,

在一些官方函数中有使用。个人觉得这种写法巧妙的消解了Pass and Share 的机制带来的违和感,非常美妙,保持一种微妙的博弈。如果说你想用Pass and Share 的特性更改输入的参数,那就使用f!,如果你想要更保守一些f。

python的pass在函数中的作用_Pass Share:Python / Julia 中函数变量的传递机制相关推荐

  1. python装饰器原理wraps(method)(self)_python装饰器中@wraps作用--修复被装饰后的函数名等属性的改变...

    Python装饰器(decorator)在实现的时候,被装饰后的函数其实已经是另外一个函数了(函数名等函数属性会发生改变),为了不影响,Python的functools包中提供了一个叫wraps的de ...

  2. python在平面设计中的作用_图像处理在平面设计中的作用

    图像处理在平面设计中的作用 处在风华正茂的我们站在 20 出头的路上,退出了懵懵懂懂的少年时光,开始露出了充 满活力与未来的青年锋芒. 我们经历了短暂而铭心的艺考, 完成了难忘的高考时光, 我们有 过 ...

  3. C语言 SLEEP函数不起作用,C语言中的sleep() 函数 sleep函数的具体用法

    导航:网站首页 > C语言中的sleep() 函数 sleep函数的具体用法 C语言中的sleep() 函数 sleep函数的具体用法 相关问题: 匿名网友: 关于sleep()函数在windo ...

  4. 范数在机器学习中的作用_设计在机器学习中的作用

    范数在机器学习中的作用 Today, machine learning (ML) is a component of practically all new software products. Fo ...

  5. 统计信息在数据库中的作用_统计在行业中的作用

    统计信息在数据库中的作用 数据科学与机器学习 (DATA SCIENCE AND MACHINE LEARNING) Statistics are everywhere, and most indus ...

  6. 论计算机在教学中的作用论文,计算机在教学中的应用

    海量优秀的免费计算机在教学中的应用范文供您参考与下载,关于计算机在教学中的应用的免费论文范文参考资料是由2016年最新的相关论文题目按照标准论文格式模板写作的,适合不知道怎么写计算机在教学中的应用的大 ...

  7. 计算机在平面设计中的作用,比例设计在平面设计中的作用与意义

    随着互联网的不断发展,用户体验在设计师的产品设计中占有的比重越大了,而今天我们就一起来了解一下,比例设计在平面设计中的作用与意义. 一.平面设计中的比例是什么? 比例尺是指设计元素相对于其他元素的相对 ...

  8. continue在c语言中什么作用,continue在c语言中什么意思?

    continue在c语言中是退出循环的意思,continue语句的作用是跳过循环体中剩余的语句而强行执行下一次循环. continue语句的作用是跳过循环体中剩余的语句而强行执行下一次循环.conti ...

  9. 计算机在地理科学中的作用,多媒体在地理教学中作用(精).doc

    多媒体在地理教学中的作用 高锦棠 随着科学的不断发展,多媒体技术在各个领域的应用越来越广泛,它在地理教学中的作用也显得越来越明显. 所谓多媒体技术,是把声音.正文.图像.图形.动画.视频 等多种媒体的 ...

最新文章

  1. 关于线程池你不得不知道的一些设置
  2. 逆向入门--第一次的HelloWorld
  3. 关于Qomo OpenProject的进度(2006.01.04)
  4. 给你的Linux把把脉(内存、磁盘、CPU、网络)
  5. java excel解析 poi_Java解析Excel之POI(一)
  6. java replace stringbuilder_Java StringBuilder replace()方法
  7. 電郵泛濫成災 電話再成新寵
  8. (超详细)Linux Shell 编程
  9. java动手写cmpp服务_Java动手微服务简介
  10. Python使用Reportlab处理PDF数据 - 段落
  11. FastStone Capture:Windows系统下小巧好用的宝藏电脑截图软件
  12. 实现winfrom进度条及进度信息提示,winfrom程序假死处理
  13. Android自定义控件 ---- 带下划线的TextView
  14. 如何安装iOS 13 、 macOS Catalina 、watchOS 6 、 tvOS 13 或 iPadOS Beta
  15. 微信小程序下载图片与缓存
  16. 伪装游戏软件变成计算机,注意!Steam上这款游戏是伪装的病毒:把玩家PC变成矿机...
  17. mysql学习ppt摘抄笔记
  18. 比较好的开源商城系统
  19. 如何使用jsDelivr+Github 实现免费CDN加速?
  20. 计算属性,方法与监听器(3-4)

热门文章

  1. mount 安卓system只读_Android如何让system分区可读写(MTK安卓6.0)-阿里云开发者社区...
  2. 宁波政务云资源的介绍与申请
  3. Oracle下的Databse,Instance,Schemas
  4. 微型计算机控制技术试卷B,微型计算机控制技术试卷b..doc
  5. python编程运算符号-Python中的逻辑运算符
  6. mysql 命令行批量sql_命令行中执行批量SQL的方法
  7. scala 线性回归_Scala的特征线性化
  8. c语言存储类_C编程语言的存储类
  9. oracle光标位置无效,解决在Form表单中光标移动不了问题
  10. linux定位哪个进程出发重启,定位Linux下定位进程被谁KILL