俗话说:由俭入奢易,由奢入俭难。
之前写 Python,老是在实现完一个特性之后,弄出来几个 AttributeError: 'NoneType' object has no attribute
或者 TypeError: list indices must be integers or slices, not str
,还有 TypeError: can only concatenate str (not "int") to str
这样的错误。一看就明白自己又是哪里一不小心疏忽了,稍微修一下就好。
后来啊,我遇见了 Rust,整个流程就变了。之前写的时候,基本上都是通过手动测试来发现这种问题。为了高效、不破坏性地测试,需要控制测试的数据量,需要保证出错的时候相关的数据不会处于某种中间状态。当然在服务器上跑的脚本,我还要来来回回地传更新的脚本,或者弄个本地测试环境。而这一切,可能不过是为了跑一个成功之后再也不会用到的小程序,比如之前分析抓包数据的那次。而在 Rust 里,这些最容易犯的错误,cargo check 一下,编译器基本上能全给你指出来。所以有时候写一些小 工具 我也用 Rust,虽然写起来慢,但写好就能正常运行,不用反复试错,多好啊!
最近给 Arch Linux 中文社区的 自动打包机器人 lilac 增加新特性。结果实现完部署之后,夜里就被 lilac 叫起来修 bug 了,还一下子就是仨……(lilac 很难本地测试,而短暂地服务中断又没多大影响,所以我都是不进行本地测试的。)
第一个 bug 是,与 dict.get 不一样,getattr 是没有默认值的。Python 里这种不一致很多,比如 configparser 里默认值要用关键字参数指定。Rust 遇到类似的情况,就会返回一个 Option。或者如果 API 决定如果不存在就 panic 的话,那么它就会直接返回我要取的值的类型,而不会包一层 Option。而我后边的代码是预期到这里可能取不到那个属性的,所以弄错了就会类型不匹配。
第二个 bug 是局部变量在一个分支上没有初始化。Rust 当然不会允许这种情况了。实际上 C 都不用担心这种问题,编译器会给出警告的,还有一些 linter 可以用。而 Python,很遗憾的是,我所使用的 pyflakes 并没有对此发出警告。我当然知道 pylint 那些。我很讨厌 pylint 和 jslint 这种不区分潜在 bug 和风格问题的 linter。我只需要工具在我可能疏忽的时候提醒我,而不需要它对我的编码风格指指点点,特别是那些指指点点往往是不对的。比如我的文件描述符变量名不叫 fd 难道要叫 fildes?
第三个 bug 是一个可能为 None 的变量我忘了先作 is not None 判断。这段代码如果初写的话我肯定是会注意到的,但是改的时候,只想着如果 pkg 里有冒号我得处理一下,就忘记了根本没有关联的包名的情况。Python 的 None,以及 C 和 C++ 的 NULL、 Java 的 null、 Lua 和 Ruby 的 nil、JavaScript 的 undefined 和 null,被称作是 十亿美元错误 ,给无数 程序员 和用户带来了无尽的 bug。幸好这个东西在 Rust 里不存在:表达「没有值」的值没有被作为特殊值存在于几乎所有类型中,而是作为一类类型的可能的值之一。想要使用「正常」的值,就需要显式地进行类型转换,所以不可能被不小心忽略掉。顺便说一下,Go 里也有 nil 这种东西,以至于会出现这种 不容易发现的 bug 。
Python 现在也给出了解决方案:类型注解,提供类似的类型检查。不过检查器是第三方的,也并不十分完善。等我找到机会试用过之后再来写感想啦。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
GUI设计禁忌2.0
Jeff Johnson / 盛海艳 等 / 机械工业出版社 / 2008 / 49.00元
本书描述软件开发人员在设计图形用户界面(GUI)时经常犯的“禁忌”,并提出避免这些错误的基本原则和理论依据。本书将GUI禁忌分为7种类型:GUI控件禁忌、导航禁忌、文字禁忌、图形设计和布局禁忌、交互禁忌、响应性禁忌以及管理禁忌,并分别进行详述。 本书编排独特,条理清晰,针对性极强,是不可多得的GUI设计优秀资源。本书适合软件开发人员、web站点设计人员、开发经理、用户界面设计人员等阅读。一起来看看 《GUI设计禁忌2.0》 这本书的介绍吧!