百科问答小站 logo
百科问答小站 font logo



为什么说「动态类型一时爽,代码重构火葬场」? 第1页

  

user avatar   catchen 网友的相关建议: 
      

因为你写一个允许传入动态类型的函数给别人用,就如同给一张签了名的空白支票别人一样危险,别人爱写什么数字上去都行。

举个例子,Facebook 有一种数据类型叫做 FBID,是一个 64 位的整数,用作任何对象的唯一 ID。在 Facebook 把无类型的 PHP 转化为有类型的 Hack 之前,很多人不知道 FBID 到底是整数还是字符串,于是有些函数用整数接收 FBID,另外一些函数用字符串。这时候函数之间传来传去的 FBID 到底是什么类型已经说不清楚。如果你写一个函数并接收一个 FBID 的数组,你永远不可能知道数字里的 FBID 是哪种类型,甚至可能是混合类型的。

尽管在语义上这绝对是有问题的,但神奇的 PHP 在做整数和字符串 == 比较时会自动把字符串隐式转换为整数,所以原本不应该相等的两种类型 FBID 可能会被判定为相等。不过如果用 === 的话,不同类型自然不相等。因为很多人不注意细节,使用 == 而非 ===,所以如果假设你接收了一个 FBID 的数组,然后调用别人的函数来去重,你猜 “123” 和 123 会不会被当作重复而去掉?你不可能猜到,因为你不知道别人用什么做对比。

这使得当时 Facebook 的 PHP 代码存在大量难以发现的 bug,而且没人敢去修。你说你这里 FBID 一定是整数,然后收到字符串就抛异常?你猜你这一改 Facebook 哪些功能会挂掉?你不可能知道……所以你不敢改。

最终 Facebook 把 PHP 逐步转化为 Hack,把 FBID 存储为整数,大家就可以放心地把 FBID 传来传去不用担心出问题了。如果你尝试拿 FBID 跟另外一个字符串或整数比较,你的代码在静态分析阶段就会报错。你一定要比较,就必须进行显式类型转换后再做比较。

同理,Facebook 把 JavaScript 改造为 Flow,但 FBID 在 JavaScript 里面必须存储为字符串,因为 JavaScript 存储不了 64 位整数,可能会转换为浮点数存储,然后丢失精度。在此之前,有人不知道 FBID 在 JavaScript 不能存为整数,然后引发各种难以复现的 bug。

如果你不懂 Hack 或 Flow,可以用现在主流的 TypeScript 做参考。我认为这是现在最好的折衷方案。语言本身是支持动态类型的,但通过类型注释来让类型稳定的变量和参数变为有类型,你不加类型注释的时候还能灵活使用动态类型。

为什么你需要保留使用动态类型的权力呢?因为你在开发新功能时,可能你只是在探索,具体数据结构还没有定下来,不需要声明完整的数据结构类型信息能为你节省不少改来改去的时间。与之对比的是那些 C++ 和 Java 操作 JSON 的代码,必须处处声明现在预期读取出来的变量是什么类型,你稍微改一下 JSON 的结构就要改对应的类型声明,这真的很麻烦。


user avatar   Ivony 网友的相关建议: 
      

吐槽并不在点子上。


首先是动态类型根本不可能一时爽,动态类型有其好处也有其缺陷,譬如说智能提示这玩意儿显然就是依赖于静态类型检查的,动态类型的智能提示完善度和静态类型显然没法比。一个静态类型的类库用起来就会比动态类型构建出来的要爽很多,所以不存在什么一时爽,各有其用武之地。

其次是动态类型和重构没什么太大的关系,诚然静态类型在语言层面上类型成员是静态绑定的,所以重构的时候可以简单的点两下就能修改一个成员的名称。但问题在于:

1、我没事干嘛要修改成员的名称,仅仅只是改个名字算哪门子的重构?

2、动态类型的成员虽然不是静态绑定,但是成员名称不会变化,我一个文件内搜索+完整匹配就能找到所有疑似的成员,再手工缩小范围照样能重构。

3、重构依赖的是单元测试和小步迭代的方法,静态类型的主要优势并不在重构。


那么,静态类型的主要优势在哪里呢?静态类型检查的主要优势当然是编译器辅助类型检查降低出错概率,成员静态绑定更好的智能提示和更好的编译优化获得更强的运行时性能哈。


user avatar   kyon-n 网友的相关建议: 
      

很多人说有测试就好了,虽然这么说没错,但没有解释问题的本质。

无论是类型还是测试,都是一种约束。


就像法律是对人的约束一样,类型和测试会约束代码的行为。约束的好处是能够规范代码的行为,坏处是失去了一部分自由,并且约束的构建也要消耗很大精力。

你写了个类Square,就是约束了它的实例必须是长宽相等的正方形。好处是这些实例不会出现长宽不等的异常,坏处是说不定你之后还想用长方形,于是就必须改这个类或者重新写个类,并且修改相关代码。

你写了个单元测试保证函数的输出是正方形。其实无非就是把「对正方形的约束」从类型定义变成了代码逻辑,本质上是一样的。

写比较大的工程时,肯定要有前期的设计,由此给出对代码行为的约束。这时用动态类型也好静态类型也好,都是要用类型和测试给出这些约束,由此保证程序的正确性。所谓重构,也就是在保证约束成立的情况下,优化代码的结构。

很多时候我们用动态类型语言,并不是因为有多需要它的动态特性(实际上绝大多数变量的类型在运行时就没变过),只是因为懒得花时间处理约束问题而已。——俺知道s肯定是个字符串,但俺就是懒得写 string s = "fuck" 前面那七个字符。


user avatar   davidtsang 网友的相关建议: 
      

扯吧。FACEBOOK,twitter、instagram都是动态语言写的,也没见火葬场。

除了java、c++还有什么不是动态类型?go?

只会写java就直说。


user avatar   cyandev 网友的相关建议: 
      

这两个游戏都有自己的问题。但严重程度完全不一样。

赛博朋克最大的问题是人力不够,没有人手把愿景在限期内做出来,导致后期狂砍。但从已有的成品来看,CDPR是完全有人才有能力把东西做出来的,只不过没时间做。光影效果,已有的垂直城市设计,以及主线和很多支线任务的演出都有毫不输巫师3的气质,尤其是日本城浮空平台那关,无论是游戏流程还是画面还是音乐,都把类似银翼杀手2047的那种气氛和感受做到了极致。有人说CDPR的人才都跑了,或者CDPR傲娇了开始放水,这并不客观。2077确实是个半成品,主机优化的问题尤其严重,但你关注已经完成的部分,用高配置PC玩,其质量并未令人失望,依然是巫师3的水准。

2077就像是一个优等生忘了做背后的几题的考卷,开天窗导致不及格,但已经做了的题目还是正确率极高的。

谈到E3的demo,单从画面上讲你很难说它缩水了。只不过CDPR没告诉你想要E3画面,就得上3080+光线追踪。。。

我猜想没有光追的话,游戏在大多数情况下也是可以达到光追的效果的,只不过人工工作量会很大,有些地方需要离线烘培,而有些地方需要人工设置虚拟光源。CDPR可能发现项目后期工作量太大搂不住了,就上了光追这个大杀器。。。


至于无人深空,现在口碑很好,但我要不客气地讲,这个游戏到了今天依然是垃圾,只配卖$19.95,打折的时候卖2.95的那种。

Hello工作室自始自终都没有把初始愿景实现的技术能力。

你可以看无人深空进入大气层的技术实现。先是一段飞船进入大气层摩擦发红的特效,然后可以看见地形通过一种非常粗糙、视距很近的情况下刷新出来,并且刷出来的地貌和太空中看到的地貌完全不同。所以从头到尾,hello工作室都没有类似精英危险和星际公民的无缝行星登陆技术。

无人深空更新了十几次,并没有触动这个游戏除了机械刷就没有任何深度的本质。这是一个极其无聊的游戏。但它刷了两年的DLC,玩家也就给他点面子,没功劳有苦劳。它每次更新我都会进游戏看看,但玩不了半小时就会放弃。一是实在无聊,二是它美术设计和渲染水平有限,色彩及其刺眼。比如在母船机库里,到处都是亮瞎狗眼的点状光源,但这些光源不会照亮周围的任何东西,看的时间长了有种不带护目镜看焊接的流泪效果。你说更新了那么久,这么简单的问题都不解决,有什么用呢。游戏中随处可见低级设计的痕迹,比如说有很多行星上有一种可以卖钱的球,这种球没有任何贴图,只有亮瞎眼的纯白色材质,在HDR效果下极其刺眼,但它又不是个光源,放在地上不会照亮周围任何东西。这种打开Blender就存盘的建模初手垃圾素材居然也能放在游戏里,真是活久见。

所以无人深空就像是一个学渣冒充学霸,把期望提得无限高,却每题都答错结果接近0分,被骂,然后花了漫长的时间在那里订正,一题一题的改,最后终于接近30分了,然后获得了大家的赞赏,全然忘记了它改了那么久依然是不及格。

无人深空的贴图我就不贴了,首发的时候真是纯垃圾,基本上是2008年魔兽世界首发的那个水准。现在也依然是垃圾,开个HDR看着眼睛都疼。




  

相关话题

  for(int i = 0; ; i++); printf("i love you"); 请问这条代码是什么意思,可以运行出什么结果? 
  <<深度探索c++对象模型>>中的虚继承看着蛋疼,感觉这在实际中也没多大用,需要继续深究吗? 
  计算机专业的学生如何系统的学习前端技术? 
  剪切板、文件拖拽这些功能桌面环境是怎么实现的? 
  CPython有GIL是因为当年设计CPython的人偷懒吗? 
  计算机专业 CPU 应该用 AMD 还是 Intel? 
  软件http请求 对网站本身有没有弊端? 能否通过这种模拟请求的方式做出一些自动刷回复的脚本软件,并出售? 
  这样一个数据库分析软件需难度高吗? 
  听说过面向工资编程吗?面向工资编程是怎样一种体验? 
  做一个优秀的程序员到底难在哪里? 

前一个讨论
家用脱毛仪是否真的可以实现永久脱毛呢?
下一个讨论
为什么小说里基因鉴定只和父亲验?母亲验不出来吗?





© 2024-11-24 - tinynew.org. All Rights Reserved.
© 2024-11-24 - tinynew.org. 保留所有权利