Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

basics/slices.md #10

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 4 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,10 @@
English base language version of the DLang Tour
Chinese translation of the DLang Tour
==============================================

[![Build Status](https://travis-ci.org/dlang-tour/english.svg?branch=master)](https://travis-ci.org/dlang-tour/english)
[![Build Status](https://travis-ci.org/dlang-tour/chinese.svg?branch=master)](https://travis-ci.org/dlang-tour/chinese)

Found a typo or want to improve the content?
Just click on "edit" and send us a pull request.
If you want to discuss an idea for a change first,
don't hesitate to open an [issue](https://github.com/dlang-tour/english/issues).
Just click on "edit" and send us the pull request.

You might also be looking for the [base repository](https://github.com/dlang-tour/core)
You might also be looking for the [base repository](https://github.com/dlang-tour)
that hosts the content.

Run locally
-----------

You will need to fetch the [base repository](https://github.com/dlang-tour/core) via DUB once:

```sh
dub fetch dlang-tour
```

Now you can execute `dlang-tour` in the root directory of this repository:

```sh
dub run dlang-tour -- --lang-dir .
```
49 changes: 19 additions & 30 deletions basics/arrays.md
Original file line number Diff line number Diff line change
@@ -1,47 +1,36 @@
# Arrays

There are two types of Arrays in D: **static** and **dynamic**.
Access to arrays of any kind is bounds-checked (except when the compiler can prove
that bounds checks aren't necessary).
A failed bounds check yields a `RangeError` which aborts the application.
The brave can disable this safety feature with the
compiler flag `-boundschecks=off`
in order to gain speed improvements at the cost of safety.
D 语言有两种数组:**静态** 和 **动态** 的数组。
访问任何类型数组的元素都需要经过边界检查(除非编译器能够证明边界检查不是必须的)。
边界检查失败时会抛出一个 `RangeError` 来中断程序。
可以通过 `-boundschecks=off` 编译选项来禁用这类检查,以提升程序的效率。

#### Static arrays
#### 静态数组

Static arrays are stored on the stack if defined inside a function,
or in static memory otherwise. They have a fixed,
compile-time known length. A static array's type includes
the fixed size:
如果静态数组在函数内声明,那么它就会被分配在堆栈中,否则他会被分配到静态内存里。静态数组的类型包括在它的类型里,它具有着固定的、编译时已知的长度:

```d
int[8] arr;
```

`arr`'s type is `int[8]`. Note that the size of the array is denoted
next to the type, and not after the variable name like in C/C++.
`arr` 的类型为 `int[8]`。注意这里与 C/C++不同,数组的大小紧在元素类型的名称后,而非在变量名称后。

#### Dynamic arrays
#### 动态数组

Dynamic arrays are stored on the heap and can be expanded
or shrunk at runtime. A dynamic array is created using a `new` expression
and its length:
动态数组存储在堆上,它可以在运行时拓展或者缩小。通过 `new` 表达式能够创建一个给定大小的动态数组:

int size = 8; // run-time variable
```d
int size = 8; // 运行时变量
int[] arr = new int[size];
```

The type of `arr` is `int[]`, which is a **slice**. Slices
will be explained in more detail in the [next section](basics/slices). Multi-dimensional
arrays can be created easily using the `auto arr = new int[3][3]` syntax.

#### Array operations and properties
`arr` 的类型为 `int[]`,这是一个 **切片**。[下一节](basics/slices)将会对切片进行更详细的讲解。

Arrays can be concatenated using the `~` operator, which
will create a new dynamic array.
#### 数组的属性与操作

Mathematical operations can
be applied to whole arrays using a syntax like `c[] = a[] + b[]`, for example.
This adds all elements of `a` and `b` so that
`c[0] = a[0] + b[0]`, `c[1] = a[1] + b[1]`, etc. It is also possible
可以使用 `~` 操作符来连接两个数组,这将会创建一个新的动态数组。
可以像 `c[] = a[] + b[] 这样让算数运算应用在数组的所有元素上。
这样操作会It is also possible
to perform operations on a whole array with a single
value:

Expand Down
72 changes: 33 additions & 39 deletions basics/functions.md
Original file line number Diff line number Diff line change
@@ -1,67 +1,65 @@
# Functions
# 函数

One function has already been introduced: `main()` - the starting point of every
D program. A function may return a value (or be declared with
`void` if nothing is returned) and accept an arbitrary number of arguments:
我们已经介绍了过了一个函数函数:`main()`,它是每一个 D 程序的入口。
每个函数都可以返回一个值(如果函数不需要返回值,那么可以将它的返回值类型声明为 `void`)。

```d
int add(int lhs, int rhs) {
return lhs + rhs;
}
```

### `auto` return types
### `auto` 返回值类型

If the return type is defined as `auto`, the D compiler infers the return
type automatically. Hence multiple `return` statements must return values with
compatible types.
如果函数的返回值类型被定义为 `auto`,那么 D 编译器会自动推断函数的返回值类型。 因此,在 `auto` 返回值类型的函数里,如果包含了多条 `return` 语句,那么它们返回的值必须有着兼容的类型。

auto add(int lhs, int rhs) { // returns `int`
```d
auto add(int lhs, int rhs) { // 返回值类型为 int
return lhs + rhs;
}

auto lessOrEqual(int lhs, int rhs) { // returns `double`
auto lessOrEqual(int lhs, int rhs) { // 返回值类型为 `double`
if (lhs <= rhs)
return 0;
else
return 1.0;
}
```

### Default arguments
### 默认参数

Functions may optionally define default arguments.
This avoids the tedious work of declaring redundant
overloads.
函数支持可选的为参数提供默认值,这避免了冗长的重载。

```d
void plot(string msg, string color = "red") {
...
//...
}
plot("D rocks");
plot("D rocks", "blue");
```

Once a default argument has been specified, all following arguments
must be default arguments too.
如果指定了一个参数的默认值,那么他后面的所有参数都必须拥有默认值。

### Local functions
### 局部函数

Functions may even be declared inside other functions, where they may be
used locally and aren't visible to the outside world.
These functions can even have access to objects that are local to
the parent's scope:
函数甚至能够定义在其他函数内部,它们可以在局部被使用,并且对于外部是不可见的。这样的局部函数甚至能够访问局部变量:

```d
void fun() {
int local = 10;
int fun_secret() {
local++; // that's legal
local++; // 合法
}
...
// ...
```

Such nested functions are called delegates, and they will be explained in more depth
[soon](basics/delegates).
这样的嵌套函数被称为 *委托*,在[这里](basics/delegates)我们会有详细的讲解。

### In-depth

- [Functions in _Programming in D_](http://ddili.org/ders/d.en/functions.html)
- [Function parameters in _Programming in D_](http://ddili.org/ders/d.en/function_parameters.html)
- [Function specification](https://dlang.org/spec/function.html)
- [_D 程序设计中的_ 函数](http://ddili.org/ders/d.en/functions.html)
- [_D 程序设计中的_ 函数参数](http://ddili.org/ders/d.en/function_parameters.html)
- [D 函数规范](https://dlang.org/spec/function.html)

## {SourceCode}

Expand All @@ -71,8 +69,7 @@ import std.random : uniform;

void randomCalculator()
{
// Define 4 local functions for
// 4 different mathematical operations
// 为 4 个不同的数学运算定义了 4 个局部函数
auto add(int lhs, int rhs) {
return lhs + rhs;
}
Expand All @@ -89,10 +86,8 @@ void randomCalculator()
int a = 10;
int b = 5;

// uniform generates a number between START
// and END, whereas END is NOT inclusive.
// Depending on the result we call one of
// the math operations.
// uniform 生成了在一个半开半闭区间 [start, end) 内的随机数,
// 根据不同的结果采用不同的数学运算
switch (uniform(0, 4)) {
case 0:
writeln(add(a, b));
Expand All @@ -107,17 +102,16 @@ void randomCalculator()
writeln(div(a, b));
break;
default:
// special code which marks
// UNREACHABLE code
// 用来标记不可能执行到的代码的特殊标记
assert(0);
}
}

void main()
{
randomCalculator();
// add(), sub(), mul() and div()
// are NOT visible outside of their scope
// add(), sub(), mul() div()
// 在 randomCalculator() 之外不可访问
static assert(!__traits(compiles,
add(1, 2)));
}
Expand Down
2 changes: 1 addition & 1 deletion basics/index.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
title: D's Basics
title: D 语言基础
ordering:
- imports-and-modules
- basic-types
Expand Down
4 changes: 2 additions & 2 deletions basics/memory.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

D 是一门系统级编程语言,所以它允许手动内存管理。但是手动内存管理十分容易出错,所以默认情况下,D 采用 *垃圾回收器* 来管理内存。

C 一样,D 提供指针类型 `T*`:
D 与 C 一样,提供了指针类型 `T*`:

```d
int a;
Expand Down Expand Up @@ -34,7 +34,7 @@ D 有三种功能不同的安全等级: `@system`, `@trusted` 以及 `@safe`

`@trusted` 函数提供了对代码安全性手动验证的能力,这为 SafeD 与肮脏的低级世界间建立起了一座桥梁。

### 神UR
### 深入

* [SafeD](https://dlang.org/safed.html)

Expand Down
57 changes: 22 additions & 35 deletions basics/slices.md
Original file line number Diff line number Diff line change
@@ -1,67 +1,54 @@
# Slices

Slices are objects from type `T[]` for any given type `T`.
Slices provide a view on a subset of an array
of `T` values - or just point to the whole array.
**Slices and dynamic arrays are the same.**
给定类型了 `T`,切片是类型为 `T[]` 的对象。
切片提供了指向数组子集或者整个数组的方法.
**切片和动态数组是一样的.**

A slice consists of two members - a pointer to the starting element and the
length of the slice:
一个切片由指向开始节点的指针和切片长度两部分组成:

T* ptr;
size_t length; // unsigned 32 bit on 32bit, unsigned 64 bit on 64bit
size_t length; // 32位系统上长度为32,64位系统上长度为64

### Getting a slice via new allocation
### 从新分配的数组里获得切片

If a new dynamic array is created, a slice to this freshly
allocated memory is returned:
如果创建了一个动态数组,则返回这个新分配内存块的切片

auto arr = new int[5];
assert(arr.length == 5); // memory referenced in arr.ptr

Actual allocated memory in this case is completely managed by the garbage
collector. The returned slice acts as a "view" on underlying elements.
在这种情况下实际分配的内存完全由垃圾回收器管理. 返回的切片作为底层元素的“视图”。

### Getting a slice to existing memory
### 从已存在的内存块中获取分片

Using a slicing operator one can also get a slice pointing to some already
existing memory. The slicing operator can be applied to another slice, static
arrays, structs/classes implementing `opSlice` and a few other entities.
使用切片操作符也可以指向已经存在的内存块. 切片操作符可以应用于另一个切片,数组,实现了`opSlice`的结构/类和其他几个实体.

In an example expression `origin[start .. end]` the slicing operator is used to get
a slice of all elements of `origin` from `start` to the element _before_ `end`:
在表达式`origin[start .. end]`的示例中,切片运算符用于从`起始`到`结束`前的元素获取`origin`元素的切片:

auto newArr = arr[1 .. 4]; // index 4 is NOT included
auto newArr = arr[1 .. 4]; // 索引4不包括在切片中
assert(newArr.length == 3);
newArr[0] = 10; // changes newArr[0] aka arr[1]
newArr[0] = 10; // 修改newArr[0]

Such slices generate a new view on existing memory. They *don't* create
a new copy. If no slice holds a reference to that memory anymore - or a *sliced*
part of it - it will be freed by the garbage collector.
这样切片在现有的内存块上生成新的视图时 *不会* 创建新的副本.
如果没有切片保留对该内存的引用 它将被垃圾收集器释放.

Using slices, it's possible to write very efficient code for things (like parsers, for example)
that only operate on one memory block, and slice only the parts they really need
to work on. In this way, there's no need to allocate new memory blocks.
使用切片,可以为仅在一个内存块上操作的东西(例如解析器)编写非常高效的代码,并且只切割他们真正需要处理的部分,这样就不需要分配新的内存了.

As seen in the [previous section](basics/arrays), the `[$]` expression is a shorthand form for
`arr.length`. Hence `arr[$]` indexes the element one past the slice's end, and
thus would generate a `RangeError` (if bounds-checking hasn't been disabled).
像上一节[previous section](basics/arrays)说的, `[$]` 表达式是`arr.length`的缩写形式.
因此 `arr[$]` 将索引至切片结束 ,并会生成`RangeError`(如果bounds-checking未被禁用).

### In-depth
### 更深入的参考

- [Introduction to Slices in D](http://dlang.org/d-array-article.html)
- [Slices in _Programming in D_](http://ddili.org/ders/d.en/slices.html)

## {SourceCode}
## {代码示例}

```d
import std.stdio : writefln;

/**
Calculates the minimum of all values
in a slice recursively. For every recursive
call a sub-slice is taken thus we don't
create a copy and don't do any allocations.
使用分片,递归计算出所有值的最小值.对于每个递归
调用一个子切片,因此我们没有创建新的拷贝,不会有新的内存分配.
*/
int minimum(int[] slice)
{
Expand Down
2 changes: 1 addition & 1 deletion gems/index.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
title: D's Gems
title: D 语言的特性
ordering:
- uniform-function-call-syntax-ufcs
- scope-guards
Expand Down
2 changes: 1 addition & 1 deletion multithreading/index.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
title: Multithreading
title: 多线程
ordering:
- thread-local-storage
- message-passing
Expand Down
2 changes: 1 addition & 1 deletion welcome/index.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
title: Welcome
title: 欢迎
ordering:
- welcome-to-d
- languages
Expand Down
4 changes: 2 additions & 2 deletions welcome/welcome-to-d.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ D 语言是现代编译器的集大成者,它还拥有着下面这些特性:

### 关于本教程

本教程的每一部分都附带了一个源代码实力,可以通过修改这些例子来实验 D 的语言特性。单击 _run_ 按钮(或者使用 `Ctrl-enter` 快捷键)来编译运行它。
本教程的每一部分都附带了一个源代码实例,可以通过修改这些例子来实验 D 的语言特性。单击 _run_ 按钮(或者使用 `Ctrl-enter` 快捷键)来编译运行它。

### 协作

Expand All @@ -51,7 +51,7 @@ void main()
{
// 让我们开始吧!
writeln("Hello World!");

// 一个给有经验的程序员的例子:
// 在不进行动态内存分配的情况下,创建了三个数组,
// 并对他们进行排序。
Expand Down