summaryrefslogtreecommitdiffhomepage
path: root/zh-cn
diff options
context:
space:
mode:
Diffstat (limited to 'zh-cn')
-rw-r--r--zh-cn/bash-cn.html.markdown2
-rw-r--r--zh-cn/csharp-cn.html.markdown3
-rw-r--r--zh-cn/go-cn.html.markdown4
-rw-r--r--zh-cn/groovy-cn.html.markdown420
-rw-r--r--zh-cn/haskell-cn.html.markdown6
-rw-r--r--zh-cn/java-cn.html.markdown4
-rw-r--r--zh-cn/javascript-cn.html.markdown5
-rw-r--r--zh-cn/markdown-cn.html.markdown2
-rw-r--r--zh-cn/python3-cn.html.markdown2
-rw-r--r--zh-cn/ruby-cn.html.markdown9
-rw-r--r--zh-cn/rust-cn.html.markdown296
-rw-r--r--zh-cn/swift-cn.html.markdown131
12 files changed, 811 insertions, 73 deletions
diff --git a/zh-cn/bash-cn.html.markdown b/zh-cn/bash-cn.html.markdown
index 558d9110..d85e5b8f 100644
--- a/zh-cn/bash-cn.html.markdown
+++ b/zh-cn/bash-cn.html.markdown
@@ -258,7 +258,7 @@ help return
help source
help .
-# 用 mam 指令阅读相关的 Bash 手册
+# 用 man 指令阅读相关的 Bash 手册
apropos bash
man 1 bash
man bash
diff --git a/zh-cn/csharp-cn.html.markdown b/zh-cn/csharp-cn.html.markdown
index a3cda5b3..971c1be9 100644
--- a/zh-cn/csharp-cn.html.markdown
+++ b/zh-cn/csharp-cn.html.markdown
@@ -232,7 +232,8 @@ on a new line! ""Wow!"", the masses cried";
// 三元表达式
// 简单的 if/else 语句可以写成:
// <条件> ? <真> : <假>
- string isTrue = (true) ? "True" : "False";
+ int toCompare = 17;
+ string isTrue = toCompare == 17 ? "True" : "False";
// While 循环
int fooWhile = 0;
diff --git a/zh-cn/go-cn.html.markdown b/zh-cn/go-cn.html.markdown
index 9f6a8c15..49224085 100644
--- a/zh-cn/go-cn.html.markdown
+++ b/zh-cn/go-cn.html.markdown
@@ -239,7 +239,7 @@ func learnConcurrency() {
go inc(0, c) // go is a statement that starts a new goroutine.
go inc(10, c)
go inc(-805, c)
- // 从channel中独处结果并打印。
+ // 从channel中读取结果并打印。
// 打印出什么东西是不可预知的。
fmt.Println(<-c, <-c, <-c) // channel在右边的时候,<-是读操作。
@@ -283,4 +283,4 @@ Go的根源在[Go官方网站](http://golang.org/)。
强烈推荐阅读语言定义部分,很简单而且很简洁!(as language definitions go these days.)
-学习Go还要阅读Go标准库的源代码,全部文档化了,可读性非常好,可以学到go,go style和go idioms。在文档中点击函数名,源代码就出来了!
+学习Go还要阅读Go[标准库的源代码](http://golang.org/src/),全部文档化了,可读性非常好,可以学到go,go style和go idioms。在[文档](http://golang.org/pkg/)中点击函数名,源代码就出来了!
diff --git a/zh-cn/groovy-cn.html.markdown b/zh-cn/groovy-cn.html.markdown
new file mode 100644
index 00000000..562a0284
--- /dev/null
+++ b/zh-cn/groovy-cn.html.markdown
@@ -0,0 +1,420 @@
+---
+language: Groovy
+filename: learngroovy-cn.groovy
+contributors:
+ - ["Roberto Pérez Alcolea", "http://github.com/rpalcolea"]
+translators:
+ - ["Todd Gao", "http://github.com/7c00"]
+lang: zh-cn
+---
+
+Groovy - Java平台的动态语言。[了解更多。](http://www.groovy-lang.org/)
+
+```groovy
+
+/*
+ 安装:
+
+ 1) 安装 GVM - http://gvmtool.net/
+ 2) 安装 Groovy: gvm install groovy
+ 3) 启动 groovy 控制台,键入: groovyConsole
+
+*/
+
+// 双斜线开始的是单行注释
+/*
+像这样的是多行注释
+*/
+
+// Hello World
+println "Hello world!"
+
+/*
+ 变量:
+
+ 可以给变量赋值,以便稍后使用
+*/
+
+def x = 1
+println x
+
+x = new java.util.Date()
+println x
+
+x = -3.1499392
+println x
+
+x = false
+println x
+
+x = "Groovy!"
+println x
+
+/*
+ 集合和映射
+*/
+
+//创建一个空的列表
+def technologies = []
+
+/*** 往列表中增加一个元素 ***/
+
+// 和Java一样
+technologies.add("Grails")
+
+// 左移添加,返回该列表
+technologies << "Groovy"
+
+// 增加多个元素
+technologies.addAll(["Gradle","Griffon"])
+
+/*** 从列表中删除元素 ***/
+
+// 和Java一样
+technologies.remove("Griffon")
+
+// 减号也行
+technologies = technologies - 'Grails'
+
+/*** 遍历列表 ***/
+
+// 遍历列表中的元素
+technologies.each { println "Technology: $it"}
+technologies.eachWithIndex { it, i -> println "$i: $it"}
+
+/*** 检查列表内容 ***/
+
+//判断列表是否包含某元素,返回boolean
+contained = technologies.contains( 'Groovy' )
+
+// 或
+contained = 'Groovy' in technologies
+
+// 检查多个元素
+technologies.containsAll(['Groovy','Grails'])
+
+/*** 列表排序 ***/
+
+// 排序列表(修改原列表)
+technologies.sort()
+
+// 要想不修改原列表,可以这样:
+sortedTechnologies = technologies.sort( false )
+
+/*** 列表操作 ***/
+
+//替换列表元素
+Collections.replaceAll(technologies, 'Gradle', 'gradle')
+
+//打乱列表
+Collections.shuffle(technologies, new Random())
+
+//清空列表
+technologies.clear()
+
+//创建空的映射
+def devMap = [:]
+
+//增加值
+devMap = ['name':'Roberto', 'framework':'Grails', 'language':'Groovy']
+devMap.put('lastName','Perez')
+
+//遍历映射元素
+devMap.each { println "$it.key: $it.value" }
+devMap.eachWithIndex { it, i -> println "$i: $it"}
+
+//判断映射是否包含某键
+assert devMap.containsKey('name')
+
+//判断映射是否包含某值
+assert devMap.containsValue('Roberto')
+
+//取得映射所有的键
+println devMap.keySet()
+
+//取得映射所有的值
+println devMap.values()
+
+/*
+ Groovy Beans
+
+ GroovyBeans 是 JavaBeans,但使用了更简单的语法
+
+ Groovy 被编译为字节码时,遵循下列规则。
+
+ * 如果一个名字声明时带有访问修饰符(public, private, 或者 protected),
+ 则会生成一个字段(field)。
+
+ * 名字声明时没有访问修饰符,则会生成一个带有public getter和setter的
+ private字段,即属性(property)。
+
+ * 如果一个属性声明为final,则会创建一个final的private字段,但不会生成setter。
+
+ * 可以声明一个属性的同时定义自己的getter和setter。
+
+ * 可以声明具有相同名字的属性和字段,该属性会使用该字段。
+
+ * 如果要定义private或protected属性,必须提供声明为private或protected的getter
+ 和setter。
+
+ * 如果使用显式或隐式的 this(例如 this.foo, 或者 foo)访问类的在编译时定义的属性,
+ Groovy会直接访问对应字段,而不是使用getter或者setter
+
+ * 如果使用显式或隐式的 foo 访问一个不存在的属性,Groovy会通过元类(meta class)
+ 访问它,这可能导致运行时错误。
+
+*/
+
+class Foo {
+ // 只读属性
+ final String name = "Roberto"
+
+ // 只读属性,有public getter和protected setter
+ String language
+ protected void setLanguage(String language) { this.language = language }
+
+ // 动态类型属性
+ def lastName
+}
+
+/*
+ 逻辑分支和循环
+*/
+
+//Groovy支持常见的if - else语法
+def x = 3
+
+if(x==1) {
+ println "One"
+} else if(x==2) {
+ println "Two"
+} else {
+ println "X greater than Two"
+}
+
+//Groovy也支持三元运算符
+def y = 10
+def x = (y > 1) ? "worked" : "failed"
+assert x == "worked"
+
+//for循环
+//使用区间(range)遍历
+def x = 0
+for (i in 0 .. 30) {
+ x += i
+}
+
+//遍历列表
+x = 0
+for( i in [5,3,2,1] ) {
+ x += i
+}
+
+//遍历数组
+array = (0..20).toArray()
+x = 0
+for (i in array) {
+ x += i
+}
+
+//遍历映射
+def map = ['name':'Roberto', 'framework':'Grails', 'language':'Groovy']
+x = 0
+for ( e in map ) {
+ x += e.value
+}
+
+/*
+ 运算符
+
+ 在Groovy中以下常用运算符支持重载:
+ http://www.groovy-lang.org/operators.html#Operator-Overloading
+
+ 实用的groovy运算符
+*/
+//展开(spread)运算符:对聚合对象的所有元素施加操作
+def technologies = ['Groovy','Grails','Gradle']
+technologies*.toUpperCase() // 相当于 technologies.collect { it?.toUpperCase() }
+
+//安全导航(safe navigation)运算符:用来避免NullPointerException
+def user = User.get(1)
+def username = user?.username
+
+
+/*
+ 闭包
+ Groovy闭包好比代码块或者方法指针,它是一段代码定义,可以以后执行。
+
+ 更多信息见:http://www.groovy-lang.org/closures.html
+*/
+//例子:
+def clos = { println "Hello World!" }
+
+println "Executing the Closure:"
+clos()
+
+//传参数给闭包
+def sum = { a, b -> println a+b }
+sum(2,4)
+
+//闭包可以引用参数列表以外的变量
+def x = 5
+def multiplyBy = { num -> num * x }
+println multiplyBy(10)
+
+// 只有一个参数的闭包可以省略参数的定义
+def clos = { print it }
+clos( "hi" )
+
+/*
+ Groovy可以记忆闭包结果 [1][2][3]
+*/
+def cl = {a, b ->
+ sleep(3000) // 模拟费时操作
+ a + b
+}
+
+mem = cl.memoize()
+
+def callClosure(a, b) {
+ def start = System.currentTimeMillis()
+ mem(a, b)
+ println "Inputs(a = $a, b = $b) - took ${System.currentTimeMillis() - start} msecs."
+}
+
+callClosure(1, 2)
+callClosure(1, 2)
+callClosure(2, 3)
+callClosure(2, 3)
+callClosure(3, 4)
+callClosure(3, 4)
+callClosure(1, 2)
+callClosure(2, 3)
+callClosure(3, 4)
+
+/*
+ Expando
+
+ Expando类是一种动态bean类,可以给它的实例添加属性和添加闭包作为方法
+
+ http://mrhaki.blogspot.mx/2009/10/groovy-goodness-expando-as-dynamic-bean.html
+*/
+ def user = new Expando(name:"Roberto")
+ assert 'Roberto' == user.name
+
+ user.lastName = 'Pérez'
+ assert 'Pérez' == user.lastName
+
+ user.showInfo = { out ->
+ out << "Name: $name"
+ out << ", Last name: $lastName"
+ }
+
+ def sw = new StringWriter()
+ println user.showInfo(sw)
+
+
+/*
+ 元编程(MOP)
+*/
+
+//使用ExpandoMetaClass增加行为
+String.metaClass.testAdd = {
+ println "we added this"
+}
+
+String x = "test"
+x?.testAdd()
+
+//拦截方法调用
+class Test implements GroovyInterceptable {
+ def sum(Integer x, Integer y) { x + y }
+
+ def invokeMethod(String name, args) {
+ System.out.println "Invoke method $name with args: $args"
+ }
+}
+
+def test = new Test()
+test?.sum(2,3)
+test?.multiply(2,3)
+
+//Groovy支持propertyMissing,来处理属性解析尝试
+class Foo {
+ def propertyMissing(String name) { name }
+}
+def f = new Foo()
+
+assertEquals "boo", f.boo
+
+/*
+ 类型检查和静态编译
+ Groovy天生是并将永远是一门动态语言,但也支持类型检查和静态编译
+
+ 更多: http://www.infoq.com/articles/new-groovy-20
+*/
+//类型检查
+import groovy.transform.TypeChecked
+
+void testMethod() {}
+
+@TypeChecked
+void test() {
+ testMeethod()
+
+ def name = "Roberto"
+
+ println naameee
+
+}
+
+//另一例子
+import groovy.transform.TypeChecked
+
+@TypeChecked
+Integer test() {
+ Integer num = "1"
+
+ Integer[] numbers = [1,2,3,4]
+
+ Date date = numbers[1]
+
+ return "Test"
+
+}
+
+//静态编译例子
+import groovy.transform.CompileStatic
+
+@CompileStatic
+int sum(int x, int y) {
+ x + y
+}
+
+assert sum(2,5) == 7
+
+
+```
+
+## 进阶资源
+
+[Groovy文档](http://www.groovy-lang.org/documentation.html)
+
+[Groovy web console](http://groovyconsole.appspot.com/)
+
+加入[Groovy用户组](http://www.groovy-lang.org/usergroups.html)
+
+## 图书
+
+* [Groovy Goodness] (https://leanpub.com/groovy-goodness-notebook)
+
+* [Groovy in Action] (http://manning.com/koenig2/)
+
+* [Programming Groovy 2: Dynamic Productivity for the Java Developer] (http://shop.oreilly.com/product/9781937785307.do)
+
+[1] http://roshandawrani.wordpress.com/2010/10/18/groovy-new-feature-closures-can-now-memorize-their-results/
+[2] http://www.solutionsiq.com/resources/agileiq-blog/bid/72880/Programming-with-Groovy-Trampoline-and-Memoize
+[3] http://mrhaki.blogspot.mx/2011/05/groovy-goodness-cache-closure-results.html
+
+
+
diff --git a/zh-cn/haskell-cn.html.markdown b/zh-cn/haskell-cn.html.markdown
index 8904970f..b0b1183f 100644
--- a/zh-cn/haskell-cn.html.markdown
+++ b/zh-cn/haskell-cn.html.markdown
@@ -200,13 +200,13 @@ foo 5 -- 75
-- 你可以使用 `$` 来移除多余的括号。
-- 修改前
-(even (fib 7)) -- true
+(even (fib 7)) -- False
-- 修改后
-even . fib $ 7 -- true
+even . fib $ 7 -- False
-- 等价地
-even $ fib 7 -- true
+even $ fib 7 -- False
----------------------------------------------------
-- 5. 类型声明
diff --git a/zh-cn/java-cn.html.markdown b/zh-cn/java-cn.html.markdown
index f08d3507..a8fd2a4c 100644
--- a/zh-cn/java-cn.html.markdown
+++ b/zh-cn/java-cn.html.markdown
@@ -149,7 +149,7 @@ public class LearnJava {
// 位运算操作符
/*
- ~ 补
+ ~ 取反,求反码
<< 带符号左移
>> 带符号右移
>>> 无符号右移
@@ -405,4 +405,4 @@ class PennyFarthing extends Bicycle {
* [泛型](http://docs.oracle.com/javase/tutorial/java/generics/index.html)
-* [Java代码规范](http://www.oracle.com/technetwork/java/codeconv-138413.html)
+* [Java代码规范](http://www.oracle.com/technetwork/java/codeconvtoc-136057.html)
diff --git a/zh-cn/javascript-cn.html.markdown b/zh-cn/javascript-cn.html.markdown
index b450ab84..bdef0099 100644
--- a/zh-cn/javascript-cn.html.markdown
+++ b/zh-cn/javascript-cn.html.markdown
@@ -402,7 +402,7 @@ myObj.meaningOfLife; // = 42
// 函数也可以工作。
myObj.myFunc() // = "hello world!"
-// 当然,如果你要访问的成员在原型当中也没有定义的话,解释器就会去找原型的原型,以此类堆。
+// 当然,如果你要访问的成员在原型当中也没有定义的话,解释器就会去找原型的原型,以此类推。
myPrototype.__proto__ = {
myBoolean: true
};
@@ -447,9 +447,6 @@ myNumber === myNumberObj; // = false
if (0){
// 这段代码不会执行,因为0代表假
}
-if (Number(0)){
- // 这段代码*会*执行,因为Number(0)代表真
-}
// 不过,包装类型和内置类型共享一个原型,
// 所以你实际可以给内置类型也增加一些功能,例如对string:
diff --git a/zh-cn/markdown-cn.html.markdown b/zh-cn/markdown-cn.html.markdown
index b1143dac..b633714d 100644
--- a/zh-cn/markdown-cn.html.markdown
+++ b/zh-cn/markdown-cn.html.markdown
@@ -69,7 +69,7 @@ __此文本也是__
<!-- 如果你插入一个 HTML中的<br />标签,你可以在段末加入两个以上的空格,
然后另起一段。-->
-此段落结尾有两个空格(选中以显示)。
+此段落结尾有两个空格(选中以显示)。
上文有一个 <br /> !
diff --git a/zh-cn/python3-cn.html.markdown b/zh-cn/python3-cn.html.markdown
index c223297c..76455a46 100644
--- a/zh-cn/python3-cn.html.markdown
+++ b/zh-cn/python3-cn.html.markdown
@@ -535,7 +535,7 @@ Human.grunt() # => "*grunt*"
# 用import导入模块
import math
-print(math.sqrt(16)) # => 4
+print(math.sqrt(16)) # => 4.0
# 也可以从模块中导入个别值
from math import ceil, floor
diff --git a/zh-cn/ruby-cn.html.markdown b/zh-cn/ruby-cn.html.markdown
index 99250b43..14d38137 100644
--- a/zh-cn/ruby-cn.html.markdown
+++ b/zh-cn/ruby-cn.html.markdown
@@ -7,6 +7,7 @@ contributors:
- ["Joel Walden", "http://joelwalden.net"]
- ["Luke Holder", "http://twitter.com/lukeholder"]
- ["lidashuang", "https://github.com/lidashuang"]
+ - ["ftwbzhao", "https://github.com/ftwbzhao"]
translators:
- ["Lin Xiangyu", "https://github.com/oa414"]
---
@@ -120,11 +121,11 @@ status == :approved #=> false
# 数组
# 这是一个数组
-[1, 2, 3, 4, 5] #=> [1, 2, 3, 4, 5]
+array = [1, 2, 3, 4, 5] #=> [1, 2, 3, 4, 5]
# 数组可以包含不同类型的元素
-array = [1, "hello", false] #=> => [1, "hello", false]
+[1, "hello", false] #=> [1, "hello", false]
# 数组可以被索引
# 从前面开始
@@ -140,8 +141,8 @@ array.[] 12 #=> nil
# 从尾部开始
array[-1] #=> 5
-# 同时指定开始的位置和结束的位置
-array[2, 4] #=> [3, 4, 5]
+# 同时指定开始的位置和长度
+array[2, 3] #=> [3, 4, 5]
# 或者指定一个范围
array[1..3] #=> [2, 3, 4]
diff --git a/zh-cn/rust-cn.html.markdown b/zh-cn/rust-cn.html.markdown
new file mode 100644
index 00000000..17a897df
--- /dev/null
+++ b/zh-cn/rust-cn.html.markdown
@@ -0,0 +1,296 @@
+---
+language: rust
+contributors:
+ - ["P1start", "http://p1start.github.io/"]
+translators:
+ - ["Guangming Mao", "http://maogm.com"]
+filename: learnrust-cn.rs
+lang: zh-cn
+---
+
+Rust 是由 Mozilla 研究院开发的编程语言。Rust 将底层的性能控制与高级语言的便利性和安全保障结合在了一起。
+
+而 Rust 并不需要一个垃圾回收器或者运行时即可实现这个目的,这使得 Rust 库可以成为一种 C 语言的替代品。
+
+Rust 第一版(0.1 版)发布于 2012 年 1 月,3 年以来一直在紧锣密鼓地迭代。
+因为更新太频繁,一般建议使用每夜构建版而不是稳定版,直到最近 1.0 版本的发布。
+
+2015 年 3 月 15 日,Rust 1.0 发布,完美向后兼容,最新的每夜构建版提供了缩短编译时间等新特性。
+Rust 采用了持续迭代模型,每 6 周一个发布版。Rust 1.1 beta 版在 1.0 发布时同时发布。
+
+尽管 Rust 相对来说是一门底层语言,它提供了一些常见于高级语言的函数式编程的特性。这让 Rust 不仅高效,并且易用。
+
+```rust
+// 这是注释,单行注释...
+/* ...这是多行注释 */
+
+///////////////
+// 1. 基础 //
+///////////////
+
+// 函数 (Functions)
+// `i32` 是有符号 32 位整数类型(32-bit signed integers)
+fn add2(x: i32, y: i32) -> i32 {
+ // 隐式返回 (不要分号)
+ x + y
+}
+
+// 主函数(Main function)
+fn main() {
+ // 数字 (Numbers) //
+
+ // 不可变绑定
+ let x: i32 = 1;
+
+ // 整形/浮点型数 后缀
+ let y: i32 = 13i32;
+ let f: f64 = 1.3f64;
+
+ // 类型推导
+ // 大部分时间,Rust 编译器会推导变量类型,所以不必把类型显式写出来。
+ // 这个教程里面很多地方都显式写了类型,但是只是为了示范。
+ // 绝大部分时间可以交给类型推导。
+ let implicit_x = 1;
+ let implicit_f = 1.3;
+
+ // 算术运算
+ let sum = x + y + 13;
+
+ // 可变变量
+ let mut mutable = 1;
+ mutable = 4;
+ mutable += 2;
+
+ // 字符串 (Strings) //
+
+ // 字符串字面量
+ let x: &str = "hello world!";
+
+ // 输出
+ println!("{} {}", f, x); // 1.3 hello world
+
+ // 一个 `String` – 在堆上分配空间的字符串
+ let s: String = "hello world".to_string();
+
+ // 字符串分片(slice) - 另一个字符串的不可变视图
+ // 基本上就是指向一个字符串的不可变指针,它不包含字符串里任何内容,只是一个指向某个东西的指针
+ // 比如这里就是 `s`
+ let s_slice: &str = &s;
+
+ println!("{} {}", s, s_slice); // hello world hello world
+
+ // 数组 (Vectors/arrays) //
+
+ // 长度固定的数组 (array)
+ let four_ints: [i32; 4] = [1, 2, 3, 4];
+
+ // 变长数组 (vector)
+ let mut vector: Vec<i32> = vec![1, 2, 3, 4];
+ vector.push(5);
+
+ // 分片 - 某个数组(vector/array)的不可变视图
+ // 和字符串分片基本一样,只不过是针对数组的
+ let slice: &[i32] = &vector;
+
+ // 使用 `{:?}` 按调试样式输出
+ println!("{:?} {:?}", vector, slice); // [1, 2, 3, 4, 5] [1, 2, 3, 4, 5]
+
+ // 元组 (Tuples) //
+
+ // 元组是固定大小的一组值,可以是不同类型
+ let x: (i32, &str, f64) = (1, "hello", 3.4);
+
+ // 解构 `let`
+ let (a, b, c) = x;
+ println!("{} {} {}", a, b, c); // 1 hello 3.4
+
+ // 索引
+ println!("{}", x.1); // hello
+
+ //////////////
+ // 2. 类型 (Type) //
+ //////////////
+
+ // 结构体(Sturct)
+ struct Point {
+ x: i32,
+ y: i32,
+ }
+
+ let origin: Point = Point { x: 0, y: 0 };
+
+ // 匿名成员结构体,又叫“元组结构体”(‘tuple struct’)
+ struct Point2(i32, i32);
+
+ let origin2 = Point2(0, 0);
+
+ // 基础的 C 风格枚举类型(enum)
+ enum Direction {
+ Left,
+ Right,
+ Up,
+ Down,
+ }
+
+ let up = Direction::Up;
+
+ // 有成员的枚举类型
+ enum OptionalI32 {
+ AnI32(i32),
+ Nothing,
+ }
+
+ let two: OptionalI32 = OptionalI32::AnI32(2);
+ let nothing = OptionalI32::Nothing;
+
+ // 泛型 (Generics) //
+
+ struct Foo<T> { bar: T }
+
+ // 这个在标准库里面有实现,叫 `Option`
+ enum Optional<T> {
+ SomeVal(T),
+ NoVal,
+ }
+
+ // 方法 (Methods) //
+
+ impl<T> Foo<T> {
+ // 方法需要一个显式的 `self` 参数
+ fn get_bar(self) -> T {
+ self.bar
+ }
+ }
+
+ let a_foo = Foo { bar: 1 };
+ println!("{}", a_foo.get_bar()); // 1
+
+ // 接口(Traits) (其他语言里叫 interfaces 或 typeclasses) //
+
+ trait Frobnicate<T> {
+ fn frobnicate(self) -> Option<T>;
+ }
+
+ impl<T> Frobnicate<T> for Foo<T> {
+ fn frobnicate(self) -> Option<T> {
+ Some(self.bar)
+ }
+ }
+
+ let another_foo = Foo { bar: 1 };
+ println!("{:?}", another_foo.frobnicate()); // Some(1)
+
+ ///////////////////////////////////
+ // 3. 模式匹配 (Pattern matching) //
+ ///////////////////////////////////
+
+ let foo = OptionalI32::AnI32(1);
+ match foo {
+ OptionalI32::AnI32(n) => println!("it’s an i32: {}", n),
+ OptionalI32::Nothing => println!("it’s nothing!"),
+ }
+
+ // 高级模式匹配
+ struct FooBar { x: i32, y: OptionalI32 }
+ let bar = FooBar { x: 15, y: OptionalI32::AnI32(32) };
+
+ match bar {
+ FooBar { x: 0, y: OptionalI32::AnI32(0) } =>
+ println!("The numbers are zero!"),
+ FooBar { x: n, y: OptionalI32::AnI32(m) } if n == m =>
+ println!("The numbers are the same"),
+ FooBar { x: n, y: OptionalI32::AnI32(m) } =>
+ println!("Different numbers: {} {}", n, m),
+ FooBar { x: _, y: OptionalI32::Nothing } =>
+ println!("The second number is Nothing!"),
+ }
+
+ ///////////////////////////////
+ // 4. 流程控制 (Control flow) //
+ ///////////////////////////////
+
+ // `for` 循环
+ let array = [1, 2, 3];
+ for i in array.iter() {
+ println!("{}", i);
+ }
+
+ // 区间 (Ranges)
+ for i in 0u32..10 {
+ print!("{} ", i);
+ }
+ println!("");
+ // 输出 `0 1 2 3 4 5 6 7 8 9 `
+
+ // `if`
+ if 1 == 1 {
+ println!("Maths is working!");
+ } else {
+ println!("Oh no...");
+ }
+
+ // `if` 可以当表达式
+ let value = if true {
+ "good"
+ } else {
+ "bad"
+ };
+
+ // `while` 循环
+ while 1 == 1 {
+ println!("The universe is operating normally.");
+ }
+
+ // 无限循环
+ loop {
+ println!("Hello!");
+ }
+
+ ////////////////////////////////////////////////
+ // 5. 内存安全和指针 (Memory safety & pointers) //
+ ////////////////////////////////////////////////
+
+ // 独占指针 (Owned pointer) - 同一时刻只能有一个对象能“拥有”这个指针
+ // 意味着 `Box` 离开他的作用域后,会被安全地释放
+ let mut mine: Box<i32> = Box::new(3);
+ *mine = 5; // 解引用
+ // `now_its_mine` 获取了 `mine` 的所有权。换句话说,`mine` 移动 (move) 了
+ let mut now_its_mine = mine;
+ *now_its_mine += 2;
+
+ println!("{}", now_its_mine); // 7
+ // println!("{}", mine); // 编译报错,因为现在 `now_its_mine` 独占那个指针
+
+ // 引用 (Reference) – 引用其他数据的不可变指针
+ // 当引用指向某个值,我们称为“借用”这个值,因为是被不可变的借用,所以不能被修改,也不能移动
+ // 借用一直持续到生命周期结束,即离开作用域
+ let mut var = 4;
+ var = 3;
+ let ref_var: &i32 = &var;
+
+ println!("{}", var); //不像 `box`, `var` 还可以继续使用
+ println!("{}", *ref_var);
+ // var = 5; // 编译报错,因为 `var` 被借用了
+ // *ref_var = 6; // 编译报错,因为 `ref_var` 是不可变引用
+
+ // 可变引用 (Mutable reference)
+ // 当一个变量被可变地借用时,也不可使用
+ let mut var2 = 4;
+ let ref_var2: &mut i32 = &mut var2;
+ *ref_var2 += 2;
+
+ println!("{}", *ref_var2); // 6
+ // var2 = 2; // 编译报错,因为 `var2` 被借用了
+}
+```
+
+## 更深入的资料
+
+Rust 还有很多很多其他内容 - 这只是 Rust 最基本的功能,帮助你了解 Rust 里面最重要的东西。
+如果想深入学习 Rust,可以去读
+[The Rust Programming Language](http://doc.rust-lang.org/book/index.html)
+或者上 reddit [/r/rust](http://reddit.com/r/rust) 订阅。
+同时 irc.mozilla.org 的 #rust 频道上的小伙伴们也非常欢迎新来的朋友。
+
+你可以在这个在线编译器 [Rust playpen](http://play.rust-lang.org) 上尝试 Rust 的一些特性
+或者上[官方网站](http://rust-lang.org).
diff --git a/zh-cn/swift-cn.html.markdown b/zh-cn/swift-cn.html.markdown
index 28001e3f..3efe4941 100644
--- a/zh-cn/swift-cn.html.markdown
+++ b/zh-cn/swift-cn.html.markdown
@@ -5,7 +5,8 @@ contributors:
- ["Grant Timmerman", "http://github.com/grant"]
translators:
- ["Xavier Yao", "http://github.com/xavieryao"]
- - ["Joey Huang", "http://github.com/kamidox"]
+ - ["Joey Huang", "http://github.com/kamidox"]
+ - ["CY Lim", "http://github.com/cylim"]
lang: zh-cn
---
@@ -13,13 +14,13 @@ Swift 是 Apple 开发的用于 iOS 和 OS X 开发的编程语言。Swift 于20
Swift 的官方语言教程 [Swift Programming Language](https://itunes.apple.com/us/book/swift-programming-language/id881256329) 可以从 iBooks 免费下载.
-亦可参阅:Apple's [getting started guide](https://developer.apple.com/library/prerelease/ios/referencelibrary/GettingStarted/RoadMapiOS/index.html) ——一个完整的Swift 教程
+亦可参阅:Apple's [getting started guide](https://developer.apple.com/library/prerelease/ios/referencelibrary/GettingStarted/DevelopiOSAppsSwift/) ——一个完整的Swift 教程
```swift
// 导入外部模块
import UIKit
-//
+//
// MARK: 基础
//
@@ -28,12 +29,14 @@ import UIKit
// TODO: TODO 标记
// FIXME: FIXME 标记
-println("Hello, world")
+// Swift2.0 println() 及 print() 已经整合成 print()。
+print("Hello, world") // 这是原本的 println(),会自动进入下一行
+print("Hello, world", appendNewLine: false) // 如果不要自动进入下一行,需设定进入下一行为 false
// 变量 (var) 的值设置后可以随意改变
// 常量 (let) 的值设置后不能改变
var myVariable = 42
-let øπΩ = "value" // 可以支持 unicode 变量名
+let øπΩ = "value" // 可以支持 unicode 变量名
let π = 3.1415926
let myConstant = 3.1415926
let explicitDouble: Double = 70 // 明确指定变量类型为 Double ,否则编译器将自动推断变量类型
@@ -46,16 +49,17 @@ let piText = "Pi = \(π), Pi 2 = \(π * 2)" // 格式化字符串
// 条件编译
// 使用 -D 定义编译开关
#if false
- println("Not printed")
+ print("Not printed")
let buildValue = 3
#else
let buildValue = 7
#endif
-println("Build value: \(buildValue)") // Build value: 7
+print("Build value: \(buildValue)") // Build value: 7
/*
- Optionals 是 Swift 的新特性,它允许你存储两种状态的值给 Optional 变量:有效值或 None
-
+ Optionals 是 Swift 的新特性,它允许你存储两种状态的值给 Optional 变量:有效值或 None 。
+ 可在值名称后加个问号 (?) 来表示这个值是 Optional。
+
Swift 要求所有的 Optinal 属性都必须有明确的值,如果为空,则必须明确设定为 nil
Optional<T> 是个枚举类型
@@ -67,13 +71,17 @@ var someOptionalString2: Optional<String> = "optional"
if someOptionalString != nil {
// 变量不为空
if someOptionalString!.hasPrefix("opt") {
- println("has the prefix")
+ print("has the prefix")
}
-
+
let empty = someOptionalString?.isEmpty
}
someOptionalString = nil
+/*
+ 使用 (!) 可以解决无法访问optional值的运行错误。若要使用 (!)来强制解析,一定要确保 Optional 里不是 nil参数。
+*/
+
// 显式解包 optional 变量
var unwrappedString: String! = "Value is expected."
// 下面语句和上面完全等价,感叹号 (!) 是个后缀运算符,这也是个语法糖
@@ -94,7 +102,7 @@ anyObjectVar = "Changed value to a string, not good practice, but possible."
/*
这里是注释
-
+
/*
支持嵌套的注释
*/
@@ -116,6 +124,7 @@ shoppingList[1] = "bottle of water"
let emptyArray = [String]() // 使用 let 定义常量,此时 emptyArray 数组不能添加或删除内容
let emptyArray2 = Array<String>() // 与上一语句等价,上一语句更常用
var emptyMutableArray = [String]() // 使用 var 定义变量,可以向 emptyMutableArray 添加数组元素
+var explicitEmptyMutableStringArray: [String] = [] // 与上一语句等价
// 字典
var occupations = [
@@ -126,6 +135,7 @@ occupations["Jayne"] = "Public Relations" // 修改字典,如果 key 不存
let emptyDictionary = [String: Float]() // 使用 let 定义字典常量,字典常量不能修改里面的值
let emptyDictionary2 = Dictionary<String, Float>() // 与上一语句类型等价,上一语句更常用
var emptyMutableDictionary = [String: Float]() // 使用 var 定义字典变量
+var explicitEmptyMutableDictionary: [String: Float] = [:] // 与上一语句类型等价
//
@@ -136,21 +146,21 @@ var emptyMutableDictionary = [String: Float]() // 使用 var 定义字典变量
let myArray = [1, 1, 2, 3, 5]
for value in myArray {
if value == 1 {
- println("One!")
+ print("One!")
} else {
- println("Not one!")
+ print("Not one!")
}
}
// 字典的 for 循环
var dict = ["one": 1, "two": 2]
for (key, value) in dict {
- println("\(key): \(value)")
+ print("\(key): \(value)")
}
// 区间的 loop 循环:其中 `...` 表示闭环区间,即[-1, 3];`..<` 表示半开闭区间,即[-1,3)
for i in -1...shoppingList.count {
- println(i)
+ print(i)
}
shoppingList[1...2] = ["steak", "peacons"]
// 可以使用 `..<` 来去掉最后一个元素
@@ -163,7 +173,7 @@ while i < 1000 {
// do-while 循环
do {
- println("hello")
+ print("hello")
} while 1 == 2
// Switch 语句
@@ -177,7 +187,7 @@ case "cucumber", "watercress":
let vegetableComment = "That would make a good tea sandwich."
case let localScopeValue where localScopeValue.hasSuffix("pepper"):
let vegetableComment = "Is it a spicy \(localScopeValue)?"
-default: // 在 Swift 里,switch 语句的 case 必须处理所有可能的情况,如果 case 无法全部处理,则必须包含 default语句
+default: // 在 Swift 里,switch 语句的 case 必须处理所有可能的情况,如果 case 无法全部处理,则必须包含 default语句
let vegetableComment = "Everything tastes good in soup."
}
@@ -219,8 +229,8 @@ let pricesTuple = getGasPrices()
let price = pricesTuple.2 // 3.79
// 通过下划线 (_) 来忽略不关心的值
let (_, price1, _) = pricesTuple // price1 == 3.69
-println(price1 == pricesTuple.1) // true
-println("Gas price: \(price)")
+print(price1 == pricesTuple.1) // true
+print("Gas price: \(price)")
// 可变参数
func setup(numbers: Int...) {
@@ -248,7 +258,7 @@ func swapTwoInts(inout a: Int, inout b: Int) {
var someIntA = 7
var someIntB = 3
swapTwoInts(&someIntA, &someIntB)
-println(someIntB) // 7
+print(someIntB) // 7
//
@@ -256,7 +266,7 @@ println(someIntB) // 7
//
var numbers = [1, 2, 6]
-// 函数是闭包的一个特例
+// 函数是闭包的一个特例 ({})
// 闭包实例
// `->` 分隔了闭包的参数和返回值
@@ -296,7 +306,7 @@ print(numbers) // [3, 6, 18]
struct NamesTable {
let names = [String]()
-
+
// 自定义下标运算符
subscript(index: Int) -> String {
return names[index]
@@ -306,7 +316,7 @@ struct NamesTable {
// 结构体有一个自动生成的隐含的命名构造函数
let namesTable = NamesTable(names: ["Me", "Them"])
let name = namesTable[1]
-println("Name is \(name)") // Name is Them
+print("Name is \(name)") // Name is Them
//
// MARK: 类
@@ -329,7 +339,7 @@ public class Shape {
internal class Rect: Shape {
// 值属性 (Stored properties)
var sideLength: Int = 1
-
+
// 计算属性 (Computed properties)
private var perimeter: Int {
get {
@@ -340,11 +350,11 @@ internal class Rect: Shape {
sideLength = newValue / 4
}
}
-
+
// 延时加载的属性,只有这个属性第一次被引用时才进行初始化,而不是定义时就初始化
// subShape 值为 nil ,直到 subShape 第一次被引用时才初始化为一个 Rect 实例
lazy var subShape = Rect(sideLength: 4)
-
+
// 监控属性值的变化。
// 当我们需要在属性值改变时做一些事情,可以使用 `willSet` 和 `didSet` 来设置监控函数
// `willSet`: 值改变之前被调用
@@ -352,14 +362,14 @@ internal class Rect: Shape {
var identifier: String = "defaultID" {
// `willSet` 的参数是即将设置的新值,参数名可以指定,如果没有指定,就是 `newValue`
willSet(someIdentifier) {
- println(someIdentifier)
+ print(someIdentifier)
}
// `didSet` 的参数是已经被覆盖掉的旧的值,参数名也可以指定,如果没有指定,就是 `oldValue`
didSet {
- println(oldValue)
+ print(oldValue)
}
}
-
+
// 命名构造函数 (designated inits),它必须初始化所有的成员变量,
// 然后调用父类的命名构造函数继续初始化父类的所有变量。
init(sideLength: Int) {
@@ -367,13 +377,13 @@ internal class Rect: Shape {
// 必须显式地在构造函数最后调用父类的构造函数 super.init
super.init()
}
-
+
func shrink() {
if sideLength > 0 {
--sideLength
}
}
-
+
// 函数重载使用 override 关键字
override func getArea() -> Int {
return sideLength * sideLength
@@ -394,16 +404,16 @@ class Square: Rect {
}
var mySquare = Square()
-println(mySquare.getArea()) // 25
+print(mySquare.getArea()) // 25
mySquare.shrink()
-println(mySquare.sideLength) // 4
+print(mySquare.sideLength) // 4
// 类型转换
let aShape = mySquare as Shape
// 使用三个等号来比较是不是同一个实例
if mySquare === aShape {
- println("Yep, it's mySquare")
+ print("Yep, it's mySquare")
}
class Circle: Shape {
@@ -411,12 +421,12 @@ class Circle: Shape {
override func getArea() -> Int {
return 3 * radius * radius
}
-
+
// optional 构造函数,可能会返回 nil
init?(radius: Int) {
self.radius = radius
super.init()
-
+
if radius <= 0 {
return nil
}
@@ -425,13 +435,13 @@ class Circle: Shape {
// 根据 Swift 类型推断,myCircle 是 Optional<Circle> 类型的变量
var myCircle = Circle(radius: 1)
-println(myCircle?.getArea()) // Optional(3)
-println(myCircle!.getArea()) // 3
+print(myCircle?.getArea()) // Optional(3)
+print(myCircle!.getArea()) // 3
var myEmptyCircle = Circle(radius: -1)
-println(myEmptyCircle?.getArea()) // "nil"
+print(myEmptyCircle?.getArea()) // "nil"
if let circle = myEmptyCircle {
// 此语句不会输出,因为 myEmptyCircle 变量值为 nil
- println("circle is not nil")
+ print("circle is not nil")
}
@@ -461,7 +471,7 @@ enum BookName: String {
case John = "John"
case Luke = "Luke"
}
-println("Name: \(BookName.John.rawValue)")
+print("Name: \(BookName.John.rawValue)")
// 与特定数据类型关联的枚举
enum Furniture {
@@ -469,7 +479,7 @@ enum Furniture {
case Desk(height: Int)
// 和 String, Int 关联的枚举记录
case Chair(brand: String, height: Int)
-
+
func description() -> String {
switch self {
case .Desk(let height):
@@ -481,9 +491,9 @@ enum Furniture {
}
var desk: Furniture = .Desk(height: 80)
-println(desk.description()) // "Desk with 80 cm"
+print(desk.description()) // "Desk with 80 cm"
var chair = Furniture.Chair(brand: "Foo", height: 40)
-println(chair.description()) // "Chair of Foo with 40 cm"
+print(chair.description()) // "Chair of Foo with 40 cm"
//
@@ -512,7 +522,7 @@ protocol ShapeGenerator {
class MyShape: Rect {
var delegate: TransformShape?
-
+
func grow() {
sideLength += 2
@@ -539,21 +549,21 @@ extension Square: Printable {
}
}
-println("Square: \(mySquare)") // Area: 16 - ID: defaultID
+print("Square: \(mySquare)") // Area: 16 - ID: defaultID
// 也可以给系统内置类型添加功能支持
extension Int {
var customProperty: String {
return "This is \(self)"
}
-
+
func multiplyBy(num: Int) -> Int {
return num * self
}
}
-println(7.customProperty) // "This is 7"
-println(14.multiplyBy(3)) // 42
+print(7.customProperty) // "This is 7"
+print(14.multiplyBy(3)) // 42
// 泛型: 和 Java 及 C# 的泛型类似,使用 `where` 关键字来限制类型。
// 如果只有一个类型限制,可以省略 `where` 关键字
@@ -566,7 +576,7 @@ func findIndex<T: Equatable>(array: [T], valueToFind: T) -> Int? {
return nil
}
let foundAtIndex = findIndex([1, 2, 3, 4], 3)
-println(foundAtIndex == 2) // true
+print(foundAtIndex == 2) // true
// 自定义运算符:
// 自定义运算符可以以下面的字符打头:
@@ -581,11 +591,24 @@ prefix func !!! (inout shape: Square) -> Square {
}
// 当前值
-println(mySquare.sideLength) // 4
+print(mySquare.sideLength) // 4
// 使用自定义的 !!! 运算符来把矩形边长放大三倍
!!!mySquare
-println(mySquare.sideLength) // 12
+print(mySquare.sideLength) // 12
-```
+// 运算符也可以是泛型
+infix operator <-> {}
+func <-><T: Equatable> (inout a: T, inout b: T) {
+ let c = a
+ a = b
+ b = c
+}
+var foo: Float = 10
+var bar: Float = 20
+
+foo <-> bar
+print("foo is \(foo), bar is \(bar)") // "foo is 20.0, bar is 10.0"
+
+```