C 程序的原则

按照 Doug Gwyn 的话说:“Unix 不会阻止你做愚蠢的事情,因为那会同样阻止你做聪明的事情”。C 是一个非常强大的工具,但使用它的时候需要非常小心和自律。学习这些纪律是绝对值得的,因为 C 是所有程序语言中最优秀的。一个自律的 C 程序员将会……

喜欢可维护性。不要在不必要的地方自作聪明。取而代之的是,找出最简单最易懂的满足需求的方案。诸如性能之类考量是放在第二位的。你应该为你的代码做一个性能预算,并自在的支配它。

随着你对这门语言越来越了解,掌握了越来越多能够从中获益的特性,你也应该学会什么时候不能使用它们。相比用到了很多新奇的方式去解决问题,易于新手理解是更重要的。最好是让一个新手理解你的代码并从中有所收获。像你大概去年就在维护它一样去撰写代码。

避免使用魔法。不要使用宏 (macros)——尽管用它定义常量是没问题的。不要使用 typedef 来隐藏指针或回避撰写“结构”。避免撰写复杂的抽象。保持你的构建系统简单透明。不要因为一个愚蠢的 hacky 的废物解决问题的方式酷炫就使用它。你的代码在行为之下应该是明显的,甚至不需要上下文。

C 最大的优势之一就是透明和简单。这应该被信奉,而不是被颠覆。但是 C 的优良传统是给你足够的空间施展自己,所以你可以为了一些魔术般的目的使用它。但最好还是不要这样,做个麻瓜挺好的。

辨识并回避危险的模式。不要使用固定尺寸的 buffers (有人指出这种说法并不是完全正确。我之前打草稿的时候提到了这些,但还是删掉了)——始终计算你需要分配的空间。阅读你使用的函数的 man 手册并掌握他的成功有出错模式。立刻把不安全的用户输入转换为干净的 C 结构。如果你之后会把这些数据展现给用户,那么尽可能把 C 结构保持到最后。要学会在使用例如 strcat 的敏感函数时多加留意。

撰写 C 有的时候像握着一把枪。枪是很重要的工具,但是和枪有关的事故都是非常糟糕的。你对待枪要非常小心:不要用枪指着任何你喜爱的东西,要有好的用枪纪律,把它当作始终上膛一样谨慎。而就像枪善于拿来打孔一样,C 也善于用来撰写内核。

用心组织代码。永远不要把代码写到 header 里。永远不要使用 inline 关键字。把独立的东西分开写成不同的文件。大量使用静态方法组织你的逻辑。用一套编码规范让一切都有足够的空间且易于阅读。当目的显而易见的情况下使用单字符变量名,反之则使用描述性的变量名。

我喜欢把我的代码组织成目录,每个目录实现一组函数,每个函数有属于自己的文件。这些文件通常会包含很多静态函数,但是它们全部用于组织这个文件所要实现的行为。写一个 header 允许这个模块被外部访问。并使用 Linux 内核编码规范,该死

只使用标准的特性。不要把平台假设为 Linux。不要把编译器假设为 gcc。不要把 libc 假设为 glibc。不要把架构假设为 x86 的。不要把核心工具假设为 GNU。不要定义 _GNU_SOURCE

如果你一定要使用平台相关的特性,为这样的特性描述一个接口,然后撰写各自平台相关的支持代码。在任何情况下都不要使用 gcc 扩展或 glibc 扩展。GNU 是枯萎的,不要让它传染到你的代码。

使用严谨的工作流。也要有严谨的版本控制方法。撰写提交记录的时候要用心——在第一行简短解释变动,然后在扩展提交记录中加上改变它的理由。在 feature 分支上工作要明确定义目标,不要包含和这个目标不相关的改动。不要害怕在 rebase 时编辑你的分支的历史,它会让你的改动展示得更清晰。

当你稍后不得不回退你的代码时,你将会感激你之前详尽撰写的提交记录。其他人和你的代码互动时也同样会心存感激。当你看到一些愚蠢的代码时,也可以知道这个白痴当时是怎么想的,尤其是当这个白痴是你自己的时候。

严格测试和回顾。找出你的改动可能会经过的代码路径。测试每条路径的行为是正确的。给它不正确的输入。给它“永远不可能发生”的输入。对有错误倾向的模式格外小心。寻找可以简化代码的地方并让过程变得更清晰。

接下来,把你的改动交给另外一个人进行回顾。这个人应该运用相同的程序并签署你的改动。而且回顾严格,标准始终如一。回顾的时候应该想着,如果由于这些代码出了问题,自己会感到耻辱

从错误中学习。首先,修复 bug。然后,修复实际的 bug:你的流程允许里这个错误的发生。拉回顾你代码的人讨论——这是你们共同的过错。严格的检查撰写、回顾和部署这些代码的流程,找出根源所在。

解决方案可以简单,比如把 strcat 加入到你的触发“认真回顾”条件反射的函数列表。它可以通过电脑进行静态分析,帮你检测到这个问题。可能这些代码需要重构,这样找出问题变得简单容易。疏于避免未来的错误才是真的大错


重要的是记住规则就是用来打破的。可能有些情况下,不被鼓励的行为是有用的,被鼓励的行为是应该被忽视的。你应该力争把这些情况当作例外而不是常态,并当它们发生时仔细的证明它们。

C 是狗屎。我爱它,并希望更多的人可以学到我做事的方式。祝好运!

Vue 2.0 来了!

终于发布了!

原文:https://medium.com/the-vue-point/vue-2-0-is-here-ef1f26acf4b8#.6r9xjmu6x

今天我非常兴奋的官宣 Vue.js 2.0 的发布:Ghost in the Shell。历经 8 个 alpha 版本、8 个 beta 版本和 8 个 rc 版本 (矮油好巧!),Vue.js 2.0 已经为生产环境准备好了!我们的官方教程 vuejs.org/guide 也已经全面更新。

2.0 的工作自今年 4 月启动以来,核心团队为 API 设计、bugfix、文档、类型声明做出了很重要的贡献,社区中的同学们也反馈了很多有价值的 API 建议——在此为每一位参与者致以大大的感谢!

2.0 有哪些新东西

性能

基于第三方 benchmark,数值越低越好

基于第三方 benchmark,数值越低越好

2.0 用一个 fork 自 snabbdom 的轻量 Virtual DOM 实现对渲染层进行了重写。在其上层,Vue 的模板编译器能够在编译时做一些智能的优化处理,例如分析并提炼出静态子树以避免界面重绘时不必要的比对。新的渲染层较之 v1 带来了巨大的性能提升,也让 Vue 2.0 成为了最快速的框架之一。除此之外,它把你在优化方面需要做的努力降到了最低,因为 Vue 的响应系统能够在巨大而且复杂的组件树中精准的判断其中需要被重绘的那部分。

还有个值得一提的地方,就是 2.0 的 runtime-only 包大小 min+gzip 过后只有 16kb,即便把 vue-routervuex 都包含进去也只有 26kb,和 v1 核心的包大小相当!

渲染函数

尽管渲染层全面更新,Vue 2.0 兼容了绝大部分的 1.0 模板语法,仅废弃掉了其中的一小部分。这些模板在背后被编译成了 Virtual DOM 渲染函数,但是如果用户需要更复杂的 JavaScript,也可以选择在其中直接撰写渲染函数。同时我们为喜欢 JSX 的同学提供了支持选项

渲染函数使得这种基于组件的开发模式变得异常强大,并打开了各种可能性——比如现在新的 transition 系统就是完全基于组件的,内部由渲染函数实现。

服务端渲染

Vue 2.0 支持服务端渲染 (SSR),并且是流式的,可以做组件级的缓存,这使得极速渲染成为可能。同时,vue-routervuex 2.0 也都支持了可以通用路由和客户端状态“hydration”的服务端渲染。你可以通过 vue-hackernews-2.0 的 demo app 了解到它们是如何协同工作的。

辅助库

官方支持的库和工具——vue-routervuexvue-loadervueify——都已经升级并支持 2.0 了。vue-cli 现在已经默认生成 2.0 的脚手架了。

特别之处在于,vue-routervuex 在它们的 2.0 版本中都已经有了很多改进:

vue-router

  • 支持多命名的 <router-view>
  • 通过 <router-link> 组件改进了导航功能
  • 简化了导航的 hooks API
  • 可定制的滚动行为控制
  • 更多复杂示例

vuex

  • 简化了组件内的用法
  • 通过改进 modules API 提供更好的代码组织方式
  • 可聚合的异步 actions

它们各自的 2.0 文档里有更多的细节:

社区项目

中国最大的在线订餐平台饿了么的团队已经基于 Vue 2.0 构建了一套完整的桌面 UI 组件库。不过还没有英文文档,但是他们正在为此而努力!

很多其他社区的项目也都在为 2.0 做兼容——请移步到 awesome-vue 搜索关键字“2.0”。

从 1.0 迁移

如果你是一个 Vue 的新同学,现在就可以“无脑”使用 Vue 2.0 了。最大的问题其实是目前 1.0 的用户如何迁移到新的版本。

为了帮助大家完成迁移,团队已经在配合 CLI 迁移辅助工具制作非常详实的迁移教程。这个工具不一定捕获每一处被废弃的东西,但相信能帮你开个好头。

One More Thing……

中国最大的电商公司阿里巴巴的工程师们已经发起了一个叫做 Weex 的项目,通过 Vue-inspired 语法在移动端渲染 native UI 组件。但是很快,“Vue-inspired” 将会成为 “Vue-powered”——我们已经启动了官方合作,让 Vue 2.0 真正成为 Weex 的 JavaScript 运行时框架。这让用户能够撰写横跨 Web、iOS 和 Android 的通用 Vue 组件!我们的合作才刚刚开始,这将会是 2.0 发布后未来我们专注的重点,请大家拭目以待!

Vue 从一个不起眼的 side project 开始如今已经有了长足的发展。今天它已经是社区资助的被实际广泛认可的,并且根据 stats.js.org 统计在所有 JavaScript 库中增势最强劲的一个。我们相信 2.0 会走得更远。这是 Vue 自启动以来最大的一次更新,我们期待大家用 Vue 创造出更多好产品!

【整理】Vue 2.0 自 beta 1 到 beta 4 以来的主要更新

主要内容来自 https://github.com/vuejs/vue/releases

之前 Vue 2.0 发布技术预览版 到现在差不多三个月了,之前写过一篇简单的 code review,如今三个月过去了,Vue 2.0 在这个基础之上又带来了不少更新,这里汇总 beta 以来 (最新的版本是 beta 4) 的主要更新,大家随意学习感受一下

alpha 和 beta 版本的侧重点会有所不同

首先 Vue 2.0 对 alpha、beta 有自己的理解和设定:alpha 版本旨在完善 API、考虑所需的特性;而来到 beta 版则会对未来的正式发布进行充分的“消化”,比如提前进行一些必要的 breaking change,增强框架的稳定性、完善文档和周边工具 (如 vue-router 2.0 等)

最后的几个 alpha 版本主要更新

Vue 本身的语法基础这里就不多赘述了,网上有很多资料可以查阅,我们已经假定你比较熟悉 Vue 并对 2.0 的理念和技术预览版的状态有一定的了解。

alpha 5

  1. ref 的写法由 <comp v-ref:foo> 变成了 <comp ref="foo">,更加简单,同时动态数据的写法是 <comp :ref="x">
  2. 支持 functional components,这个特性蛮酷的,可以把一个组件的生成过程完全变成一个高度自定义的函数执行过程,比如:

    Vue.component('name', { functional: true, props: ['x'], render: (h, props, children) { return h(props.tag, null, children) } })

你可以在 render() 函数里写各种特殊的逻辑,这样标签的含义和能力都得到了非常大的扩展,在后续的几次更新中,你马上会感受到一些 functional components 的威力

另外剧透一下,h 方法里的第二个参数如果是 null 就可以省略,这个改动出现在了 beta 1

alpha 6

可以设置特殊的 keyCode,比如 Vue.config.keyCodes.a = 65,然后你就可以写 <input @keyup.a="aPressed">

alpha7

  1. 一个组件的生命周期名由 init 改成了 beforeCreated (大家可以在 Vuex 的源码里看到对应的改变哦)
  2. Vue.transition 的 hook 支持第二个参数,把 vm 传递进去

如:

Vue.transition('name', {
    onEnter (el, vm) {
        ...
    }
})

Beta 1 ~ Beta 4

beta 1

  1. 自定义 directive 里 update 的触发时机发生了变化,由于 functional component 等概念的引入,一个 directive 的变更的颗粒度也不完全是 directive 本身引起的,所以这里做了一个更具有通用性的调整;同时 hook 名 postupdate 也相应的更名为 componentUpdated——如果你想让 update 保持原有的触发时机,可以加入一句 binding.value !== binding.oldValue 即可。
  2. Vue.traisition 的 hook 名做了简化
    • onEnter -> enter
    • onLeave -> leave
  3. server-side rendering
    • server.getCacheKey 更名为 serverCacheKey,避免多一层结构嵌套
    • createRenderer/createBundleRenderer 方法不会强制应用 lru-cache,而是开发者手动选择

beta 2

<transition> 标签来了!

其实这个玩意儿我之前在 polymer 等其他框架里也见到过,不过看到 Vue 的语法设计,还是觉得巧妙而简洁:

<transition>
    <div v-if="...">...</div>
</traisition>

<transition-group tag="ul">
    <li v-for="...">...</li>
</traisition-group>

更牛掰的在这里,还记得 functional components 吧,你今天可以这样抽象一个动画效果的标签:

Vue.component('fade', {
    functional: true,
    render (h, children) {
        return h('transition', {
            props: {...},
            on: {
                beforeEnter,
                afterEnter
            }
        }, children)
    }
})

然后

<fade>...</fade>

就可以实现高度自定义的动画效果了,这个我个人觉得是非常赞的设计和实现!

beta 3

  1. 支持在自定义组件中使用原生事件。因为在 Vue 2.0 的设计中,自定义组件上是不能绑定原生事件的,自定义组件上的事件绑定被默认理解为组件的自定义事件,而不是原生事件。针对这个问题我很早就提了 issue 当时小右提出了一个新的语法设计,就是 <comp @click.native="..."></comp>,beta 3 的时候终于看到它被实现了,嘿嘿,有点小激动
  2. 支持两种语法 <div :xxx.prop="x"><div v-bind:prop="{ xxx: x }"> 来对 DOM 的 property 进行绑定,最近我自己也在思考一些在 virtual-DOM 上支持 properties 而不只是 attributes 的想法,这个设计让我也多了一些新的思路。

beta 4

2 天前发布的,其实这个版本以 bugfix 为主

总结

以上是近期 Vue 2.0 的一些更新,让我自己比较兴奋的主要是 functional component 以及基于这个设计的 <transition><transition-group> 标签和自定义 transition 标签的能力拓展,还有就是久违的 <comp @click.native="..."></comp>

最后希望大家可以多多试用,有更大兴趣的可以多多学习 Vue 的源码!

通过一张图走进 Vue 2.0

这可能是字最少的一篇了,都在图里 - -

文字介绍稍后抽空再补补

Code Review for Vue 2.0 Preview

是的!Vue 2.0 发布了! 源代码仓库在此

首先,当我第一次看到 Vue 2.0 的真面目的时候,我的内心是非常激动的

Demo

来个简单的 demo,首先把 dist/vue.js 导入到一个空白的网页里,然后写:

当然,在大家阅读下面所有的内容之前,先想象一下,这是一个运行时 min+gzip 后只有 12kb 大小的库

<script src="./dist/vue.js"></script>

<div id="app">
  Hello {{who}}
</div>
<script>
  new Vue({
    el: '#app',
    data: {who: 'Vue'}
  })
</script>

你将看到 "Hello Vue"

然后再看一个神奇的:

<script src="./dist/vue.js"></script>

<div id="app"></div>
<script>
  new Vue({
    el: '#app',
    render: function () {
      with (this) {
        __h__('div',
          {staticAttrs:{"id":"app"}},
          [("\n  Hello "+__toString__(who)+"\n")],
          ''
        )
      }
    }
    data: {who: 'Vue'}
  })
</script>

这个是 compile 过后的格式,大家会发现首先 #app 下不需要写模板了,然后 <script> 里多了一个 render 字段,Vue 在运行时其实是会把模板内容先转换成渲染方法存入 render 字段,然后再执行,如果发现 render 已经存在,就跳过模板解析过程直接渲染。所以在 Vue 2.0 中写一段模板和写一个 render option 是等价的。为什么要这样设计,稍后会我们会涉及到。

阅读剩余部分...