diff options
Diffstat (limited to 'zh-cn')
| -rw-r--r-- | zh-cn/go-cn.html.markdown | 1 | ||||
| -rw-r--r-- | zh-cn/javascript-cn.html.markdown | 7 | ||||
| -rw-r--r-- | zh-cn/kotlin-cn.html.markdown | 33 | ||||
| -rw-r--r-- | zh-cn/make-cn.html.markdown | 262 | 
4 files changed, 281 insertions, 22 deletions
| diff --git a/zh-cn/go-cn.html.markdown b/zh-cn/go-cn.html.markdown index 75498367..37b4b137 100644 --- a/zh-cn/go-cn.html.markdown +++ b/zh-cn/go-cn.html.markdown @@ -142,6 +142,7 @@ func learnTypes() {  func learnNamedReturns(x, y int) (z int) {      z = x * y      return // z is implicit here, because we named it earlier. +}  // Go全面支持垃圾回收。Go有指针,但是不支持指针运算。  // 你会因为空指针而犯错,但是不会因为增加指针而犯错。 diff --git a/zh-cn/javascript-cn.html.markdown b/zh-cn/javascript-cn.html.markdown index bdef0099..360f7c65 100644 --- a/zh-cn/javascript-cn.html.markdown +++ b/zh-cn/javascript-cn.html.markdown @@ -12,12 +12,9 @@ translators:  lang: zh-cn  --- -Javascript于1995年由网景公司的Brendan Eich发明。 -最初发明的目的是作为一个简单的网站脚本语言,来作为 -复杂网站应用java的补充。但由于它与网页结合度很高并且由浏览器内置支持, -所以javascript变得比java在前端更为流行了。 +Javascript 于 1995 年由网景公司的 Brendan Eich 发明。最初它作为一种简单的,用于开发网站的脚本语言而被发明出来,是用于开发复杂网站的 Java 的补充。但由于它与网页结合度很高并且在浏览器中得到内置的支持,所以在网页前端领域 Javascript 变得比 Java 更流行了。 -不过 JavaScript 可不仅仅只用于浏览器: Node.js,一个基于Google Chrome V8引擎的独立运行时环境,也越来越流行。 +不过,Javascript 不仅用于网页浏览器,一个名为 Node.js 的项目提供了面向 Google Chrome V8 引擎的独立运行时环境,它正在变得越来越流行。  很欢迎来自您的反馈,您可以通过下列方式联系到我:  [@adambrenecki](https://twitter.com/adambrenecki), 或者 diff --git a/zh-cn/kotlin-cn.html.markdown b/zh-cn/kotlin-cn.html.markdown index 5d655029..f6dcd847 100644 --- a/zh-cn/kotlin-cn.html.markdown +++ b/zh-cn/kotlin-cn.html.markdown @@ -22,7 +22,7 @@ package com.learnxinyminutes.kotlin  /*  Kotlin程序的入口点是一个"main"函数 -该函数传递一个包含任何命令行参数的数组。 +该函数传递一个包含所有命令行参数的数组。  */  fun main(args: Array<String>) {      /* @@ -67,10 +67,10 @@ fun helloWorld(val name : String) {      模板表达式从一个美元符号($)开始。      */      val fooTemplateString = "$fooString has ${fooString.length} characters" -    println(fooTemplateString) +    println(fooTemplateString) // => 输出 My String Is Here! has 18 characters      /* -    当某个变量的值可以为 null 的时候,我们必须被明确指定它是可为空的。 +    当某个变量的值可以为 null 的时候,我们必须明确指定它是可为空的。      在变量声明处的类型后面加上?来标识它是可为空的。      我们可以用?.操作符来访问可为空的变量。      我们可以用?:操作符来指定一个在变量为空时使用的替代值。 @@ -96,24 +96,24 @@ fun helloWorld(val name : String) {      println(hello()) // => Hello, world!      /* -    用"vararg"关键字来修饰一个函数的参数来允许可变参数传递给该函数 +    函数的可变参数可使用 "vararg" 关键字来修饰      */      fun varargExample(vararg names: Int) {          println("Argument has ${names.size} elements")      } -    varargExample() // => Argument has 0 elements -    varargExample(1) // => Argument has 1 elements -    varargExample(1, 2, 3) // => Argument has 3 elements +    varargExample() // => 传入 0 个参数 +    varargExample(1) // => 传入 1 个参数 +    varargExample(1, 2, 3) // => 传入 3 个参数      /* -    当函数只包含一个单独的表达式时,大括号可以被省略。 -    函数体可以被指定在一个=符号后面。 +    当函数只包含一个单独的表达式时,大括号可以省略。 +    函数体可以写在一个=符号后面。      */      fun odd(x: Int): Boolean = x % 2 == 1      println(odd(6)) // => false      println(odd(7)) // => true -    // 如果返回值类型可以被推断,那么我们不需要指定它。 +    // 如果返回值类型可以推断,那么我们不需要指定它。      fun even(x: Int) = x % 2 == 0      println(even(6)) // => true      println(even(7)) // => false @@ -122,15 +122,14 @@ fun helloWorld(val name : String) {      fun not(f: (Int) -> Boolean) : (Int) -> Boolean {          return {n -> !f.invoke(n)}      } -    // 命名函数可以用::运算符被指定为参数。 +    // 普通函数可以用::运算符传入引用作为函数参数。      val notOdd = not(::odd)      val notEven = not(::even) -    // 匿名函数可以被指定为参数。 +    // lambda 表达式可以直接作为参数传递。      val notZero = not {n -> n == 0}      /* -    如果一个匿名函数只有一个参数 -    那么它的声明可以被省略(连同->)。 -    这个参数的名字是"it"。 +    如果一个 lambda 表达式只有一个参数 +    那么它的声明可以省略(连同->),内部以 "it" 引用。      */      val notPositive = not {it > 0}      for (i in 0..4) { @@ -152,7 +151,7 @@ fun helloWorld(val name : String) {      注意,Kotlin没有"new"关键字。      */      val fooExampleClass = ExampleClass(7) -    // 可以使用一个点号来调用成员函数。 +    // 可以使用一个点号来调用成员方法。      println(fooExampleClass.memberFunction(4)) // => 11      /*      如果使用"infix"关键字来标记一个函数 @@ -162,7 +161,7 @@ fun helloWorld(val name : String) {      /*      数据类是创建只包含数据的类的一个简洁的方法。 -    "hashCode"、"equals"和"toString"方法将被自动生成。 +    "hashCode"、"equals"和"toString"方法将自动生成。      */      data class DataClassExample (val x: Int, val y: Int, val z: Int)      val fooData = DataClassExample(1, 2, 4) diff --git a/zh-cn/make-cn.html.markdown b/zh-cn/make-cn.html.markdown new file mode 100644 index 00000000..4cdf1e63 --- /dev/null +++ b/zh-cn/make-cn.html.markdown @@ -0,0 +1,262 @@ +--- +language: make +contributors: +- ["Robert Steed", "https://github.com/robochat"] +- ["Jichao Ouyang", "https://github.com/jcouyang"] +translators: +- ["Jichao Ouyang", "https://github.com/jcouyang"] +filename: Makefile-cn +lang: zh-cn +--- + +Makefile 用于定义如何创建目标文件, 比如如何从源码到可执行文件. 创建这一工具的目标是 +减少不必要的编译或者任务.是传说中的 Stuart Feldman 在 1976 年花了一个周末写出来的,  +而今仍然使用广泛, 特别是在 Unix 和 Linux 系统上. + +虽然每个语言可能都有相应的或多或少提供 make 的功能, 比如 ruby 的 rake, node 的 gulp, broccoli +, scala 的 sbt 等等. 但是 make 的简洁与高效, 和只做一件事并做到极致的风格, 使其至今仍是无可替代的, +甚至与其他构建工具一起使用也并无冲突. + +尽管有许多的分支和变体, 这篇文章针对是标准的 GNU make. + +```make +# 这行表示注释 + +# 文件名一定要交 Makefile, 大小写区分, 使用 `make <target>` 生成 target +# 如果想要取别的名字, 可以用 `make -f "filename" <target>`. + +# 重要的事情 - 只认识 TAB, 空格是不认的, 但是在 GNU Make 3.82 之后, 可以通过 +# 设置参数 .RECIPEPREFIX 进行修改 + +#----------------------------------------------------------------------- +# 初级 +#----------------------------------------------------------------------- + +# 创建一个 target 的规则非常简单 +# targets : prerequisites +# 	recipe +# 	 … +# prerequisites(依赖) 是可选的, recipe(做法) 也可以多个或者不给. + +# 下面这个任务没有给 prerequisites, 只会在目标文件 file0.txt 文件不存在是跑 +file0.txt: +	echo "foo" > file0.txt +	# 试试 `make file0.txt` +	# 或者直接 `make`, 因为第一个任务是默认任务. +	# 注意: 即使是这些注释, 如果前面有 TAB, 也会发送给 shell, 注意看 `make file0.txt` 输出 + +# 如果提供 prerequisites, 则只有 prerequisites 比 target 新时会执行 +# 比如下面这个任务只有当 file1.txt 比 file0.txt 新时才会执行. +file1.txt: file0.txt +	cat file0.txt > file1.txt +	# 这里跟shell里的命令式一毛一样的. +	@cat file0.txt >> file1.txt +	# @ 不会把命令往 stdout 打印. +	-@echo 'hello' +	# - 意思是发生错误了也没关系. +	# 试试 `make file1.txt` 吧. + +# targets 和 prerequisites 都可以是多个, 以空格分割 +file2.txt file3.txt: file0.txt file1.txt +	touch file2.txt +	touch file3.txt + +# 如果声明重复的 target, make 会给一个 warning, 后面会覆盖前面的 +# 比如重复定义 file2.txt 会得到这样的 warning +# Makefile:46: warning: overriding commands for target `file2.txt' +# Makefile:40: warning: ignoring old commands for target `file2.txt' +file2.txt: file0.txt +	touch file2.txt + +# 但是如果不定义任何 recipe, 就不会冲突, 只是多了依赖关系 +file2.txt: file0.txt file3.txt + +#----------------------------------------------------------------------- +# Phony(假的) Targets +#----------------------------------------------------------------------- + +# phony targets 意思是 tagets 并不是文件, 可以想象成一个任务的名字而已. +# 因为不是文件, 无法比对是否有更新, 所以每次make都会执行. +all: maker process + +# 依赖于 phony target 的 target 也会每次 make 都执行, 即使 target 是文件 +ex0.txt ex1.txt: maker + +# target 的声明顺序并不重要, 比如上面的 all 的依赖 maker 现在才声明 +maker: +	touch ex0.txt ex1.txt + +# 如果定义的 phony target 与文件名重名, 可以用 .PHONY 显示的指明哪些 targets 是 phony +.PHONY: all maker process +# This is a special target. There are several others. + +# 常用的 phony target 有: all clean install ... + +#----------------------------------------------------------------------- +# 变量与通配符 +#----------------------------------------------------------------------- + +process: file*.txt | dir/a.foo.b	# 可以用通配符匹配多个文件作为prerequisites +	@echo $^	# $^ 是 prerequisites +	@echo $@	# $@ 代表 target, 如果 target 为多个, $@ 代表当前执行的那个 +	@echo $<	# $< prerequisite 中的第一个 +	@echo $?	# $? 需要更新的 prerequisite 文件列表 +	@echo $+	# $+ 所有依赖, 包括重复的 +	@echo $|	# $| 竖线后面的 order-only prerequisites + +a.%.b: +	@echo $*  # $* match 的target % 那部分, 包括路径, 比如 `make dir/a.foo.b` 会打出 `dir/foo` + +# 即便分开定义依赖, $^ 依然能拿到 +process: ex1.txt file0.txt +# 非常智能的, ex1.txt 会被找到, file0.txt 会被去重. + +#----------------------------------------------------------------------- +# 模式匹配 +#----------------------------------------------------------------------- + +# 可以让 make 知道如何转换某些文件到别格式 +# 比如 从 svg 到 png +%.png: %.svg +	inkscape --export-png $^ + +# 一旦有需要 foo.png 这个任务就会运行 + +# 路径会被忽略, 所以上面的 target 能匹配所有 png +# 但是如果加了路径, make 会找到最接近的匹配, 如果 +# make small/foo.png (在这之前要先有 small/foo.svg 这个文件) +# 则会匹配下面这个规则 +small/%.png: %.svg +	inkscape --export-png --export-dpi 30 $^ + +%.png: %.svg +	@echo 重复定义会覆盖前面的, 现在 inkscape 没用了 + +# make 已经有一些内置的规则, 比如从 *.c 到 *.o + +#----------------------------------------------------------------------- +# 变量 +#----------------------------------------------------------------------- +# 其实是宏 macro + +# 变量都是字符串类型, 下面这俩是一样一样的 + +name = Ted +name2="Sarah" + +echo: +	@echo $(name) +	@echo ${name2} +	@echo $name    # 这个会被蠢蠢的解析成 $(n)ame. +	@echo \"$(name3)\" # 为声明的变量或扩展成空字符串. +	@echo $(name4) +	@echo $(name5) +# 你可以通过4种方式设置变量. +# 按以下顺序由高到低: +# 1: 命令行参数. 比如试试 `make echo name3=JICHAO` +# 2: Makefile 里面的 +# 3: shell 中的环境变量 +# 4: make 预设的一些变量 + +name4 ?= Jean +# 问号意思是如果 name4 被设置过了, 就不设置了. + +override name5 = David +# 用 override 可以防止命令行参数设置的覆盖 + +name4 +=grey +# 用加号可以连接 (中间用空格分割). + +# 在依赖的地方设置变量 +echo: name2 = Sara2 + +# 还有一些内置的变量 +echo_inbuilt: +	echo $(CC) +	echo ${CXX)} +	echo $(FC) +	echo ${CFLAGS)} +	echo $(CPPFLAGS) +	echo ${CXXFLAGS} +	echo $(LDFLAGS) +	echo ${LDLIBS} + +#----------------------------------------------------------------------- +# 变量 2 +#----------------------------------------------------------------------- + +# 加个冒号可以声明 Simply expanded variables 即时扩展变量, 即只在声明时扩展一次 +# 之前的等号声明时 recursively expanded 递归扩展 + +var := hello +var2 :=  $(var) hello + +# 这些变量会在其引用的顺序求值 +# 比如 var3 声明时找不到 var4, var3 会扩展成 `and good luck` +var3 := $(var4) and good luck +# 但是一般的变量会在调用时递归扩展, 先扩展 var5, 再扩展 var4, 所以是正常的 +var5 = $(var4) and good luck +var4 := good night + +echoSEV: +	@echo $(var) +	@echo $(var2) +	@echo $(var3) +	@echo $(var4) +	@echo $(var5) + +#----------------------------------------------------------------------- +# 函数 +#----------------------------------------------------------------------- + +# make 自带了一些函数. +# wildcard 会将后面的通配符变成一串文件路径 +all_markdown: +	@echo $(wildcard *.markdown) +# patsubst 可以做替换, 比如下面会把所有 markdown +# 后缀的文件重命名为 md 后缀 +substitue: * +	@echo $(patsubst %.markdown,%.md,$* $^) + +# 函数调用格式是 $(func arg0,arg1,arg2...) + +# 试试 +ls:	* +	@echo $(filter %.txt, $^) +	@echo $(notdir $^) +	@echo $(join $(dir $^),$(notdir $^)) + +#----------------------------------------------------------------------- +# Directives +#----------------------------------------------------------------------- + +# 可以用 include 引入别的 Makefile 文件 +# include foo.mk + +sport = tennis +# 一些逻辑语句 if else 什么的, 顶个写 +report: +ifeq ($(sport),tennis) +	@echo 'game, set, match' +else +	@echo "They think it's all over; it is now" +endif + +# 还有 ifneq, ifdef, ifndef + +foo = true + +# 不只是 recipe, 还可以写在外面哟 +ifdef $(foo) +bar = 'bar' +endif + +hellobar: +	@echo bar +``` + +### 资源 + ++ GNU Make 官方文档 [HTML](https://www.gnu.org/software/make/manual/) [PDF](https://www.gnu.org/software/make/manual/make.pdf) ++ [software carpentry tutorial](http://swcarpentry.github.io/make-novice/) ++ learn C the hard way [ex2](http://c.learncodethehardway.org/book/ex2.html) [ex28](http://c.learncodethehardway.org/book/ex28.html) | 
