diff options
author | woclass <inkydragon@users.noreply.github.com> | 2018-12-03 20:30:45 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-12-03 20:30:45 +0800 |
commit | cd7816a2be62b0dcd2aca181d1aadd68b8e4d5d7 (patch) | |
tree | f75c300c92d40e29bf59f83775aec019b45e56e7 /zh-cn | |
parent | 440247a59706603bd980016821ecd6a72a6182d1 (diff) | |
parent | 1fd955ae6479650b987a54a93b09507bfdf06954 (diff) |
Merge pull request #1 from adambard/master
Update from Upstream
Diffstat (limited to 'zh-cn')
-rw-r--r-- | zh-cn/awk-cn.html.markdown | 326 | ||||
-rw-r--r-- | zh-cn/c++-cn.html.markdown | 6 | ||||
-rw-r--r-- | zh-cn/c-cn.html.markdown | 2 | ||||
-rw-r--r-- | zh-cn/clojure-macro-cn.html.markdown | 10 | ||||
-rw-r--r-- | zh-cn/dart-cn.html.markdown | 44 | ||||
-rw-r--r-- | zh-cn/git-cn.html.markdown | 2 | ||||
-rw-r--r-- | zh-cn/julia-cn.html.markdown | 917 | ||||
-rw-r--r-- | zh-cn/markdown-cn.html.markdown | 238 | ||||
-rw-r--r-- | zh-cn/matlab-cn.html.markdown | 47 | ||||
-rw-r--r-- | zh-cn/python3-cn.html.markdown | 48 | ||||
-rw-r--r-- | zh-cn/swift-cn.html.markdown | 18 | ||||
-rw-r--r-- | zh-cn/typescript-cn.html.markdown | 132 |
12 files changed, 1189 insertions, 601 deletions
diff --git a/zh-cn/awk-cn.html.markdown b/zh-cn/awk-cn.html.markdown new file mode 100644 index 00000000..3fea782b --- /dev/null +++ b/zh-cn/awk-cn.html.markdown @@ -0,0 +1,326 @@ +--- +language: awk +contributors: + - ["Marshall Mason", "http://github.com/marshallmason"] +translators: + - ["Tian Zhipeng", "https://github.com/tianzhipeng-git"] +filename: learnawk-cn.awk +lang: zh-cn +--- + +AWK是POSIX兼容的UNIX系统中的标准工具. 它像简化版的Perl, 非常适用于文本处理任务和其他脚本类需求. +它有着C风格的语法, 但是没有分号, 没有手动内存管理, 没有静态类型. +他擅长于文本处理, 你可以通过shell脚本调用AWK, 也可以用作独立的脚本语言. + +为什么使用AWK而不是Perl, 大概是因为AWK是UNIX的一部分, 你总能依靠它, 而Perl已经前途未卜了. +AWK比Perl更易读. 对于简单的文本处理脚本, 特别是按行读取文件, 按分隔符分隔处理, AWK极可能是正确的工具. + +```awk +#!/usr/bin/awk -f + +# 注释使用井号 + +# AWK程序由一系列 模式(patterns) 和 动作(actions) 组成. +# 最重要的模式叫做 BEGIN. 动作由大括号包围. +BEGIN { + + # BEGIN在程序最开始运行. 在这里放一些在真正处理文件之前的准备和setup的代码. + # 如果没有文本文件要处理, 那就把BEGIN作为程序的主入口吧. + + # 变量是全局的. 直接赋值使用即可, 无需声明. + count = 0 + + # 运算符和C语言系一样 + a = count + 1 + b = count - 1 + c = count * 1 + d = count / 1 # 整数除法 + e = count % 1 # 取余 + f = count ^ 1 # 取幂 + + a += 1 + b -= 1 + c *= 1 + d /= 1 + e %= 1 + f ^= 1 + + # 自增1, 自减1 + a++ + b-- + + # 前置运算, 返回增加之后的值 + ++a + --b + + # 注意, 不需要分号之类的标点来分隔语句 + + # 控制语句 + if (count == 0) + print "Starting with count of 0" + else + print "Huh?" + + # 或者三目运算符 + print (count == 0) ? "Starting with count of 0" : "Huh?" + + # 多行的代码块用大括号包围 + while (a < 10) { + print "String concatenation is done" " with a series" " of" + " space-separated strings" + print a + + a++ + } + + for (i = 0; i < 10; i++) + print "Good ol' for loop" + + # 标准的比较运算符 + a < b # 小于 + a <= b # 小于或等于 + a != b # 不等于 + a == b # 等于 + a > b # 大于 + a >= b # 大于或等于 + + # 也有逻辑运算符 + a && b # 且 + a || b # 或 + + # 并且有超实用的正则表达式匹配 + if ("foo" ~ "^fo+$") + print "Fooey!" + if ("boo" !~ "^fo+$") + print "Boo!" + + # 数组 + arr[0] = "foo" + arr[1] = "bar" + # 不幸的是, 没有其他方式初始化数组. 必须像这样一行一行的赋值. + + # 关联数组, 类似map或dict的用法. + assoc["foo"] = "bar" + assoc["bar"] = "baz" + + # 多维数组. 但是有一些局限性这里不提了. + multidim[0,0] = "foo" + multidim[0,1] = "bar" + multidim[1,0] = "baz" + multidim[1,1] = "boo" + + # 可以检测数组包含关系 + if ("foo" in assoc) + print "Fooey!" + + # 可以使用in遍历数组 + for (key in assoc) + print assoc[key] + + # 命令行参数是一个叫ARGV的数组 + for (argnum in ARGV) + print ARGV[argnum] + + # 可以从数组中移除元素 + # 在 防止awk把文件参数当做数据来处理 时delete功能很有用. + delete ARGV[1] + + # 命令行参数的个数是一个叫ARGC的变量 + print ARGC + + # AWK有很多内置函数, 分为三类, 会在接下来定义的各个函数中介绍. + + return_value = arithmetic_functions(a, b, c) + string_functions() + io_functions() +} + +# 定义函数 +function arithmetic_functions(a, b, c, d) { + + # 或许AWK最让人恼火的地方是没有局部变量, 所有东西都是全局的, + # 对于短的脚本还好, 对于长一些的就会成问题. + + # 这里有一个技巧, 函数参数是对函数局部可见的, 并且AWK允许定义多余的参数, + # 因此可以像上面那样把局部变量插入到函数声明中. + # 为了方便区分普通参数(a,b,c)和局部变量(d), 可以多键入一些空格. + + # 现在介绍数学类函数 + + # 多数AWK实现中包含标准的三角函数 + localvar = sin(a) + localvar = cos(a) + localvar = atan2(a, b) # arc tangent of b / a + + # 对数 + localvar = exp(a) + localvar = log(a) + + # 平方根 + localvar = sqrt(a) + + # 浮点型转为整型 + localvar = int(5.34) # localvar => 5 + + # 随机数 + srand() # 接受随机种子作为参数, 默认使用当天的时间 + localvar = rand() # 0到1之间随机 + + # 函数返回 + return localvar +} + +function string_functions( localvar, arr) { + + # AWK, 作为字符处理语言, 有很多字符串相关函数, 其中大多数都严重依赖正则表达式. + + # 搜索并替换, 第一个出现的 (sub) or 所有的 (gsub) + # 都是返回替换的个数 + localvar = "fooooobar" + sub("fo+", "Meet me at the ", localvar) # localvar => "Meet me at the bar" + gsub("e+", ".", localvar) # localvar => "m..t m. at th. bar" + + # 搜索匹配正则的字符串 + # index() 也是搜索, 不支持正则 + match(localvar, "t") # => 4, 't'在4号位置. + # (译者注: awk是1开始计数的,不是常见的0-base) + + # 按分隔符分隔 + split("foo-bar-baz", arr, "-") # a => ["foo", "bar", "baz"] + + # 其他有用的函数 + sprintf("%s %d %d %d", "Testing", 1, 2, 3) # => "Testing 1 2 3" + substr("foobar", 2, 3) # => "oob" + substr("foobar", 4) # => "bar" + length("foo") # => 3 + tolower("FOO") # => "foo" + toupper("foo") # => "FOO" +} + +function io_functions( localvar) { + + # 你已经见过的print函数 + print "Hello world" + + # 也有printf + printf("%s %d %d %d\n", "Testing", 1, 2, 3) + + # AWK本身没有文件句柄, 当你使用需要文件的东西时会自动打开文件, + # 做文件I/O时, 字符串就是打开的文件句柄. 这看起来像Shell + print "foobar" >"/tmp/foobar.txt" + + # 现在"/tmp/foobar.txt"字符串是一个文件句柄, 你可以关闭它 + close("/tmp/foobar.txt") + + # 在shell里运行一些东西 + system("echo foobar") # => prints foobar + + # 从标准输入中读一行, 并存储在localvar中 + getline localvar + + # 从管道中读一行, 并存储在localvar中 + "echo foobar" | getline localvar # localvar => "foobar" + close("echo foobar") + + # 从文件中读一行, 并存储在localvar中 + getline localvar <"/tmp/foobar.txt" + close("/tmp/foobar.txt") +} + +# 正如开头所说, AWK程序由一系列模式和动作组成. 你已经看见了重要的BEGIN pattern, +# 其他的pattern在你需要处理来自文件或标准输入的的数据行时才用到. +# +# 当你给AWK程序传参数时, 他们会被视为要处理文件的文件名, 按顺序全部会处理. +# 可以把这个过程看做一个隐式的循环, 遍历这些文件中的所有行. +# 然后这些模式和动作就是这个循环里的switch语句一样 + +/^fo+bar$/ { + + # 这个动作会在匹配这个正则(/^fo+bar$/)的每一行上执行. 不匹配的则会跳过. + # 先让我们打印它: + print + + # 哦, 没有参数, 那是因为print有一个默认参数 $0. + # $0 是当前正在处理的行, 自动被创建好了. + + # 你可能猜到有其他的$变量了. + # 每一行在动作执行前会被分隔符分隔. 像shell中一样, 每个字段都可以用$符访问 + + # 这个会打印这行的第2和第4个字段 + print $2, $4 + + # AWK自动定义了许多其他的变量帮助你处理行. 最常用的是NF变量 + # 打印这一行的字段数 + print NF + + # 打印这一行的最后一个字段 + print $NF +} + +# 每一个模式其实是一个true/false判断, 上面那个正则其实也是一个true/false判断, 只不过被部分省略了. +# 没有指定时默认使用当前处理的整行($0)进行匹配. 因此, 完全版本是这样: + +$0 ~ /^fo+bar$/ { + print "Equivalent to the last pattern" +} + +a > 0 { + # 只要a是整数, 这块会在每一行上执行. +} + +# 就是这样, 处理文本文件, 一次读一行, 对行做一些操作. +# 按分隔符分隔, 这在UNIX中很常见, awk都帮你做好了. +# 你所需要做的是基于自己的需求写一些模式和动作. + +# 这里有一个快速的例子, 展示了AWK所擅长做的事. +# 它从标准输入读一个名字, 打印这个first name下所有人的平均年龄. +# 示例数据: +# +# Bob Jones 32 +# Jane Doe 22 +# Steve Stevens 83 +# Bob Smith 29 +# Bob Barker 72 +# +# 示例脚本: + +BEGIN { + + # 首先, 问用户要一个名字 + print "What name would you like the average age for?" + + # 从标准输入获取名字 + getline name <"/dev/stdin" +} + +# 然后, 用给定的名字匹配每一行的第一个字段. +$1 == name { + + # 这里我们要使用几个有用的变量, 已经提前为我们加载好的: + # $0 是整行 + # $3 是第三个字段, 就是我们所感兴趣的年龄 + # NF 字段数, 这里是3 + # NR 至此为止的行数 + # FILENAME 在处理的文件名 + # FS 在使用的字段分隔符, 这里是空格" " + # ...等等, 还有很多, 在帮助文档中列出. + + # 跟踪 总和以及行数 + sum += $3 + nlines++ +} + +# 另一个特殊的模式叫END. 它会在处理完所有行之后运行. 不像BEGIN, 它只会在有输入的时候运行. +# 它在所有文件依据给定的模式和动作处理完后运行, 目的通常是输出一些最终报告, 做一些数据聚合操作. + +END { + if (nlines) + print "The average age for " name " is " sum / nlines +} + +``` +更多: + +* [Awk 教程](http://www.grymoire.com/Unix/Awk.html) +* [Awk 手册](https://linux.die.net/man/1/awk) +* [The GNU Awk 用户指南](https://www.gnu.org/software/gawk/manual/gawk.html) GNU Awk在大多数Linux中预装 diff --git a/zh-cn/c++-cn.html.markdown b/zh-cn/c++-cn.html.markdown index 87951bc3..e0d6b6fe 100644 --- a/zh-cn/c++-cn.html.markdown +++ b/zh-cn/c++-cn.html.markdown @@ -567,6 +567,6 @@ void doSomethingWithAFile(const std::string& filename) ```
扩展阅读:
-<http://cppreference.com/w/cpp> 提供了最新的语法参考。
-
-可以在 <http://cplusplus.com> 找到一些补充资料。
+* [CPP Reference](http://cppreference.com/w/cpp) 提供了最新的语法参考。
+* 可以在 [CPlusPlus](http://cplusplus.com) 找到一些补充资料。
+* 可以在 [TheChernoProject - C ++](https://www.youtube.com/playlist?list=PLlrATfBNZ98dudnM48yfGUldqGD0S4FFb)上找到涵盖语言基础和设置编码环境的教程。
diff --git a/zh-cn/c-cn.html.markdown b/zh-cn/c-cn.html.markdown index 02ec7f7b..8566e811 100644 --- a/zh-cn/c-cn.html.markdown +++ b/zh-cn/c-cn.html.markdown @@ -41,7 +41,7 @@ enum days {SUN = 1, MON, TUE, WED, THU, FRI, SAT}; void function_1(char c); void function_2(void); -// 如果函数调用在main()之后,那么必须在main()之前 +// 如果函数调用在main()之后,那么必须声明在main()之前 // 先声明一个函数原型 int add_two_ints(int x1, int x2); // 函数原型 diff --git a/zh-cn/clojure-macro-cn.html.markdown b/zh-cn/clojure-macro-cn.html.markdown index 9324841e..23b2f203 100644 --- a/zh-cn/clojure-macro-cn.html.markdown +++ b/zh-cn/clojure-macro-cn.html.markdown @@ -142,11 +142,9 @@ lang: zh-cn ## 扩展阅读 -[Clojure for the Brave and True](http://www.braveclojure.com/)系列的编写宏 -http://www.braveclojure.com/writing-macros/ +[Clojure for the Brave and True](http://www.braveclojure.com/) +[系列的编写宏](http://www.braveclojure.com/writing-macros/) -官方文档 -http://clojure.org/macros +[官方文档](http://clojure.org/macros) -何时使用宏? -http://dunsmor.com/lisp/onlisp/onlisp_12.html +[何时使用宏?](https://lispcast.com/when-to-use-a-macro/) diff --git a/zh-cn/dart-cn.html.markdown b/zh-cn/dart-cn.html.markdown index b0287f0c..79db8e5c 100644 --- a/zh-cn/dart-cn.html.markdown +++ b/zh-cn/dart-cn.html.markdown @@ -176,23 +176,47 @@ example13() { match(s2); } -// 布尔表达式必需被解析为 true 或 false, -// 因为不支持隐式转换。 +// 布尔表达式支持隐式转换以及动态类型 example14() { - var v = true; - if (v) { - print("Example14 value is true"); + var a = true; + if (a) { + print("Example14 true, a is $a"); } - v = null; + a = null; + if (a) { + print("Example14 true, a is $a"); + } else { + print("Example14 false, a is $a"); // 执行到这里 + } + + // 动态类型的null可以转换成bool型 + var b;// b是动态类型 + b = "abc"; try { - if (v) { - // 不会执行 + if (b) { + print("Example14 true, b is $b"); } else { - // 不会执行 + print("Example14 false, b is $b"); } } catch (e) { - print("Example14 null value causes an exception: '${e}'"); + print("Example14 error, b is $b"); // 这段代码可以执行但是会报错 } + b = null; + if (b) { + print("Example14 true, b is $b"); + } else { + print("Example14 false, b is $b"); // 这行到这里 + } + + // 静态类型的null不能转换成bool型 + var c = "abc"; + c = null; + // 编译出错 + // if (c) { + // print("Example14 true, c is $c"); + // } else { + // print("Example14 false, c is $c"); + // } } // try/catch/finally 和 throw 语句用于异常处理。 diff --git a/zh-cn/git-cn.html.markdown b/zh-cn/git-cn.html.markdown index 4ef3ffb8..d471ab5d 100644 --- a/zh-cn/git-cn.html.markdown +++ b/zh-cn/git-cn.html.markdown @@ -131,7 +131,7 @@ $ git help init ```bash -# 显示分支,为跟踪文件,更改和其他不同 +# 显示分支,未跟踪文件,更改和其他不同 $ git status # 查看其他的git status的用法 diff --git a/zh-cn/julia-cn.html.markdown b/zh-cn/julia-cn.html.markdown index 1f91d52c..b350b6dc 100644 --- a/zh-cn/julia-cn.html.markdown +++ b/zh-cn/julia-cn.html.markdown @@ -2,16 +2,24 @@ language: Julia filename: learn-julia-zh.jl contributors: - - ["Jichao Ouyang", "http://oyanglul.us"] + - ["Leah Hanson", "http://leahhanson.us"] + - ["Pranit Bauva", "https://github.com/pranitbauva1997"] + - ["Daniel YC Lin", "https://github.com/dlintw"] translators: - ["Jichao Ouyang", "http://oyanglul.us"] + - ["woclass", "https://github.com/inkydragon"] lang: zh-cn --- -```ruby -# 单行注释只需要一个井号 +Julia 是一种新的同像函数式编程语言(homoiconic functional language),它专注于科学计算领域。 +虽然拥有同像宏(homoiconic macros)、一级函数(first-class functions)和底层控制等全部功能,但 Julia 依旧和 Python 一样易于学习和使用。 + +示例代码基于 Julia 1.0.0 + +```julia +# 单行注释只需要一个井号「#」 #= 多行注释 - 只需要以 '#=' 开始 '=#' 结束 + 只需要以「#=」开始「=#」结束 还可以嵌套. =# @@ -19,41 +27,41 @@ lang: zh-cn ## 1. 原始类型与操作符 #################################################### -# Julia 中一切皆是表达式。 - -# 这是一些基本数字类型. -3 # => 3 (Int64) -3.2 # => 3.2 (Float64) -2 + 1im # => 2 + 1im (Complex{Int64}) -2//3 # => 2//3 (Rational{Int64}) - -# 支持所有的普通中缀操作符。 -1 + 1 # => 2 -8 - 1 # => 7 -10 * 2 # => 20 -35 / 5 # => 7.0 -5 / 2 # => 2.5 # 用 Int 除 Int 永远返回 Float -div(5, 2) # => 2 # 使用 div 截断小数点 -5 \ 35 # => 7.0 -2 ^ 2 # => 4 # 次方, 不是二进制 xor -12 % 10 # => 2 +# Julia 中一切皆为表达式 + +# 这是一些基本数字类型 +typeof(3) # => Int64 +typeof(3.2) # => Float64 +typeof(2 + 1im) # => Complex{Int64} +typeof(2 // 3) # => Rational{Int64} + +# 支持所有的普通中缀操作符 +1 + 1 # => 2 +8 - 1 # => 7 +10 * 2 # => 20 +35 / 5 # => 7.0 +10 / 2 # => 5.0 # 整数除法总是返回浮点数 +div(5, 2) # => 2 # 使用 div 可以获得整除的结果 +5 \ 35 # => 7.0 +2^2 # => 4 # 幂运算,不是异或 (xor) +12 % 10 # => 2 # 用括号提高优先级 (1 + 3) * 2 # => 8 -# 二进制操作符 -~2 # => -3 # 非 -3 & 5 # => 1 # 与 -2 | 4 # => 6 # 或 -2 $ 4 # => 6 # 异或 -2 >>> 1 # => 1 # 逻辑右移 -2 >> 1 # => 1 # 算术右移 -2 << 1 # => 4 # 逻辑/算术 右移 - -# 可以用函数 bits 查看二进制数。 -bits(12345) +# 位操作符 +~2 # => -3 # 按位非 (not) +3 & 5 # => 1 # 按位与 (and) +2 | 4 # => 6 # 按位或 (or) +xor(2, 4) # => 6 # 按位异或 (xor) +2 >>> 1 # => 1 # 逻辑右移 +2 >> 1 # => 1 # 算术右移 +2 << 1 # => 4 # 逻辑/算术左移 + +# 可以用函数 bitstring 查看二进制数。 +bitstring(12345) # => "0000000000000000000000000000000000000000000000000011000000111001" -bits(12345.0) +bitstring(12345.0) # => "0100000011001000000111001000000000000000000000000000000000000000" # 布尔值是原始类型 @@ -61,40 +69,50 @@ true false # 布尔操作符 -!true # => false -!false # => true -1 == 1 # => true -2 == 1 # => false -1 != 1 # => false -2 != 1 # => true -1 < 10 # => true -1 > 10 # => false -2 <= 2 # => true -2 >= 2 # => true -# 比较可以串联 +!true # => false +!false # => true +1 == 1 # => true +2 == 1 # => false +1 != 1 # => false +2 != 1 # => true +1 < 10 # => true +1 > 10 # => false +2 <= 2 # => true +2 >= 2 # => true + +# 链式比较 1 < 2 < 3 # => true 2 < 3 < 2 # => false -# 字符串可以由 " 创建 +# 字符串可以由「"」创建 "This is a string." -# 字符字面量可用 ' 创建 +# 字符字面量可用「'」创建 'a' +# 字符串使用 UTF-8 编码 # 可以像取数组取值一样用 index 取出对应字符 -"This is a string"[1] # => 'T' # Julia 的 index 从 1 开始 :( -# 但是对 UTF-8 无效, -# 因此建议使用遍历器 (map, for loops, 等). +ascii("This is a string")[1] +# => 'T': ASCII/Unicode U+0054 (category Lu: Letter, uppercase) +# Julia 的 index 从 1 开始 :( +# 但只有在字符串仅由 ASCII 字符构成时,字符串才能够被安全的引索 +# 因此建议使用遍历器 (map, for loops, 等) # $ 可用于字符插值: "2 + 2 = $(2 + 2)" # => "2 + 2 = 4" # 可以将任何 Julia 表达式放入括号。 -# 另一种格式化字符串的方式是 printf 宏. -@printf "%d is less than %f" 4.5 5.3 # 5 is less than 5.300000 +# 另一种输出格式化字符串的方法是使用标准库 Printf 中的 Printf 宏 +using Printf +@printf "%d is less than %f\n" 4.5 5.3 # => 5 is less than 5.300000 # 打印字符串很容易 -println("I'm Julia. Nice to meet you!") +println("I'm Julia. Nice to meet you!") # => I'm Julia. Nice to meet you! + +# 字符串可以按字典序进行比较 +"good" > "bye" # => true +"good" == "good" # => true +"1 + 2 = 3" == "1 + 2 = $(1 + 2)" # => true #################################################### ## 2. 变量与集合 @@ -106,12 +124,12 @@ some_var # => 5 # 访问未声明变量会抛出异常 try - some_other_var # => ERROR: some_other_var not defined + some_other_var # => ERROR: UndefVarError: some_other_var not defined catch e println(e) end -# 变量名需要以字母开头. +# 变量名必须以下划线或字母开头 # 之后任何字母,数字,下划线,叹号都是合法的。 SomeOtherVar123! = 6 # => 6 @@ -122,66 +140,93 @@ SomeOtherVar123! = 6 # => 6 # 注意 Julia 的命名规约: # -# * 变量名为小写,单词之间以下划线连接('\_')。 +# * 名称可以用下划线「_」分割。 +# 不过一般不推荐使用下划线,除非不用变量名就会变得难于理解 # -# * 类型名以大写字母开头,单词以 CamelCase 方式连接。 +# * 类型名以大写字母开头,单词以 CamelCase 方式连接,无下划线。 # # * 函数与宏的名字小写,无下划线。 # -# * 会改变输入的函数名末位为 !。 +# * 会改变输入的函数名末位为「!」。 # 这类函数有时被称为 mutating functions 或 in-place functions. -# 数组存储一列值,index 从 1 开始。 -a = Int64[] # => 0-element Int64 Array +# 数组存储一列值,index 从 1 开始 +a = Int64[] # => 0-element Array{Int64,1} + +# 一维数组可以以逗号分隔值的方式声明 +b = [4, 5, 6] # => 3-element Array{Int64,1}: [4, 5, 6] +b = [4; 5; 6] # => 3-element Array{Int64,1}: [4, 5, 6] +b[1] # => 4 +b[end] # => 6 -# 一维数组可以以逗号分隔值的方式声明。 -b = [4, 5, 6] # => 包含 3 个 Int64 类型元素的数组: [4, 5, 6] -b[1] # => 4 -b[end] # => 6 +# 二维数组以分号分隔维度 +matrix = [1 2; 3 4] # => 2×2 Array{Int64,2}: [1 2; 3 4] -# 二维数组以分号分隔维度。 -matrix = [1 2; 3 4] # => 2x2 Int64 数组: [1 2; 3 4] +# 指定数组的类型 +b = Int8[4, 5, 6] # => 3-element Array{Int8,1}: [4, 5, 6] # 使用 push! 和 append! 往数组末尾添加元素 -push!(a,1) # => [1] -push!(a,2) # => [1,2] -push!(a,4) # => [1,2,4] -push!(a,3) # => [1,2,4,3] -append!(a,b) # => [1,2,4,3,4,5,6] +push!(a, 1) # => [1] +push!(a, 2) # => [1,2] +push!(a, 4) # => [1,2,4] +push!(a, 3) # => [1,2,4,3] +append!(a, b) # => [1,2,4,3,4,5,6] -# 用 pop 弹出末尾元素 -pop!(b) # => 6 and b is now [4,5] +# 用 pop 弹出尾部的元素 +pop!(b) # => 6 +b # => [4,5] -# 可以再放回去 -push!(b,6) # b 又变成了 [4,5,6]. +# 再放回去 +push!(b, 6) # => [4,5,6] +b # => [4,5,6] -a[1] # => 1 # 永远记住 Julia 的 index 从 1 开始! +a[1] # => 1 # 永远记住 Julia 的引索从 1 开始!而不是 0! -# 用 end 可以直接取到最后索引. 可用作任何索引表达式 +# 用 end 可以直接取到最后索引。它可以用在任何索引表达式中 a[end] # => 6 -# 还支持 shift 和 unshift -shift!(a) # => 返回 1,而 a 现在时 [2,4,3,4,5,6] -unshift!(a,7) # => [7,2,4,3,4,5,6] +# 数组还支持 popfirst! 和 pushfirst! +popfirst!(a) # => 1 +a # => [2,4,3,4,5,6] +pushfirst!(a, 7) # => [7,2,4,3,4,5,6] +a # => [7,2,4,3,4,5,6] # 以叹号结尾的函数名表示它会改变参数的值 -arr = [5,4,6] # => 包含三个 Int64 元素的数组: [5,4,6] -sort(arr) # => [4,5,6]; arr 还是 [5,4,6] -sort!(arr) # => [4,5,6]; arr 现在是 [4,5,6] +arr = [5,4,6] # => 3-element Array{Int64,1}: [5,4,6] +sort(arr) # => [4,5,6] +arr # => [5,4,6] +sort!(arr) # => [4,5,6] +arr # => [4,5,6] -# 越界会抛出 BoundsError 异常 +# 数组越界会抛出 BoundsError try - a[0] # => ERROR: BoundsError() in getindex at array.jl:270 - a[end+1] # => ERROR: BoundsError() in getindex at array.jl:270 + a[0] + # => ERROR: BoundsError: attempt to access 7-element Array{Int64,1} at + # index [0] + # => Stacktrace: + # => [1] getindex(::Array{Int64,1}, ::Int64) at .\array.jl:731 + # => [2] top-level scope at none:0 + # => [3] ... + # => in expression starting at ...\LearnJulia.jl:203 + a[end + 1] + # => ERROR: BoundsError: attempt to access 7-element Array{Int64,1} at + # index [8] + # => Stacktrace: + # => [1] getindex(::Array{Int64,1}, ::Int64) at .\array.jl:731 + # => [2] top-level scope at none:0 + # => [3] ... + # => in expression starting at ...\LearnJulia.jl:211 catch e println(e) end -# 错误会指出发生的行号,包括标准库 -# 如果你有 Julia 源代码,你可以找到这些地方 +# 报错时错误会指出出错的文件位置以及行号,标准库也一样 +# 你可以在 Julia 安装目录下的 share/julia 文件夹里找到这些标准库 # 可以用 range 初始化数组 -a = [1:5] # => 5-element Int64 Array: [1,2,3,4,5] +a = [1:5;] # => 5-element Array{Int64,1}: [1,2,3,4,5] +# 注意!分号不可省略 +a2 = [1:5] # => 1-element Array{UnitRange{Int64},1}: [1:5] # 可以切割数组 a[1:3] # => [1, 2, 3] @@ -189,11 +234,13 @@ a[2:end] # => [2, 3, 4, 5] # 用 splice! 切割原数组 arr = [3,4,5] -splice!(arr,2) # => 4 ; arr 变成了 [3,5] +splice!(arr, 2) # => 4 +arr # => [3,5] # 用 append! 连接数组 b = [1,2,3] -append!(a,b) # a 变成了 [1, 2, 3, 4, 5, 1, 2, 3] +append!(a, b) # => [1, 2, 3, 4, 5, 1, 2, 3] +a # => [1, 2, 3, 4, 5, 1, 2, 3] # 检查元素是否在数组中 in(1, a) # => true @@ -201,240 +248,258 @@ in(1, a) # => true # 用 length 获得数组长度 length(a) # => 8 -# Tuples 是 immutable 的 -tup = (1, 2, 3) # => (1,2,3) # an (Int64,Int64,Int64) tuple. +# 元组(Tuples)是不可变的 +tup = (1, 2, 3) # => (1,2,3) +typeof(tup) # => Tuple{Int64,Int64,Int64} tup[1] # => 1 -try: - tup[1] = 3 # => ERROR: no method setindex!((Int64,Int64,Int64),Int64,Int64) +try + tup[1] = 3 + # => ERROR: MethodError: no method matching + # setindex!(::Tuple{Int64,Int64,Int64}, ::Int64, ::Int64) catch e println(e) end -# 大多数组的函数同样支持 tuples +# 大多数组的函数同样支持元组 length(tup) # => 3 -tup[1:2] # => (1,2) -in(2, tup) # => true +tup[1:2] # => (1,2) +in(2, tup) # => true -# 可以将 tuples 元素分别赋给变量 -a, b, c = (1, 2, 3) # => (1,2,3) # a is now 1, b is now 2 and c is now 3 +# 可以将元组的元素解包赋给变量 +a, b, c = (1, 2, 3) # => (1,2,3) +a # => 1 +b # => 2 +c # => 3 # 不用括号也可以 -d, e, f = 4, 5, 6 # => (4,5,6) +d, e, f = 4, 5, 6 # => (4,5,6) +d # => 4 +e # => 5 +f # => 6 # 单元素 tuple 不等于其元素值 (1,) == 1 # => false -(1) == 1 # => true +(1) == 1 # => true # 交换值 -e, d = d, e # => (5,4) # d is now 5 and e is now 4 +e, d = d, e # => (5,4) +d # => 5 +e # => 4 -# 字典Dictionaries store mappings -empty_dict = Dict() # => Dict{Any,Any}() +# 字典用于储存映射(mappings)(键值对) +empty_dict = Dict() # => Dict{Any,Any} with 0 entries # 也可以用字面量创建字典 -filled_dict = ["one"=> 1, "two"=> 2, "three"=> 3] -# => Dict{ASCIIString,Int64} +filled_dict = Dict("one" => 1, "two" => 2, "three" => 3) +# => Dict{String,Int64} with 3 entries: +# => "two" => 2, "one" => 1, "three" => 3 # 用 [] 获得键值 filled_dict["one"] # => 1 # 获得所有键 keys(filled_dict) -# => KeyIterator{Dict{ASCIIString,Int64}}(["three"=>3,"one"=>1,"two"=>2]) +# => Base.KeySet for a Dict{String,Int64} with 3 entries. Keys: +# => "two", "one", "three" # 注意,键的顺序不是插入时的顺序 # 获得所有值 values(filled_dict) -# => ValueIterator{Dict{ASCIIString,Int64}}(["three"=>3,"one"=>1,"two"=>2]) +# => Base.ValueIterator for a Dict{String,Int64} with 3 entries. Values: +# => 2, 1, 3 # 注意,值的顺序也一样 # 用 in 检查键值是否已存在,用 haskey 检查键是否存在 -in(("one", 1), filled_dict) # => true -in(("two", 3), filled_dict) # => false -haskey(filled_dict, "one") # => true -haskey(filled_dict, 1) # => false +in(("one" => 1), filled_dict) # => true +in(("two" => 3), filled_dict) # => false +haskey(filled_dict, "one") # => true +haskey(filled_dict, 1) # => false # 获取不存在的键的值会抛出异常 try - filled_dict["four"] # => ERROR: key not found: four in getindex at dict.jl:489 + filled_dict["four"] # => ERROR: KeyError: key "four" not found catch e println(e) end # 使用 get 可以提供默认值来避免异常 # get(dictionary,key,default_value) -get(filled_dict,"one",4) # => 1 -get(filled_dict,"four",4) # => 4 +get(filled_dict, "one", 4) # => 1 +get(filled_dict, "four", 4) # => 4 -# 用 Sets 表示无序不可重复的值的集合 -empty_set = Set() # => Set{Any}() -# 初始化一个 Set 并定义其值 -filled_set = Set(1,2,2,3,4) # => Set{Int64}(1,2,3,4) +# Set 表示无序不可重复的值的集合 +empty_set = Set() # => Set(Any[]) +# 初始化一个带初值的 Set +filled_set = Set([1, 2, 2, 3, 4]) # => Set([4, 2, 3, 1]) -# 添加值 -push!(filled_set,5) # => Set{Int64}(5,4,2,3,1) +# 新增值 +push!(filled_set, 5) # => Set([4, 2, 3, 5, 1]) -# 检查是否存在某值 -in(2, filled_set) # => true -in(10, filled_set) # => false +# 检查 Set 中是否存在某值 +in(2, filled_set) # => true +in(10, filled_set) # => false # 交集,并集,差集 -other_set = Set(3, 4, 5, 6) # => Set{Int64}(6,4,5,3) -intersect(filled_set, other_set) # => Set{Int64}(3,4,5) -union(filled_set, other_set) # => Set{Int64}(1,2,3,4,5,6) -setdiff(Set(1,2,3,4),Set(2,3,5)) # => Set{Int64}(1,4) - +other_set = Set([3, 4, 5, 6]) # => Set([4, 3, 5, 6]) +intersect(filled_set, other_set) # => Set([4, 3, 5]) +union(filled_set, other_set) # => Set([4, 2, 3, 5, 6, 1]) +setdiff(Set([1,2,3,4]), Set([2,3,5])) # => Set([4, 1]) #################################################### -## 3. 控制流 +## 3. 控制语句 #################################################### # 声明一个变量 some_var = 5 -# 这是一个 if 语句,缩进不是必要的 +# 这是一个 if 语句块,其中的缩进不是必须的 if some_var > 10 println("some_var is totally bigger than 10.") -elseif some_var < 10 # elseif 是可选的. +elseif some_var < 10 # elseif 是可选的 println("some_var is smaller than 10.") -else # else 也是可选的. +else # else 也是可选的 println("some_var is indeed 10.") end -# => prints "some var is smaller than 10" +# => some_var is smaller than 10. # For 循环遍历 -# Iterable 类型包括 Range, Array, Set, Dict, 以及 String. -for animal=["dog", "cat", "mouse"] +# 可迭代的类型包括:Range, Array, Set, Dict 和 AbstractString +for animal = ["dog", "cat", "mouse"] println("$animal is a mammal") - # 可用 $ 将 variables 或 expression 转换为字符串into strings + # 你可以用 $ 将变量或表达式插入字符串中 end -# prints: -# dog is a mammal -# cat is a mammal -# mouse is a mammal +# => dog is a mammal +# => cat is a mammal +# => mouse is a mammal -# You can use 'in' instead of '='. +# 你也可以不用「=」而使用「in」 for animal in ["dog", "cat", "mouse"] println("$animal is a mammal") end -# prints: -# dog is a mammal -# cat is a mammal -# mouse is a mammal +# => dog is a mammal +# => cat is a mammal +# => mouse is a mammal -for a in ["dog"=>"mammal","cat"=>"mammal","mouse"=>"mammal"] - println("$(a[1]) is a $(a[2])") +for pair in Dict("dog" => "mammal", "cat" => "mammal", "mouse" => "mammal") + from, to = pair + println("$from is a $to") end -# prints: -# dog is a mammal -# cat is a mammal -# mouse is a mammal +# => mouse is a mammal +# => cat is a mammal +# => dog is a mammal +# 注意!这里的输出顺序和上面的不同 -for (k,v) in ["dog"=>"mammal","cat"=>"mammal","mouse"=>"mammal"] +for (k, v) in Dict("dog" => "mammal", "cat" => "mammal", "mouse" => "mammal") println("$k is a $v") end -# prints: -# dog is a mammal -# cat is a mammal -# mouse is a mammal +# => mouse is a mammal +# => cat is a mammal +# => dog is a mammal # While 循环 -x = 0 -while x < 4 - println(x) - x += 1 # x = x + 1 +let x = 0 + while x < 4 + println(x) + x += 1 # x = x + 1 的缩写 + end end -# prints: -# 0 -# 1 -# 2 -# 3 +# => 0 +# => 1 +# => 2 +# => 3 # 用 try/catch 处理异常 try - error("help") + error("help") catch e - println("caught it $e") + println("caught it $e") end # => caught it ErrorException("help") - #################################################### ## 4. 函数 #################################################### -# 用关键字 'function' 可创建一个新函数 -#function name(arglist) -# body... -#end +# 关键字 function 用于定义函数 +# function name(arglist) +# body... +# end function add(x, y) println("x is $x and y is $y") - # 最后一行语句的值为返回 + # 函数会返回最后一行的值 x + y end -add(5, 6) # => 在 "x is 5 and y is 6" 后会打印 11 +add(5, 6) +# => x is 5 and y is 6 +# => 11 + +# 更紧凑的定义函数 +f_add(x, y) = x + y # => f_add (generic function with 1 method) +f_add(3, 4) # => 7 + +# 函数可以将多个值作为元组返回 +fn(x, y) = x + y, x - y # => fn (generic function with 1 method) +fn(3, 4) # => (7, -1) # 还可以定义接收可变长参数的函数 function varargs(args...) return args - # 关键字 return 可在函数内部任何地方返回 + # 使用 return 可以在函数内的任何地方返回 end # => varargs (generic function with 1 method) varargs(1,2,3) # => (1,2,3) -# 省略号 ... 被称为 splat. +# 省略号「...」称为 splat # 刚刚用在了函数定义中 -# 还可以用在函数的调用 -# Array 或者 Tuple 的内容会变成参数列表 -Set([1,2,3]) # => Set{Array{Int64,1}}([1,2,3]) # 获得一个 Array 的 Set -Set([1,2,3]...) # => Set{Int64}(1,2,3) # 相当于 Set(1,2,3) +# 在调用函数时也可以使用它,此时它会把数组或元组解包为参数列表 +add([5,6]...) # 等价于 add(5,6) -x = (1,2,3) # => (1,2,3) -Set(x) # => Set{(Int64,Int64,Int64)}((1,2,3)) # 一个 Tuple 的 Set -Set(x...) # => Set{Int64}(2,3,1) +x = (5, 6) # => (5,6) +add(x...) # 等价于 add(5,6) - -# 可定义可选参数的函数 -function defaults(a,b,x=5,y=6) +# 可定义带可选参数的函数 +function defaults(a, b, x=5, y=6) return "$a $b and $x $y" end +# => defaults (generic function with 3 methods) -defaults('h','g') # => "h g and 5 6" -defaults('h','g','j') # => "h g and j 6" -defaults('h','g','j','k') # => "h g and j k" +defaults('h', 'g') # => "h g and 5 6" +defaults('h', 'g', 'j') # => "h g and j 6" +defaults('h', 'g', 'j', 'k') # => "h g and j k" try - defaults('h') # => ERROR: no method defaults(Char,) - defaults() # => ERROR: no methods defaults() + defaults('h') # => ERROR: MethodError: no method matching defaults(::Char) + defaults() # => ERROR: MethodError: no method matching defaults() catch e println(e) end -# 还可以定义键值对的参数 -function keyword_args(;k1=4,name2="hello") # note the ; - return ["k1"=>k1,"name2"=>name2] +# 还可以定义带关键字参数的函数 +function keyword_args(;k1=4, name2="hello") # 注意分号 ';' + return Dict("k1" => k1, "name2" => name2) end +# => keyword_args (generic function with 1 method) -keyword_args(name2="ness") # => ["name2"=>"ness","k1"=>4] -keyword_args(k1="mine") # => ["k1"=>"mine","name2"=>"hello"] -keyword_args() # => ["name2"=>"hello","k1"=>4] +keyword_args(name2="ness") # => ["name2"=>"ness", "k1"=>4] +keyword_args(k1="mine") # => ["name2"=>"hello", "k1"=>"mine"] +keyword_args() # => ["name2"=>"hello", "k1"=>4] -# 可以组合各种类型的参数在同一个函数的参数列表中 +# 可以在一个函数中组合各种类型的参数 function all_the_args(normal_arg, optional_positional_arg=2; keyword_arg="foo") println("normal arg: $normal_arg") println("optional arg: $optional_positional_arg") println("keyword arg: $keyword_arg") end +# => all_the_args (generic function with 2 methods) all_the_args(1, 3, keyword_arg=4) -# prints: -# normal arg: 1 -# optional arg: 3 -# keyword arg: 4 +# => normal arg: 1 +# => optional arg: 3 +# => keyword arg: 4 # Julia 有一等函数 function create_adder(x) @@ -443,14 +508,16 @@ function create_adder(x) end return adder end +# => create_adder (generic function with 1 method) # 这是用 "stabby lambda syntax" 创建的匿名函数 (x -> x > 2)(3) # => true -# 这个函数和上面的 create_adder 一模一样 +# 这个函数和上面的 create_adder 是等价的 function create_adder(x) y -> x + y end +# => create_adder (generic function with 1 method) # 你也可以给内部函数起个名字 function create_adder(x) @@ -459,18 +526,19 @@ function create_adder(x) end adder end +# => create_adder (generic function with 1 method) -add_10 = create_adder(10) -add_10(3) # => 13 - +add_10 = create_adder(10) # => (::getfield(Main, Symbol("#adder#11")){Int64}) + # (generic function with 1 method) +add_10(3) # => 13 # 内置的高阶函数有 -map(add_10, [1,2,3]) # => [11, 12, 13] -filter(x -> x > 5, [3, 4, 5, 6, 7]) # => [6, 7] +map(add_10, [1,2,3]) # => [11, 12, 13] +filter(x -> x > 5, [3, 4, 5, 6, 7]) # => [6, 7] -# 还可以使用 list comprehensions 替代 map -[add_10(i) for i=[1, 2, 3]] # => [11, 12, 13] -[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13] +# 还可以使用 list comprehensions 让 map 更美观 +[add_10(i) for i = [1, 2, 3]] # => [11, 12, 13] +[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13] #################################################### ## 5. 类型 @@ -482,248 +550,315 @@ filter(x -> x > 5, [3, 4, 5, 6, 7]) # => [6, 7] typeof(5) # => Int64 # 类型是一等值 -typeof(Int64) # => DataType -typeof(DataType) # => DataType +typeof(Int64) # => DataType +typeof(DataType) # => DataType # DataType 是代表类型的类型,也代表他自己的类型 -# 类型可用作文档化,优化,以及调度 -# 并不是静态检查类型 +# 类型可用于文档化代码、执行优化以及多重派分(dispatch) +# Julia 并不只是静态的检查类型 # 用户还可以自定义类型 -# 跟其他语言的 records 或 structs 一样 -# 用 `type` 关键字定义新的类型 +# 就跟其它语言的 record 或 struct 一样 +# 用 `struct` 关键字定义新的类型 -# type Name +# struct Name # field::OptionalType # ... # end -type Tiger - taillength::Float64 - coatcolor # 不附带类型标注的相当于 `::Any` +struct Tiger + taillength::Float64 + coatcolor # 不带类型标注相当于 `::Any` end -# 构造函数参数是类型的属性 -tigger = Tiger(3.5,"orange") # => Tiger(3.5,"orange") +# 默认构造函数的参数是类型的属性,按类型定义中的顺序排列 +tigger = Tiger(3.5, "orange") # => Tiger(3.5, "orange") # 用新类型作为构造函数还会创建一个类型 -sherekhan = typeof(tigger)(5.6,"fire") # => Tiger(5.6,"fire") +sherekhan = typeof(tigger)(5.6, "fire") # => Tiger(5.6, "fire") -# struct 类似的类型被称为具体类型 -# 他们可被实例化但不能有子类型 +# 类似 struct 的类型被称为具体类型 +# 它们可被实例化,但不能有子类型 # 另一种类型是抽象类型 -# abstract Name -abstract Cat # just a name and point in the type hierarchy +# 抽象类型名 +abstract type Cat end # 仅仅是指向类型结构层次的一个名称 -# 抽象类型不能被实例化,但是可以有子类型 +# 抽象类型不能被实例化,但可以有子类型 # 例如,Number 就是抽象类型 -subtypes(Number) # => 6-element Array{Any,1}: - # Complex{Float16} - # Complex{Float32} - # Complex{Float64} - # Complex{T<:Real} - # ImaginaryUnit - # Real -subtypes(Cat) # => 0-element Array{Any,1} - -# 所有的类型都有父类型; 可以用函数 `super` 得到父类型. +subtypes(Number) # => 2-element Array{Any,1}: + # => Complex + # => Real +subtypes(Cat) # => 0-element Array{Any,1} + +# AbstractString,类如其名,也是一个抽象类型 +subtypes(AbstractString) # => 4-element Array{Any,1}: + # => String + # => SubString + # => SubstitutionString + # => Test.GenericString + +# 所有的类型都有父类型。可以用函数 `supertype` 得到父类型 typeof(5) # => Int64 -super(Int64) # => Signed -super(Signed) # => Real -super(Real) # => Number -super(Number) # => Any -super(super(Signed)) # => Number -super(Any) # => Any -# 所有这些类型,除了 Int64, 都是抽象类型. - -# <: 是类型集成操作符 -type Lion <: Cat # Lion 是 Cat 的子类型 - mane_color - roar::String +supertype(Int64) # => Signed +supertype(Signed) # => Integer +supertype(Integer) # => Real +supertype(Real) # => Number +supertype(Number) # => Any +supertype(supertype(Signed)) # => Real +supertype(Any) # => Any +# 除了 Int64 外,其余的类型都是抽象类型 +typeof("fire") # => String +supertype(String) # => AbstractString +supertype(AbstractString) # => Any +supertype(SubString) # => AbstractString + +# <: 是子类型化操作符 +struct Lion <: Cat # Lion 是 Cat 的子类型 + mane_color + roar::AbstractString end # 可以继续为你的类型定义构造函数 -# 只需要定义一个同名的函数 -# 并调用已有的构造函数设置一个固定参数 -Lion(roar::String) = Lion("green",roar) -# 这是一个外部构造函数,因为他再类型定义之外 - -type Panther <: Cat # Panther 也是 Cat 的子类型 - eye_color - Panther() = new("green") - # Panthers 只有这个构造函数,没有默认构造函数 +# 只需要定义一个与类型同名的函数,并调用已有的构造函数得到正确的类型 +Lion(roar::AbstractString) = Lion("green", roar) # => Lion +# 这是一个外部构造函数,因为它在类型定义之外 + +struct Panther <: Cat # Panther 也是 Cat 的子类型 + eye_color + Panther() = new("green") + # Panthers 只有这个构造函数,没有默认构造函数 end -# 使用内置构造函数,如 Panther,可以让你控制 -# 如何构造类型的值 -# 应该尽可能使用外部构造函数而不是内部构造函数 +# 像 Panther 一样使用内置构造函数,让你可以控制如何构建类型的值 +# 应该尽量使用外部构造函数,而不是内部构造函数 #################################################### ## 6. 多分派 #################################################### -# 在Julia中, 所有的具名函数都是类属函数 -# 这意味着他们都是有很大小方法组成的 -# 每个 Lion 的构造函数都是类属函数 Lion 的方法 +# Julia 中所有的函数都是通用函数,或者叫做泛型函数(generic functions) +# 也就是说这些函数都是由许多小方法组合而成的 +# Lion 的每一种构造函数都是通用函数 Lion 的一个方法 # 我们来看一个非构造函数的例子 +# 首先,让我们定义一个函数 meow -# Lion, Panther, Tiger 的 meow 定义为 +# Lion, Panther, Tiger 的 meow 定义分别为 function meow(animal::Lion) - animal.roar # 使用点符号访问属性 + animal.roar # 使用点记号「.」访问属性 end +# => meow (generic function with 1 method) function meow(animal::Panther) - "grrr" + "grrr" end +# => meow (generic function with 2 methods) function meow(animal::Tiger) - "rawwwr" + "rawwwr" end +# => meow (generic function with 3 methods) # 试试 meow 函数 -meow(tigger) # => "rawwr" -meow(Lion("brown","ROAAR")) # => "ROAAR" +meow(tigger) # => "rawwwr" +meow(Lion("brown", "ROAAR")) # => "ROAAR" meow(Panther()) # => "grrr" -# 再看看层次结构 -issubtype(Tiger,Cat) # => false -issubtype(Lion,Cat) # => true -issubtype(Panther,Cat) # => true +# 回顾类型的层次结构 +Tiger <: Cat # => false +Lion <: Cat # => true +Panther <: Cat # => true -# 定义一个接收 Cats 的函数 +# 定义一个接收 Cat 类型的函数 function pet_cat(cat::Cat) - println("The cat says $(meow(cat))") + println("The cat says $(meow(cat))") end +# => pet_cat (generic function with 1 method) -pet_cat(Lion("42")) # => prints "The cat says 42" +pet_cat(Lion("42")) # => The cat says 42 try - pet_cat(tigger) # => ERROR: no method pet_cat(Tiger,) + pet_cat(tigger) # => ERROR: MethodError: no method matching pet_cat(::Tiger) catch e println(e) end # 在面向对象语言中,通常都是单分派 -# 这意味着分派方法是通过第一个参数的类型决定的 -# 在Julia中, 所有参数类型都会被考虑到 +# 这意味着使用的方法取决于第一个参数的类型 +# 而 Julia 中选择方法时会考虑到所有参数的类型 -# 让我们定义有多个参数的函数,好看看区别 -function fight(t::Tiger,c::Cat) - println("The $(t.coatcolor) tiger wins!") +# 让我们定义一个有更多参数的函数,这样我们就能看出区别 +function fight(t::Tiger, c::Cat) + println("The $(t.coatcolor) tiger wins!") end # => fight (generic function with 1 method) -fight(tigger,Panther()) # => prints The orange tiger wins! -fight(tigger,Lion("ROAR")) # => prints The orange tiger wins! +fight(tigger, Panther()) # => The orange tiger wins! +fight(tigger, Lion("ROAR")) # => fight(tigger, Lion("ROAR")) -# 让我们修改一下传入具体为 Lion 类型时的行为 -fight(t::Tiger,l::Lion) = println("The $(l.mane_color)-maned lion wins!") +# 让我们修改一下传入 Lion 类型时的行为 +fight(t::Tiger, l::Lion) = println("The $(l.mane_color)-maned lion wins!") # => fight (generic function with 2 methods) -fight(tigger,Panther()) # => prints The orange tiger wins! -fight(tigger,Lion("ROAR")) # => prints The green-maned lion wins! +fight(tigger, Panther()) # => The orange tiger wins! +fight(tigger, Lion("ROAR")) # => The green-maned lion wins! -# 把 Tiger 去掉 -fight(l::Lion,c::Cat) = println("The victorious cat says $(meow(c))") +# 我们不需要一只老虎参与战斗 +fight(l::Lion, c::Cat) = println("The victorious cat says $(meow(c))") # => fight (generic function with 3 methods) -fight(Lion("balooga!"),Panther()) # => prints The victorious cat says grrr +fight(Lion("balooga!"), Panther()) # => The victorious cat says grrr try - fight(Panther(),Lion("RAWR")) # => ERROR: no method fight(Panther,Lion) -catch + fight(Panther(), Lion("RAWR")) + # => ERROR: MethodError: no method matching fight(::Panther, ::Lion) + # => Closest candidates are: + # => fight(::Tiger, ::Lion) at ... + # => fight(::Tiger, ::Cat) at ... + # => fight(::Lion, ::Cat) at ... + # => ... +catch e + println(e) end -# 在试试让 Cat 在前面 -fight(c::Cat,l::Lion) = println("The cat beats the Lion") -# => Warning: New definition -# fight(Cat,Lion) at none:1 -# is ambiguous with -# fight(Lion,Cat) at none:2. -# Make sure -# fight(Lion,Lion) -# is defined first. -#fight (generic function with 4 methods) - -# 警告说明了无法判断使用哪个 fight 方法 -fight(Lion("RAR"),Lion("brown","rarrr")) # => prints The victorious cat says rarrr -# 结果在老版本 Julia 中可能会不一样 - -fight(l::Lion,l2::Lion) = println("The lions come to a tie") -fight(Lion("RAR"),Lion("brown","rarrr")) # => prints The lions come to a tie - - -# Under the hood -# 你还可以看看 llvm 以及生成的汇编代码 - -square_area(l) = l * l # square_area (generic function with 1 method) - -square_area(5) #25 - -# 给 square_area 一个整形时发生什么 -code_native(square_area, (Int32,)) - # .section __TEXT,__text,regular,pure_instructions - # Filename: none - # Source line: 1 # Prologue - # push RBP - # mov RBP, RSP - # Source line: 1 - # movsxd RAX, EDI # Fetch l from memory? - # imul RAX, RAX # Square l and store the result in RAX - # pop RBP # Restore old base pointer - # ret # Result will still be in RAX - -code_native(square_area, (Float32,)) - # .section __TEXT,__text,regular,pure_instructions - # Filename: none - # Source line: 1 - # push RBP - # mov RBP, RSP - # Source line: 1 - # vmulss XMM0, XMM0, XMM0 # Scalar single precision multiply (AVX) - # pop RBP - # ret - -code_native(square_area, (Float64,)) - # .section __TEXT,__text,regular,pure_instructions - # Filename: none - # Source line: 1 - # push RBP - # mov RBP, RSP - # Source line: 1 - # vmulsd XMM0, XMM0, XMM0 # Scalar double precision multiply (AVX) - # pop RBP - # ret - # -# 注意 只要参数中又浮点类型,Julia 就使用浮点指令 +# 试试把 Cat 放在前面 +fight(c::Cat, l::Lion) = println("The cat beats the Lion") +# => fight (generic function with 4 methods) + +# 由于无法判断该使用哪个 fight 方法,而产生了错误 +try + fight(Lion("RAR"), Lion("brown", "rarrr")) + # => ERROR: MethodError: fight(::Lion, ::Lion) is ambiguous. Candidates: + # => fight(c::Cat, l::Lion) in Main at ... + # => fight(l::Lion, c::Cat) in Main at ... + # => Possible fix, define + # => fight(::Lion, ::Lion) + # => ... +catch e + println(e) +end +# 在不同版本的 Julia 中错误信息可能有所不同 + +fight(l::Lion, l2::Lion) = println("The lions come to a tie") +# => fight (generic function with 5 methods) +fight(Lion("RAR"), Lion("brown", "rarrr")) # => The lions come to a tie + + +# 深入编译器之后 +# 你还可以看看 llvm 以及它生成的汇编代码 + +square_area(l) = l * l # => square_area (generic function with 1 method) +square_area(5) # => 25 + +# 当我们喂给 square_area 一个整数时会发生什么? +code_native(square_area, (Int32,), syntax = :intel) + # .text + # ; Function square_area { + # ; Location: REPL[116]:1 # 函数序言 (Prologue) + # push rbp + # mov rbp, rsp + # ; Function *; { + # ; Location: int.jl:54 + # imul ecx, ecx # 求 l 的平方,并把结果放在 ECX 中 + # ;} + # mov eax, ecx + # pop rbp # 还原旧的基址指针(base pointer) + # ret # 返回值放在 EAX 中 + # nop dword ptr [rax + rax] + # ;} +# 使用 syntax 参数指定输出语法。默认为 AT&T 格式,这里指定为 Intel 格式 + +code_native(square_area, (Float32,), syntax = :intel) + # .text + # ; Function square_area { + # ; Location: REPL[116]:1 + # push rbp + # mov rbp, rsp + # ; Function *; { + # ; Location: float.jl:398 + # vmulss xmm0, xmm0, xmm0 # 标量双精度乘法 (AVX) + # ;} + # pop rbp + # ret + # nop word ptr [rax + rax] + # ;} + +code_native(square_area, (Float64,), syntax = :intel) + # .text + # ; Function square_area { + # ; Location: REPL[116]:1 + # push rbp + # mov rbp, rsp + # ; Function *; { + # ; Location: float.jl:399 + # vmulsd xmm0, xmm0, xmm0 # 标量双精度乘法 (AVX) + # ;} + # pop rbp + # ret + # nop word ptr [rax + rax] + # ;} + +# 注意!只要参数中有浮点数,Julia 就会使用浮点指令 # 让我们计算一下圆的面积 -circle_area(r) = pi * r * r # circle_area (generic function with 1 method) -circle_area(5) # 78.53981633974483 - -code_native(circle_area, (Int32,)) - # .section __TEXT,__text,regular,pure_instructions - # Filename: none - # Source line: 1 - # push RBP - # mov RBP, RSP - # Source line: 1 - # vcvtsi2sd XMM0, XMM0, EDI # Load integer (r) from memory - # movabs RAX, 4593140240 # Load pi - # vmulsd XMM1, XMM0, QWORD PTR [RAX] # pi * r - # vmulsd XMM0, XMM0, XMM1 # (pi * r) * r - # pop RBP - # ret - # - -code_native(circle_area, (Float64,)) - # .section __TEXT,__text,regular,pure_instructions - # Filename: none - # Source line: 1 - # push RBP - # mov RBP, RSP - # movabs RAX, 4593140496 - # Source line: 1 - # vmulsd XMM1, XMM0, QWORD PTR [RAX] - # vmulsd XMM0, XMM1, XMM0 - # pop RBP - # ret - # +circle_area(r) = pi * r * r # => circle_area (generic function with 1 method) +circle_area(5) # => 78.53981633974483 + +code_native(circle_area, (Int32,), syntax = :intel) + # .text + # ; Function circle_area { + # ; Location: REPL[121]:1 + # push rbp + # mov rbp, rsp + # ; Function *; { + # ; Location: operators.jl:502 + # ; Function *; { + # ; Location: promotion.jl:314 + # ; Function promote; { + # ; Location: promotion.jl:284 + # ; Function _promote; { + # ; Location: promotion.jl:261 + # ; Function convert; { + # ; Location: number.jl:7 + # ; Function Type; { + # ; Location: float.jl:60 + # vcvtsi2sd xmm0, xmm0, ecx # 从内存中读取整数 r + # movabs rax, 497710928 # 读取 pi + # ;}}}}} + # ; Function *; { + # ; Location: float.jl:399 + # vmulsd xmm1, xmm0, qword ptr [rax] # pi * r + # vmulsd xmm0, xmm1, xmm0 # (pi * r) * r + # ;}} + # pop rbp + # ret + # nop dword ptr [rax] + # ;} + +code_native(circle_area, (Float64,), syntax = :intel) + # .text + # ; Function circle_area { + # ; Location: REPL[121]:1 + # push rbp + # mov rbp, rsp + # movabs rax, 497711048 + # ; Function *; { + # ; Location: operators.jl:502 + # ; Function *; { + # ; Location: promotion.jl:314 + # ; Function *; { + # ; Location: float.jl:399 + # vmulsd xmm1, xmm0, qword ptr [rax] + # ;}}} + # ; Function *; { + # ; Location: float.jl:399 + # vmulsd xmm0, xmm1, xmm0 + # ;} + # pop rbp + # ret + # nop dword ptr [rax + rax] + # ;} ``` + +## 拓展阅读材料 + +你可以在 [Julia 中文文档](http://docs.juliacn.com/latest/) / [Julia 文档(en)](https://docs.julialang.org/) +中获得关于 Julia 的更多细节。 + +如果有任何问题可以去 [Julia 中文社区](http://discourse.juliacn.com/) / [官方社区(en)](https://discourse.julialang.org/) 提问,大家对待新手都非常的友好。 diff --git a/zh-cn/markdown-cn.html.markdown b/zh-cn/markdown-cn.html.markdown index e9a8aeb2..2bd8d11a 100644 --- a/zh-cn/markdown-cn.html.markdown +++ b/zh-cn/markdown-cn.html.markdown @@ -4,45 +4,63 @@ contributors: - ["Dan Turkel", "http://danturkel.com/"] translators: - ["Fangzhou Chen","https://github.com/FZSS"] + - ["Luffy Zhong", "https://github.com/mengzhongshi"] filename: learnmarkdown-cn.md lang: zh-cn --- Markdown 由 John Gruber 于 2004年创立. 它旨在成为一门容易读写的语法结构,并可以便利地转换成 HTML(以及其他很多)格式。 -欢迎您多多反馈以及分支和请求合并。 +在不同的解析器中,Markdown 的实现方法有所不同。 +此教程会指出哪些特征是通用,哪一些只对某一解析器有效。 +- [HTML标签](#HTML标签) +- [标题](#标题) +- [文本样式](#文本样式) +- [段落](#段落) +- [列表](#列表) +- [代码块](#代码块) +- [水平线分隔](#水平线分隔) +- [链接](#链接) +- [图片](#图片) +- [杂项](#杂项) + +## HTML标签 +Markdown 是 HTML 的父集,所以任何 HTML 文件都是有效的 Markdown。 ```md -<!-- Markdown 是 HTML 的父集,所以任何 HTML 文件都是有效的 Markdown。 -这意味着我们可以在 Markdown 里使用任何 HTML 元素,比如注释元素, +<!--这意味着我们可以在 Markdown 里使用任何 HTML 元素,比如注释元素, 且不会被 Markdown 解析器所影响。不过如果你在 Markdown 文件内创建了 HTML 元素, 你将无法在 HTML 元素的内容中使用 Markdown 语法。--> +``` -<!-- 在不同的解析器中,Markdown 的实现方法有所不同。 -此教程会指出当某功能是否通用及是否只对某一解析器有效。 --> +## 标题 -<!-- 标头 --> -<!-- 通过在文本前加上不同数量的hash(#), 你可以创建相对应的 <h1> -到 <h6> HTML元素。--> +通过在文本前加上不同数量的hash(#), 你可以创建相对应的 `<h1>` 到 `<h6>` HTML元素。 +```md # 这是一个 <h1> ## 这是一个 <h2> ### 这是一个 <h3> #### 这是一个 <h4> ##### 这是一个 <h5> ###### 这是一个 <h6> +``` +对于 `<h1>` 和 `<h2>` 元素,Markdown 额外提供了两种添加方式。 -<!-- 对于 <h1> 和 <h2> 元素,Markdown 额外提供了两种添加方式。 --> +```md 这是一个 h1 ============= 这是一个 h2 ------------- +``` + +## 文本样式 -<!-- 简易文本样式 --> -<!-- 文本的斜体,粗体,和删除线在 Markdown 中可以轻易地被实现。--> +文本的斜体,粗体在 Markdown 中可以轻易实现。 +```md *此文本为斜体。* _此文本也是。_ @@ -52,40 +70,52 @@ __此文本也是__ ***此文本是斜体加粗体。*** **_或者这样。_** *__这个也是!__* +``` -<!-- 在 GitHub 采用的 Markdown 中 --> +GitHub 也支持 Markdown,在 GitHub 的 Markdown 解析器中,我们可以使用删除线: +```md ~~此文本为删除线效果。~~ +``` +## 段落 -<!-- 单个段落由一句或多句邻近的句子组成,这些句子由一个或多个空格分隔。--> +段落由一个句子或是多个中间没有空行的句子组成,每个段落由一个或是多个空行分隔开来。 +```md 这是第一段落. 这句话在同一个段落里,好玩么? 现在我是第二段落。 这句话也在第二段落! + 这句话在第三段落! +``` -<!-- 如果你插入一个 HTML中的<br />标签,你可以在段末加入两个以上的空格, -然后另起一段。--> +如果你想插入一个 `<br />` 标签,你可以在段末加入两个以上的空格,然后另起一 +段。(译者注:试了一下,很多解析器,并不需要空两个空格,直接换行就会添加一个`<br />`) +```md 此段落结尾有两个空格(选中以显示)。 上文有一个 <br /> ! +``` -<!-- 段落引用可由 > 字符轻松实现。--> +段落引用可由 `>` 字符轻松实现。 -> 这是一个段落引用. 你可以 -> 手动断开你的句子,然后在每句句子前面添加 “>” 字符。或者让你的句子变得很长,以至于他们自动得断开。 -> 只要你的文字以“>” 字符开头,两种方式无异。 +```md +> 这是一个段落引用。 你可以 +> 手动断开你的句子,然后在每句句子前面添加 `>` 字符。或者让你的句子变得很长,以至于他们自动得换行。 +> 只要你的文字以 `>` 字符开头,两种方式无异。 -> 你也对文本进行 +> 你也可以对文本进行 >> 多层引用 > 这多机智啊! +``` -<!-- 序列 --> -<!-- 无序序列可由星号,加号或者减号来建立 --> +## 列表 +无序列表可由星号,加号或者减号来创建 +```md * 项目 * 项目 * 另一个项目 @@ -102,139 +132,195 @@ __此文本也是__ - 项目 - 最后一个项目 -<!-- 有序序列可由数字加点来实现 --> +``` +有序序列可由数字加上点 `.` 来实现 + +```md 1. 项目一 2. 项目二 3. 项目三 +``` -<!-- 即使你的标签数字有误,Markdown 依旧会呈现出正确的序号, -不过这并不是一个好主意--> +即使你的数字标签有误,Markdown 依旧会呈现出正确的序号, +不过这并不是一个好主意 +```md 1. 项目一 1. 项目二 1. 项目三 -<!-- (此段与前例一模一样) --> +``` +(此段与上面效果一模一样) -<!-- 你也可以使用子序列 --> +你也可以使用子列表 +```md 1. 项目一 2. 项目二 3. 项目三 * 子项目 * 子项目 4. 项目四 +``` + +你甚至可以使用任务列表,它将会生成 HTML 的选择框(checkboxes)标签。 -<!-- 代码段落 --> -<!-- 代码段落(HTML中 <code>标签)可以由缩进四格(spaces) -或者一个制表符(tab)实现--> +```md +下面方框里包含 'x' 的列表,将会生成选中效果的选择框。 +- [ ] 任务一需要完成 +- [ ] 任务二需要完成 +下面这个选择框将会是选中状态 +- [x] 这个任务已经完成 +``` +## 代码块 + +代码块(HTML中 `<code>` 标签)可以由缩进四格(spaces) +或者一个制表符(tab)实现 + +```md This is code - So is this + So is this +``` -<!-- 在你的代码中,你仍然使用tab可以进行缩进操作 --> +在你的代码中,你仍然使用tab(或者四个空格)可以进行缩进操作 +```md my_array.each do |item| puts item end +``` -<!-- 内联代码可由反引号 ` 实现 --> +内联代码可由反引号 ` 实现 +```md John 甚至不知道 `go_to()` 方程是干嘛的! +``` -<!-- 在GitHub的 Markdown中,对于代码你可以使用特殊的语法 --> +在GitHub的 Markdown(GitHub Flavored Markdown)解析器中,你可以使用特殊的语法表示代码块 -\`\`\`ruby <!-- 插入时记得移除反斜线, 仅留```ruby ! --> +<pre> +<code class="highlight">```ruby def foobar puts "Hello world!" end -\`\`\` <!-- 这里也是,移除反斜线,仅留 ``` --> +```</code></pre> + +以上代码不需要缩进,而且 GitHub 会根据\`\`\`后指定的语言来进行语法高亮显示 -<!-- 以上代码不需要缩进,而且 GitHub 会根据```后表明的语言来进行语法高亮 --> +## 水平线分隔 -<!-- 水平线 (<hr />) --> -<!-- 水平线可由三个或以上的星号或者减号创建,可带可不带空格。 --> +水平线(`<hr/>`)可由三个或以上的星号或是减号创建,它们之间可以带或不带空格 +```md *** --- - - - **************** +``` + +## 链接 -<!-- 链接 --> -<!-- Markdown 最棒的地方就是简易的链接制作。链接文字放在中括号[]内, -在随后的括弧()内加入url。--> +Markdown 最棒的地方就是便捷的书写链接。把链接文字放在中括号[]内, +在随后的括弧()内加入url就可以了。 +```md [点我点我!](http://test.com/) -<!-- 你也可以为链接加入一个标题:在括弧内使用引号 --> +``` + +你也可以在小括号内使用引号,为链接加上一个标题(title) +```md [点我点我!](http://test.com/ "连接到Test.com") +``` +相对路径也可以有 -<!-- 相对路径也可以有 --> - +```md [去 music](/music/). +``` -<!-- Markdown同样支持引用样式的链接 --> - -[点此链接][link1]以获取更多信息! -[看一看这个链接][foobar] 如果你愿意的话. +Markdown同样支持引用形式的链接 -[link1]: http://test.com/ "Cool!" -[foobar]: http://foobar.biz/ "Alright!" +```md +[点此链接][link1] 以获取更多信息! +[看一看这个链接][foobar] 如果你愿意的话。 +[link1]: http://test.com/ +[foobar]: http://foobar.biz/ +``` -<!-- 链接的标题可以处于单引号中,括弧中或是被忽略。引用名可以在文档的任意何处, -并且可以随意命名,只要名称不重复。--> +对于引用形式,链接的标题可以处于单引号中,括弧中或是忽略。引用名可以在文档的任何地方,并且可以随意命名,只要名称不重复。 -<!-- “隐含式命名” 的功能可以让链接文字作为引用名 --> +“隐含式命名” 的功能可以让链接文字作为引用名 +```md [This][] is a link. +[This]: http://thisisalink.com/ +``` -[this]: http://thisisalink.com/ - -<!-- 但这并不常用 --> - -<!-- 图像 --> -<!-- 图像与链接相似,只需在前添加一个感叹号 --> +但这并不常用 -![这是我图像的悬停文本(alt text)](http://imgur.com/myimage.jpg "可选命名") +## 图片 +图片与链接相似,只需在前添加一个感叹号 -<!-- 引用样式也同样起作用 --> +```md +![这是alt,请把鼠标放在图片上](http://imgur.com/myimage.jpg "这是title") +``` -![这是我的悬停文本.][myimage] +引用形式也同样起作用 -[myimage]: relative/urls/cool/image.jpg "在此输入标题" +```md +![这是alt][myimage] +[myimage]: relative/urls/cool/image.jpg +``` -<!-- 杂项 --> -<!-- 自动链接 --> +## 杂项 +### 自动链接 +```md <http://testwebsite.com/> 与 [http://testwebsite.com/](http://testwebsite.com/) 等同 +``` -<!-- 电子邮件的自动链接 --> +### 电子邮件的自动链接 +```md <foo@bar.com> +``` -<!-- 转义字符 --> +### 转义字符 +```md 我希望 *将这段文字置于星号之间* 但是我不希望它被 -斜体化, 所以我就: \*这段置文字于星号之间\*。 +斜体化, 这么做: \*这段置文字于星号之间\*。 +``` + +### 键盘上的功能键 -<!-- 表格 --> -<!-- 表格只被 GitHub 的 Markdown 支持,并且有一点笨重,但如果你真的要用的话: --> +在 GitHub 的 Markdown中,你可以使用 `<kbd>` 标签来表示功能键。 +```md +你的电脑死机了?试试 +<kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>Del</kbd> +``` +<kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>Del</kbd> +### 表格 + +表格只被 GitHub 的 Markdown 支持,并且有一点笨重,但如果你真的要用的话: (译者注:其实现在大部分markdown都已经支持) + +```md | 第一列 | 第二列 | 第三列 | -| :---------- | :------: | ----------: | +| :--------- | :------: | ----------: | | 左对齐 | 居个中 | 右对齐 | | 某某某 | 某某某 | 某某某 | +``` -<!-- 或者, 同样的 --> +或者, 同样的 +```md 第一列 | 第二列 | 第三列 :-- | :-: | --: 这太丑了 | 药不能 | 停 - -<!-- 结束! --> - ``` 更多信息, 请于[此处](http://daringfireball.net/projects/Markdown/syntax)参见 John Gruber 关于语法的官方帖子,及于[此处](https://github.com/adam-p/Markdown-here/wiki/Markdown-Cheatsheet) 参见 Adam Pritchard 的摘要笔记。 diff --git a/zh-cn/matlab-cn.html.markdown b/zh-cn/matlab-cn.html.markdown index 2fbccfc4..d215755c 100644 --- a/zh-cn/matlab-cn.html.markdown +++ b/zh-cn/matlab-cn.html.markdown @@ -10,9 +10,12 @@ lang: zh-cn ---
-MATLAB 是 MATrix LABoratory (矩阵实验室)的缩写,它是一种功能强大的数值计算语言,在工程和数学领域中应用广泛。
+MATLAB 是 MATrix LABoratory(矩阵实验室)的缩写。
+它是一种功能强大的数值计算语言,在工程和数学领域中应用广泛。
-如果您有任何需要反馈或交流的内容,请联系本教程作者[@the_ozzinator](https://twitter.com/the_ozzinator)、[osvaldo.t.mendoza@gmail.com](mailto:osvaldo.t.mendoza@gmail.com)。
+如果您有任何需要反馈或交流的内容,请联系本教程作者:
+[@the_ozzinator](https://twitter.com/the_ozzinator)
+或 [osvaldo.t.mendoza@gmail.com](mailto:osvaldo.t.mendoza@gmail.com)。
```matlab
% 以百分号作为注释符
@@ -45,7 +48,7 @@ edit('myfunction.m') % 在编辑器中打开指定函数或脚本 type('myfunction.m') % 在命令窗口中打印指定函数或脚本的源码
profile on % 打开 profile 代码分析工具
-profile of % 关闭 profile 代码分析工具
+profile off % 关闭 profile 代码分析工具
profile viewer % 查看 profile 代码分析工具的分析结果
help command % 在命令窗口中显示指定命令的帮助文档
@@ -113,7 +116,7 @@ b(2) % ans = 符 % 元组(cell 数组)
a = {'one', 'two', 'three'}
a(1) % ans = 'one' - 返回一个元组
-char(a(1)) % ans = one - 返回一个字符串
+a{1} % ans = one - 返回一个字符串
% 结构体
@@ -210,8 +213,8 @@ size(A) % 返回矩阵的行数和列数,ans = 3 3 A(1, :) =[] % 删除矩阵的第 1 行
A(:, 1) =[] % 删除矩阵的第 1 列
-transpose(A) % 矩阵转置,等价于 A'
-ctranspose(A) % 矩阵的共轭转置(对矩阵中的每个元素取共轭复数)
+transpose(A) % 矩阵(非共轭)转置,等价于 A.' (注意!有个点)
+ctranspose(A) % 矩阵的共轭转置(对矩阵中的每个元素取共轭复数),等价于 A'
% 元素运算 vs. 矩阵运算
@@ -219,18 +222,20 @@ ctranspose(A) % 矩阵的共轭转置(对矩阵中的每个元素取共轭复 % 在运算符加上英文句点就是对矩阵中的元素进行元素计算
% 示例如下:
A * B % 矩阵乘法,要求 A 的列数等于 B 的行数
-A .* B % 元素乘法,要求 A 和 B 形状一致(A 的行数等于 B 的行数, A 的列数等于 B 的列数)
-% 元素乘法的结果是与 A 和 B 形状一致的矩阵,其每个元素等于 A 对应位置的元素乘 B 对应位置的元素
+A .* B % 元素乘法,要求 A 和 B 形状一致,即两矩阵行列数完全一致
+ % 元素乘法的结果是与 A 和 B 形状一致的矩阵
+ % 其每个元素等于 A 对应位置的元素乘 B 对应位置的元素
% 以下函数中,函数名以 m 结尾的执行矩阵运算,其余执行元素运算:
exp(A) % 对矩阵中每个元素做指数运算
expm(A) % 对矩阵整体做指数运算
sqrt(A) % 对矩阵中每个元素做开方运算
-sqrtm(A) % 对矩阵整体做开放运算(即试图求出一个矩阵,该矩阵与自身的乘积等于 A 矩阵)
+sqrtm(A) % 对矩阵整体做开方运算(即试图求出一个矩阵,该矩阵与自身的乘积等于 A 矩阵)
% 绘图
-x = 0:.10:2*pi; % 生成一向量,其元素从 0 开始,以 0.1 的间隔一直递增到 2*pi(pi 就是圆周率)
+x = 0:0.1:2*pi; % 生成一向量,其元素从 0 开始,以 0.1 的间隔一直递增到 2*pi
+ % 其中 pi 为圆周率
y = sin(x);
plot(x,y)
xlabel('x axis')
@@ -288,7 +293,10 @@ clf clear % 清除图形窗口中的图像,并重置图像属性 % 也可以用 gcf 函数返回当前图像的句柄
h = plot(x, y); % 在创建图像时显式地保存图像句柄
set(h, 'Color', 'r')
-% 颜色代码:'y' 黄色,'m' 洋红色,'c' 青色,'r' 红色,'g' 绿色,'b' 蓝色,'w' 白色,'k' 黑色
+% 颜色代码:
+% 'y' 黄色,'m' 洋红,'c' 青色
+% 'r' 红色,'g' 绿色,'b' 蓝色
+% 'w' 白色,'k' 黑色
set(h, 'Color', [0.5, 0.5, 0.4])
% 也可以使用 RGB 值指定颜色
set(h, 'LineStyle', '--')
@@ -328,7 +336,8 @@ load('myFileName.mat') % 将指定文件中的变量载入到当前工作空间 % 与脚本文件类似,同样以 .m 作为后缀名
% 但函数文件可以接受用户输入的参数并返回运算结果
% 并且函数拥有自己的工作空间(变量域),不必担心变量名称冲突
-% 函数文件的名称应当与其所定义的函数的名称一致(比如下面例子中函数文件就应命名为 double_input.m)
+% 函数文件的名称应当与其所定义的函数的名称一致
+% 比如下面例子中函数文件就应命名为 double_input.m
% 使用 'help double_input.m' 可返回函数定义中第一行注释信息
function output = double_input(x)
% double_input(x) 返回 x 的 2 倍
@@ -463,14 +472,16 @@ triu(x) % 返回 x 的上三角这部分 tril(x) % 返回 x 的下三角这部分
cross(A, B) % 返回 A 和 B 的叉积(矢量积、外积)
dot(A, B) % 返回 A 和 B 的点积(数量积、内积),要求 A 和 B 必须等长
-transpose(A) % A 的转置,等价于 A'
+transpose(A) % 矩阵(非共轭)转置,等价于 A.' (注意!有个点)
fliplr(A) % 将一个矩阵左右翻转
flipud(A) % 将一个矩阵上下翻转
% 矩阵分解
-[L, U, P] = lu(A) % LU 分解:PA = LU,L 是下三角阵,U 是上三角阵,P 是置换阵
-[P, D] = eig(A) % 特征值分解:AP = PD,D 是由特征值构成的对角阵,P 的各列就是对应的特征向量
-[U, S, V] = svd(X) % 奇异值分解:XV = US,U 和 V 是酉矩阵,S 是由奇异值构成的半正定实数对角阵
+[L, U, P] = lu(A) % LU 分解:PA = LU,L 是下三角阵,U 是上三角阵,P 是置换阵
+[P, D] = eig(A) % 特征值分解:AP = PD
+ % D 是由特征值构成的对角阵,P 的各列就是对应的特征向量
+[U, S, V] = svd(X) % 奇异值分解:XV = US
+ % U 和 V 是酉矩阵,S 是由奇异值构成的半正定实数对角阵
% 常用向量函数
max % 最大值
@@ -489,5 +500,5 @@ perms(x) % x 元素的全排列 ## 相关资料
-* 官方网页:[http://http://www.mathworks.com/products/matlab/](http://www.mathworks.com/products/matlab/)
-* 官方论坛:[http://www.mathworks.com/matlabcentral/answers/](http://www.mathworks.com/matlabcentral/answers/)
+* 官方网页:[MATLAB - 技术计算语言 - MATLAB & Simulink](https://ww2.mathworks.cn/products/matlab.html)
+* 官方论坛:[MATLAB Answers - MATLAB Central](https://ww2.mathworks.cn/matlabcentral/answers/)
diff --git a/zh-cn/python3-cn.html.markdown b/zh-cn/python3-cn.html.markdown index 211ce0c5..fd962305 100644 --- a/zh-cn/python3-cn.html.markdown +++ b/zh-cn/python3-cn.html.markdown @@ -10,13 +10,13 @@ filename: learnpython3-cn.py lang: zh-cn --- -Python是由吉多·范罗苏姆(Guido Van Rossum)在90年代早期设计。它是如今最常用的编程 -语言之一。它的语法简洁且优美,几乎就是可执行的伪代码。 +Python 是由吉多·范罗苏姆(Guido Van Rossum)在 90 年代早期设计。 +它是如今最常用的编程语言之一。它的语法简洁且优美,几乎就是可执行的伪代码。 -欢迎大家斧正。英文版原作Louie Dinh [@louiedinh](http://twitter.com/louiedinh) -或着Email louiedinh [at] [谷歌的信箱服务]。中文翻译Geoff Liu。 +欢迎大家斧正。英文版原作 Louie Dinh [@louiedinh](http://twitter.com/louiedinh) +邮箱 louiedinh [at] [谷歌的信箱服务]。中文翻译 Geoff Liu。 -注意:这篇教程是特别为Python3写的。如果你想学旧版Python2,我们特别有另一篇教程。 +注意:这篇教程是基于 Python 3 写的。如果你想学旧版 Python 2,我们特别有[另一篇教程](http://learnxinyminutes.com/docs/python/)。 ```python @@ -70,15 +70,15 @@ not True # => False not False # => True # 逻辑运算符,注意and和or都是小写 -True and False #=> False -False or True #=> True +True and False # => False +False or True # => True # 整数也可以当作布尔值 -0 and 2 #=> 0 --5 or 0 #=> -5 -0 == False #=> True -2 == True #=> False -1 == True #=> True +0 and 2 # => 0 +-5 or 0 # => -5 +0 == False # => True +2 == True # => False +1 == True # => True # 用==判断相等 1 == 1 # => True @@ -113,10 +113,11 @@ False or True #=> True # 可以重复参数以节省时间 "{0} be nimble, {0} be quick, {0} jump over the {1}".format("Jack", "candle stick") -#=> "Jack be nimble, Jack be quick, Jack jump over the candle stick" +# => "Jack be nimble, Jack be quick, Jack jump over the candle stick" # 如果不想数参数,可以用关键字 -"{name} wants to eat {food}".format(name="Bob", food="lasagna") #=> "Bob wants to eat lasagna" +"{name} wants to eat {food}".format(name="Bob", food="lasagna") +# => "Bob wants to eat lasagna" # 如果你的Python3程序也要在Python2.5以下环境运行,也可以用老式的格式化语法 "%s can be %s the %s way" % ("strings", "interpolated", "old") @@ -132,8 +133,8 @@ None is None # => True # 所有其他值都是True bool(0) # => False bool("") # => False -bool([]) #=> False -bool({}) #=> False +bool([]) # => False +bool({}) # => False #################################################### @@ -233,7 +234,8 @@ filled_dict = {"one": 1, "two": 2, "three": 3} filled_dict["one"] # => 1 -# 用keys获得所有的键。因为keys返回一个可迭代对象,所以在这里把结果包在list里。我们下面会详细介绍可迭代。 +# 用 keys 获得所有的键。 +# 因为 keys 返回一个可迭代对象,所以在这里把结果包在 list 里。我们下面会详细介绍可迭代。 # 注意:字典键的顺序是不定的,你得到的结果可能和以下不同。 list(filled_dict.keys()) # => ["three", "two", "one"] @@ -261,7 +263,7 @@ filled_dict.setdefault("five", 5) # filled_dict["five"]设为5 filled_dict.setdefault("five", 6) # filled_dict["five"]还是5 # 字典赋值 -filled_dict.update({"four":4}) #=> {"one": 1, "two": 2, "three": 3, "four": 4} +filled_dict.update({"four":4}) # => {"one": 1, "two": 2, "three": 3, "four": 4} filled_dict["four"] = 4 # 另一种赋值方法 # 用del删除 @@ -362,7 +364,7 @@ else: # else语句是可选的,必须在所有的except之后 filled_dict = {"one": 1, "two": 2, "three": 3} our_iterable = filled_dict.keys() -print(our_iterable) # => range(1,10) 是一个实现可迭代接口的对象 +print(our_iterable) # => dict_keys(['one', 'two', 'three']),是一个实现可迭代接口的对象 # 可迭代对象可以遍历 for i in our_iterable: @@ -376,17 +378,17 @@ our_iterator = iter(our_iterable) # 迭代器是一个可以记住遍历的位置的对象 # 用__next__可以取得下一个元素 -our_iterator.__next__() #=> "one" +our_iterator.__next__() # => "one" # 再一次调取__next__时会记得位置 -our_iterator.__next__() #=> "two" -our_iterator.__next__() #=> "three" +our_iterator.__next__() # => "two" +our_iterator.__next__() # => "three" # 当迭代器所有元素都取出后,会抛出StopIteration our_iterator.__next__() # 抛出StopIteration # 可以用list一次取出迭代器所有的元素 -list(filled_dict.keys()) #=> Returns ["one", "two", "three"] +list(filled_dict.keys()) # => Returns ["one", "two", "three"] diff --git a/zh-cn/swift-cn.html.markdown b/zh-cn/swift-cn.html.markdown index c25b2918..18bc52ed 100644 --- a/zh-cn/swift-cn.html.markdown +++ b/zh-cn/swift-cn.html.markdown @@ -110,7 +110,7 @@ anyObjectVar = "Changed value to a string, not good practice, but possible." // -// Mark: 数组与字典(关联数组) +// MARK: 数组与字典(关联数组) // /* @@ -214,9 +214,9 @@ func greet(name: String, day: String) -> String { } greet("Bob", day: "Tuesday") -// 第一个参数表示外部参数名和内部参数名使用同一个名称。 +// 第一个参数`_`表示不使用外部参数名,忽略`_`表示外部参数名和内部参数名使用同一个名称。 // 第二个参数表示外部参数名使用 `externalParamName` ,内部参数名使用 `localParamName` -func greet2(requiredName requiredName: String, externalParamName localParamName: String) -> String { +func greet2(_ requiredName: String, externalParamName localParamName: String) -> String { return "Hello \(requiredName), the day is \(localParamName)" } greet2(requiredName:"John", externalParamName: "Sunday") // 调用时,使用命名参数来指定参数的值 @@ -250,7 +250,7 @@ var increment = makeIncrementer() increment(7) // 强制进行指针传递 (引用传递),使用 `inout` 关键字修饰函数参数 -func swapTwoInts(inout a: Int, inout b: Int) { +func swapTwoInts(a: inout Int, b: inout Int) { let tempA = a a = b b = tempA @@ -521,7 +521,7 @@ class MyShape: Rect { // 在 optional 属性,方法或下标运算符后面加一个问号,可以优雅地忽略 nil 值,返回 nil。 // 这样就不会引起运行时错误 (runtime error) - if let reshape = self.delegate?.canReshape?() where reshape { + if let reshape = self.delegate?.canReshape?() { // 注意语句中的问号 self.delegate?.reshape?() } @@ -575,10 +575,10 @@ print(foundAtIndex == 2) // true // 自定义运算符可以以下面的字符打头: // / = - + * % < > ! & | ^ . ~ // 甚至是 Unicode 的数学运算符等 -prefix operator !!! {} +prefix operator !!! // 定义一个前缀运算符,使矩形的边长放大三倍 -prefix func !!! (inout shape: Square) -> Square { +prefix func !!! (shape: inout Square) -> Square { shape.sideLength *= 3 return shape } @@ -591,8 +591,8 @@ print(mySquare.sideLength) // 4 print(mySquare.sideLength) // 12 // 运算符也可以是泛型 -infix operator <-> {} -func <-><T: Equatable> (inout a: T, inout b: T) { +infix operator <-> +func <-><T: Equatable> (a: inout T, b: inout T) { let c = a a = b b = c diff --git a/zh-cn/typescript-cn.html.markdown b/zh-cn/typescript-cn.html.markdown index 032f89e4..5d6153da 100644 --- a/zh-cn/typescript-cn.html.markdown +++ b/zh-cn/typescript-cn.html.markdown @@ -9,97 +9,103 @@ filename: learntypescript-cn.ts lang: zh-cn --- -TypeScript是一门为开发大型JavaScript应用而设计的语言。TypeScript在JavaScript的基础上增加了类、模块、接口、泛型和静态类型(可选)等常见的概念。它是JavaScript的一个超集:所有JavaScript代码都是有效的TypeScript代码,所以任何JavaScript项目都可以无缝引入TypeScript. TypeScript编译器会把TypeScript代码编译成JavaScript代码。 +TypeScript 是一门为开发大型 JavaScript 应用而设计的语言。TypeScript 在 JavaScript 的基础上增加了类、模块、接口、泛型和静态类型(可选)等常见的概念。它是 JavaScript 的超集:所有 JavaScript 代码都是有效的 TypeScript 代码,因此任何 JavaScript 项目都可以无缝引入 TypeScript,TypeScript 编译器最终会把 TypeScript 代码编译成 JavaScript 代码。 -本文只关注TypeScript额外增加的区别于[JavaScript](../javascript-cn/)的语法,. +本文只关注 TypeScript 额外增加的区别于 [JavaScript](../javascript-cn/) 的语法,. -如需测试TypeScript编译器,你可以在[Playground](http://www.typescriptlang.org/Playground)码代码,它会自动编译成JavaScript代码然后直接显示出来。 +如需测试 TypeScript 编译器,你可以到 [Playground](https://www.typescriptlang.org/play/) 编写代码,它会自动将你编写的 TypeScript 代码编译成 JavaScript 代码后,在右侧即时展示出来。 -```js -// TypeScript有三种基本类型 -var isDone: boolean = false; -var lines: number = 42; -var name: string = "Anders"; +```ts +// TypeScript 有三种基本类型,布尔类型、数值类型、字符串类型 +let isDone: boolean = false; +let lines: number = 42; +let name: string = 'Anders'; -// 如果不知道是什么类型,可以使用"any"(任意)类型 -var notSure: any = 4; -notSure = "maybe a string instead"; -notSure = false; // 亦可,定义为布尔型 +// 如果不知道是什么类型,可以使用 "any" (任意)类型 +let notSure: any = 4; +notSure = '可以重新赋值,转换为字符串类型'; +notSure = false; // 亦可,重新定义为布尔类型 -// 对于集合的声明, 有类型化数组和泛型数组 -var list: number[] = [1, 2, 3]; -// 另外一种,使用泛型数组 -var list: Array<number> = [1, 2, 3]; +// 使用 const 关键字将一个字面量修饰为常量 +const numLivesForCat = 9; +numLivesForCat = 1; // 常量不能重新被赋值,所以这里会报错 + +// TypeScript 中的 collection 有两种表示形式, 一种是有类型的数组,另一种是泛型数组 +let list: number[] = [1, 2, 3]; +// 或者,使用泛型数组 +let list: Array<number> = [1, 2, 3]; // 枚举: -enum Color {Red, Green, Blue}; -var c: Color = Color.Green; +enum Color {Red, Green, Blue} +let c: Color = Color.Green; -// 最后,"void"用于函数没有任何返回的特殊情况下 +// 最后是 "void",它用于表明函数没有任何返回值的特殊情况 function bigHorribleAlert(): void { - alert("I'm a little annoying box!"); + alert('我是个烦人的弹出框!'); } -// 函数是"第一等公民"(first class citizens), 支持使用箭头表达式和类型推断 - -// 以下是相等的,TypeScript编译器会把它们编译成相同的JavaScript代码 -var f1 = function(i: number): number { return i * i; } -// 返回推断类型的值 -var f2 = function(i: number) { return i * i; } -var f3 = (i: number): number => { return i * i; } -// 返回推断类型的值 -var f4 = (i: number) => { return i * i; } -// 返回推断类型的值, 单行程式可以不需要return关键字和大括号 -var f5 = (i: number) => i * i; - -// 接口是结构化的,任何具有这些属性的对象都与该接口兼容 +// 函数是"一等公民"(first class citizens), 支持使用 lambda 胖箭头表达式和类型推断 + +// 以下 f1-f5 五个函数是等价的,TypeScript 编译器会把它们编译成相同的 JavaScript 代码(可以到 Playground 验证) +// 一般的函数 +let f1 = function(i: number): number { return i * i; }; +// 根据返回值推断函数返回类型 +let f2 = function(i: number) { return i * i; }; +// 胖箭头表达式 +let f3 = (i: number): number => { return i * i; }; +// 根据返回值推断返回类型的胖箭头表达式 +let f4 = (i: number) => { return i * i; }; +// 根据返回值推断返回类型的胖箭头表达式, 省略花括号的同时,可以同时省去 return 关键字 +let f5 = (i: number) => i * i; + +// 接口是结构化的,任何具备接口中声明的全部属性的对象,都与该接口兼容 interface Person { name: string; - // 可选属性,使用"?"标识 + // 使用 "?" 标识,表明该属性是一个非必需属性 age?: number; // 函数 move(): void; } -// 实现"Person"接口的对象,当它有了"name"和"move"方法之后可被视为一个"Person" -var p: Person = { name: "Bobby", move: () => {} }; -// 带了可选参数的对象 -var validPerson: Person = { name: "Bobby", age: 42, move: () => {} }; -// 因为"age"不是"number"类型所以这不是一个"Person" -var invalidPerson: Person = { name: "Bobby", age: true }; +// 实现 "Person" 接口的对象,当它具备 "name" 属性和 "move" 方法之后可被视为一个 "Person" +let p: Person = { name: 'Bobby', move: () => {} }; +// 带可选属性的对象 +let validPerson: Person = { name: 'Bobby', age: 42, move: () => {} }; +// 由于该对象 "age" 属性的类型不是 "number" ,所以这不是一个 "Person" +let invalidPerson: Person = { name: 'Bobby', age: true }; // 接口同样可以描述一个函数的类型 interface SearchFunc { (source: string, subString: string): boolean; } -// 参数名并不重要,参数类型才是重要的 -var mySearch: SearchFunc; +// 参数名并不重要,参数类型才是最重要的 +let mySearch: SearchFunc; mySearch = function(src: string, sub: string) { - return src.search(sub) != -1; -} + return src.search(sub) !== -1; +}; -// 类 - 成员默认为公共的(public) +// 类 - 成员访问权限默认都是公共的 (public) class Point { - // 属性 + // 成员属性 x: number; - // 构造器 - 这里面的public/private关键字会为属性生成样板代码和初始化值 - // 这个例子中,y会被同x一样定义,不需要额外代码 - // 同样支持默认值 + // 构造器 - 在构造器中使用 public/private 关键字修饰的变量,会被声明为类的成员属性。 + // 下面这个例子中,y 会像 x 一样被声明定义为类成员属性,而不再需要额外代码 + // 声明时,同样支持指定默认值 constructor(x: number, public y: number = 0) { this.x = x; } - // 函数 + // 成员函数 dist() { return Math.sqrt(this.x * this.x + this.y * this.y); } // 静态成员 static origin = new Point(0, 0); } -var p1 = new Point(10 ,20); -var p2 = new Point(25); //y为0 +let p1 = new Point(10 , 20); +let p2 = new Point(25); // y 为构造器中指定的默认值:0 // 继承 class Point3D extends Point { @@ -107,14 +113,14 @@ class Point3D extends Point { super(x, y); // 必须显式调用父类的构造器 } - // 重写 + // 重写父类中的 dist() 函数 dist() { - var d = super.dist(); + let d = super.dist(); return Math.sqrt(d * d + this.z * this.z); } } -// 模块, "."可以作为子模块的分隔符 +// 模块, "." 符号可以作为子模块的分隔符 module Geometry { export class Square { constructor(public sideLength: number = 0) { @@ -125,12 +131,12 @@ module Geometry { } } -var s1 = new Geometry.Square(5); +let s1 = new Geometry.Square(5); -// 引入模块并定义本地别名 +// 为模块创建一个本地别名 import G = Geometry; -var s2 = new G.Square(10); +let s2 = new G.Square(10); // 泛型 // 类 @@ -146,21 +152,21 @@ interface Pair<T> { } // 以及函数 -var pairToTuple = function<T>(p: Pair<T>) { +let pairToTuple = function<T>(p: Pair<T>) { return new Tuple(p.item1, p.item2); }; -var tuple = pairToTuple({ item1:"hello", item2:"world"}); +let tuple = pairToTuple({ item1: 'hello', item2: 'world'}); // 引用定义文件 /// <reference path="jquery.d.ts" /> // 模板字符串(使用反引号的字符串) // 嵌入变量的模板字符串 -var name = 'Tyrone'; -var greeting = `Hi ${name}, how are you?` +let name = 'Tyrone'; +let greeting = `Hi ${name}, how are you?`; // 有多行内容的模板字符串 -var multiline = `This is an example +let multiline = `This is an example of a multiline string`; ``` |