From 11a47c5f5423582c6fa4dbb38550648d1a2aec95 Mon Sep 17 00:00:00 2001 From: luojiyin Date: Mon, 18 Apr 2022 11:52:49 +0800 Subject: [PATCH 01/15] chore: rename file --- ...o-to-hero-d2a3223b3d86.md => learning-go-from-zero-to-hero.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename chinese/articles/{learning-go-from-zero-to-hero-d2a3223b3d86.md => learning-go-from-zero-to-hero.md} (100%) diff --git a/chinese/articles/learning-go-from-zero-to-hero-d2a3223b3d86.md b/chinese/articles/learning-go-from-zero-to-hero.md similarity index 100% rename from chinese/articles/learning-go-from-zero-to-hero-d2a3223b3d86.md rename to chinese/articles/learning-go-from-zero-to-hero.md From 1e95c3d17a070598975394b0f7bea0e0d1a939e0 Mon Sep 17 00:00:00 2001 From: luojiyin Date: Mon, 18 Apr 2022 11:56:25 +0800 Subject: [PATCH 02/15] fix: markdown warning --- .../articles/learning-go-from-zero-to-hero.md | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/chinese/articles/learning-go-from-zero-to-hero.md b/chinese/articles/learning-go-from-zero-to-hero.md index 8a5779574..ad87d67cd 100644 --- a/chinese/articles/learning-go-from-zero-to-hero.md +++ b/chinese/articles/learning-go-from-zero-to-hero.md @@ -1,7 +1,7 @@ -> - 原文地址:[Learning Go — from zero to hero](https://www.freecodecamp.org/news/learning-go-from-zero-to-hero-d2a3223b3d86/) -> - 原文作者:[Milap Neupane](https://www.freecodecamp.org/news/author/milapneupane/) -> - 译者: -> - 校对者: +> - 原文地址:[Learning Go — from zero to hero](https://www.freecodecamp.org/news/learning-go-from-zero-to-hero-d2a3223b3d86/) +> - 原文作者:[Milap Neupane](https://www.freecodecamp.org/news/author/milapneupane/) +> - 译者:[luojiyin](https://github.com/luojiyin1987) +> - 校对者: ![Learning Go — from zero to hero](https://cdn-media-1.freecodecamp.org/images/1*30aoNxlSnaYrLhBT0O1lzw.png) @@ -48,7 +48,7 @@ cd ~/workspace Create the file `main.go` with the following code inside the workspace folder we just created. -#### Hello World! +#### Hello World ```go package main @@ -320,8 +320,8 @@ fmt.Println(*ap) Pointers are usually preferred while passing a struct as an argument or while declaring a method for a defined type. -1. While passing value the value is actually copied which means more memory -2. With the pointer passed, the value changed by the function is reflected back in the method/function caller. +1. While passing value the value is actually copied which means more memory +2. With the pointer passed, the value changed by the function is reflected back in the method/function caller. Example: @@ -907,19 +907,19 @@ As we see in above no more than 2 messages are accepted by a channel. > Simplicity… — Rob-pike -### Great! +### Great We learned some of the major components and features of Go. -1. Variables, Datatypes -2. Array slices and maps -3. Functions -4. Looping and conditional statements -5. Pointers -6. Packages -7. Method, Structs, and Interfaces -8. Error Handling -9. Concurrency — Go routines and channels +1. Variables, Datatypes +2. Array slices and maps +3. Functions +4. Looping and conditional statements +5. Pointers +6. Packages +7. Method, Structs, and Interfaces +8. Error Handling +9. Concurrency — Go routines and channels Congratulations, you now have a decent understanding of Go. @@ -931,4 +931,4 @@ Do not stop here. Keep moving forward. Think about a small application and start [LinkedIn](https://www.linkedin.com/in/milap-neupane-99a4b565/), [Github](http://github.com/milap-neupane), [Twitter](https://twitter.com/_milap) -Also Posted on Milap Neupane Blog: [Learning Go-from zero to hero](https://milapneupane.com.np/2019/07/06/learning-golang-from-zero-to-hero/) \ No newline at end of file +Also Posted on Milap Neupane Blog: [Learning Go-from zero to hero](https://milapneupane.com.np/2019/07/06/learning-golang-from-zero-to-hero/) From 4e743b0578b74c0900fbcf8b6121f9f4646afe36 Mon Sep 17 00:00:00 2001 From: luojiyin Date: Mon, 18 Apr 2022 12:28:46 +0800 Subject: [PATCH 03/15] save and backup --- .../articles/learning-go-from-zero-to-hero.md | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/chinese/articles/learning-go-from-zero-to-hero.md b/chinese/articles/learning-go-from-zero-to-hero.md index ad87d67cd..6dd48e845 100644 --- a/chinese/articles/learning-go-from-zero-to-hero.md +++ b/chinese/articles/learning-go-from-zero-to-hero.md @@ -5,48 +5,48 @@ ![Learning Go — from zero to hero](https://cdn-media-1.freecodecamp.org/images/1*30aoNxlSnaYrLhBT0O1lzw.png) -Let’s start with a small introduction to Go (or Golang). Go was designed by Google engineers Robert Griesemer, Rob Pike, and Ken Thompson. It is a statically typed, compiled language. The first version was released as open source in March 2012. +让我们先对 Go(或称 Golang )做一个小小的介绍。Go 是由谷歌工程师 Robert Griesemer、Rob Pike 和 Ken Thompson 设计的。它是一种静态类型的、编译的语言。第一个版本于2012年3月作为开源版本发布。 -> “Go is an open source programming language that makes it easy to build simple, reliable, and efficient software”. — GoLang +> "Go是一种开源的编程语言,它使人们能够轻松地构建简单、可靠和高效的软件"。- GoLang -In many languages, there are many ways to solve a given problem. Programmers can spend a lot of time thinking about the best way to solve it. +在许多编程语言中,有许多方法来解决一个特定的问题。程序员要花很多时间去思考解决它的最佳方法。 -Go, on the other hand, believes in fewer features — with only one right way to solve the problem. +Go 却相信用较少的功能--只有一种正确的方式来解决问题。 -This saves developers time and makes the large codebase easy to maintain. There are no “expressive” features like maps and filters in Go. +这为开发人员节省了时间,并使大型代码库易于维护。 Go中没有像 `maps` 和 `filters` 这样的 "表达性 "功能。 -> “When you have features that add expressiveness it typically adds expense” — Rob Pike +> "当你有增加表现力的功能时,通常会增加系统开销。"--Rob Pike ![1*AUiSG5Gqz8MzaGCvGpckGA](https://cdn-media-1.freecodecamp.org/images/1*AUiSG5Gqz8MzaGCvGpckGA.png) -Recently published new logo of go lang: [https://blog.golang.org/go-brand](https://blog.golang.org/go-brand) +最近发表的新的 golang 标志: [https://blog.golang.org/go-brand](https://blog.golang.org/go-brand) ### Getting Started -Go is made of packages. The package main tells the Go compiler that the program is compiled as an executable, rather than a shared library. It is the entry point for an application. The main package is defined as: +Go是由 packages(包) 组成的。package main 告诉Go编译器,该程序被编译为可执行文件,而不是共享库。它是一个应用程序的入口点。package main 的定义如下: ```go package main ``` -Let’s move ahead by writing a simple hello world example by creating a file `main.go` in the Go workspace. +让我们继续前进,在 Go workspace 创建一个 `main.go` 文件,编写一个简单的 hello world 例子。 #### **Workspace** -A workspace in Go is defined by the environment variable `GOPATH`. +Go中的 workspace 是由环境变量 `GOPATH` 定义的。 -Any code you write is to be written inside the workspace. Go will search for any packages inside the `GOPATH` directory, or the `GOROOT` directory, which is set by default when installing Go. `GOROOT` is the path where the go is installed. +你写的任何代码都要写在 workspace 里面。Go将搜索 `GOPATH` 目录内的任何软件包,或者 `GOROOT` 目录,该目录在安装 Go时 默认设置。`GOROOT` 是安装 Go 的路径。 -Set `GOPATH` to your desired directory. For now, let’s add it inside a folder `~/workspace`. +设置 `GOPATH` 到你想要的目录。现在,让我们把它添加到 `~/workspace` 文件夹内。 -``` +```shell # export env export GOPATH=~/workspace # go inside the workspace directory cd ~/workspace ``` -Create the file `main.go` with the following code inside the workspace folder we just created. +在我们刚刚创建的 workspace 文件夹中创建 `main.go` 文件,其中包含以下代码。 #### Hello World @@ -62,26 +62,26 @@ func main(){ } ``` -In the above example, `fmt` is a built-in package in Go which implements functions for formatting I/O. +在上面的例子中,`fmt`是Go中的一个内置包,它实现了用于格式化 I/O 输出的函数。 -We import a package in Go by using the `import` keyword. `func main` is the main entry point where the code gets executed. `Println` is a function inside the package `fmt` which prints “hello world” for us. +我们通过使用 `import` 关键字在Go中导入一个包。`func main` 是代码被执行的主入口点。`Println` 是包 `fmt` 中的一个函数,它为我们打印出 "hello world"。 -Let’s see by running this file. There are two ways we can run a Go command. As we know, Go is a compiled language, so we first need to compile it before executing. +让我们通过运行这个文件来看看。我们有两种方法可以运行Go命令。正如我们所知,Go是一种编译语言,所以我们首先需要在执行之前编译它。 -``` +```shell > go build main.go ``` -This creates a binary executable file `main` which now we can run: +这将创建一个二进制可执行文件`main`,现在我们可以运行: -``` +```shell > ./main # Hello World! ``` -There is another, simpler, way to run the program. The `go run` command helps abstract the compilation step. You can simply run the following command to execute the program. +还有一种更简单的方法来运行程序。`go run` 命令会编译源代码,并直接执行源码中的 main() 函数,不会在当前目录留下可执行文件。你可以简单地运行以下命令来执行该程序。 -``` +```shell go run main.go # Hello World! ``` From 8fbffc56461e035745a5e922e4b6064457569b78 Mon Sep 17 00:00:00 2001 From: luojiyin Date: Mon, 18 Apr 2022 17:08:07 +0800 Subject: [PATCH 04/15] save and backup --- .../articles/learning-go-from-zero-to-hero.md | 108 +++++++++--------- 1 file changed, 56 insertions(+), 52 deletions(-) diff --git a/chinese/articles/learning-go-from-zero-to-hero.md b/chinese/articles/learning-go-from-zero-to-hero.md index 6dd48e845..5f81804af 100644 --- a/chinese/articles/learning-go-from-zero-to-hero.md +++ b/chinese/articles/learning-go-from-zero-to-hero.md @@ -86,29 +86,29 @@ go run main.go # Hello World! ``` -**_Note_**_: To try out the code that is mentioned in this blog you can use [https://play.golang.org](https://play.golang.org/)_ +**_注意_** : _要尝试本博客中提到的代码,你可以使用 [https://play.golang.org](https://play.golang.org/)_ ### Variables -Variables in Go are declared explicitly. Go is a statically typed language. This means that the variable type is checked at the time of variable declaration. A variable can be declared as: +Go 中的变量是明确声明的。Go 是一种静态类型的语言。这意味着在声明变量的时候会检查变量的类型。一个变量可以被声明: ```go var a int ``` -In this case, the value will be set as 0. Use the following syntax to declare and initialize a variable with a different value: +在这种情况下,值将被设置为0。 使用下面的语法来声明和初始化一个具有不同值的变量: ```go var a = 1 ``` -Here the variable is automatically assigned as an int. We can use a shorthand definition for the variable declaration as: +这里的变量被自动分配为int。 我们可以对变量的声明使用一个简短定义,即: ```go message := "hello world" ``` -We can also declare multiple variables in the same line: +我们也可以在同一行中声明多个变量: ```go var b, c int = 2, 3 @@ -116,18 +116,18 @@ var b, c int = 2, 3 ### Data types -Like any other programming language, Go supports various different data structures. Let’s explore some of them: +像其他编程语言一样,Go支持各种不同的数据结构。让我们来探索其中: #### **Number, String, and Boolean** -Some of the supported number store types are int, int8, int16, int32, int64, -uint, uint8, uint16, uint32, uint64, uintptr… +支持的整型包括 int, int8, int16, int32, int64, +uint, uint8, uint16, uint32, uint64, uintptr(无符号整型,长度跟平台相关,它的长度可以用来保存一个指针地址) 等 -The string type stores a sequence of bytes. It is represented and declared with keyword `string`. +字符串类型存储一个字节序列。它用关键字 `string` 来表示和声明。 -A boolean value is stored using the keyword `bool`. +布尔值使用关键字 `bool` 来存储。 -Go also supports complex number type data types, which can be declared with `complex64` and `complex128`. +Go 也支持复数类型,可以用 `complex64` 和 `complex128` 来声明。 ```go var a bool = true @@ -139,47 +139,49 @@ var x complex128 = cmplx.Sqrt(-5 + 12i) #### **Arrays, Slices, and Maps** -An array is a sequence of elements of the same data type. Arrays have a fixed length defined at declaration, so it cannot be expanded more than that. An array is declared as: +数组是由相同数据类型的元素组成的一个序列。数组在声明时有一个固定的长度,所以它不能被扩大到超过这个长度。一个数组声明: ```go var a [5]int ``` -Arrays can also be multidimensional. We can simply create them with the following format: +数组也可以是多维的。我们可以简单地用以下方式创建它们: ```go var multiD [2][3]int ``` -Arrays are limiting for cases when the values of array changes in runtime. Arrays also do not provide the ability to get a subarray. For this, Go has a data type called slices. +数组会限制数组的值发生变化,当代码运行时。数组也没有提供获取子数组的能力。 为此,Go有一种数据类型,叫做切片(slices)。 -Slices store a sequence of elements and can be expanded at any time. Slice declaration is similar to array declaration — without the capacity defined: +切片存储了一连串的元素,并且可以在任何时候扩展。切片声明与数组声明类似--但没有定义容量: ```go var b []int ``` -This creates a slice with zero capacity and zero length. Slices can also be defined with capacity and length. We can use the following syntax for it: +这将创建一个容量为 0、长度为 0 的切片。 + +也可以用容量和长度来定义切片。我们可以用下面的语法来定义它: ```go numbers := make([]int,5,10) ``` -Here, the slice has an initial length of 5 and has a capacity of 10. +这里,切片的初始长度为5,容量为10。 -Slices are an abstraction to an array. Slices use an array as an underlying structure. A slice contains three components: capacity, length, and a pointer to the underlying array as shown in the diagram below: +分片是对数组的一种抽象。切片使用一个数组作为底层结构。一个片断包含三个部分:容量、长度和一个指向底层数组的指针,如下图所示: ![1*P0lNCO0sQwIYHLEX_mfSOQ](https://cdn-media-1.freecodecamp.org/images/1*P0lNCO0sQwIYHLEX_mfSOQ.png) -image src: [https://blog.golang.org/go-slices-usage-and-internals](https://blog.golang.org/go-slices-usage-and-internals) +图片源自: [https://blog.golang.org/go-slices-usage-and-internals](https://blog.golang.org/go-slices-usage-and-internals) -The capacity of a slice can be increased by using the append or a copy function. An append function adds value to the end of the array and also increases the capacity if needed. +一个切片的容量可以通过使用 append 或 copy 函数来增加。append 函数将值添加到数组的末端,如果需要的话也可以增加容量。 ```go numbers = append(numbers, 1, 2, 3, 4) ``` -Another way to increase the capacity of a slice is to use the copy function. Simply create another slice with a larger capacity and copy the original slice to the newly created slice: +另一种增加切片容量的方法是使用 copy 函数。简单地创建另一个容量更大的片断,并将原来的切片复制到新创建的切片上: ```go // create a new slice @@ -188,7 +190,7 @@ number2 := make([]int, 15) copy(number2, number) ``` -We can create a sub-slice of a slice. This can be done simply using the following command: +我们可以创建一个切片的子切片。这可以通过以下命令简单地完成: ```go // initialize a slice with 4 len and values @@ -203,13 +205,13 @@ slice3 := number2[1:4] fmt.Println(slice3) // -> [2 3 4] ``` -Maps are a data type in Go, which maps keys to values. We can define a map using the following command: +Maps 是 Go中的一种数据类型,它将键映射到值。我们可以使用以下命令来定义一个 map: ```go var m map[string]int ``` -Here `m` is the new map variable, which has its keys as `string` and values are `integers`. We can add keys and values easily to a map: +`m` 是新的 map 变量, 它的键是 `string` 类型, 值是 `integers` 类型。我们很容易在 map 上添加键值对: ```go // adding key/value @@ -222,7 +224,7 @@ fmt.Println(m['simplicity']) // -> 3 ### **Typecasting** -One type of data type can be converted into another using type casting. Let’s see a simple type conversion: +一种类型的数据类型可以通过类型转换转换为另一种类型。让我们看看一个简单的类型转换: ```go a := 1.1 @@ -231,13 +233,13 @@ fmt.Println(b) //-> 1 ``` -Not all types of data type can be converted to another type. Make sure that the data type is compatible with the conversion. +不是所有类型的数据类型都可以转换为另一种类型。请确保数据类型与转换的内容相匹配。 ### Conditional Statements #### if else -For conditional statements, we can use if-else statements as shown in the example below. Make sure that the curly braces are in the same line as the condition is. +对于条件性语句,我们可以使用 if-else 语句,如下例所示。请确保大括号与条件语句在同一行。 ```go if num := 9; num < 0 { @@ -251,7 +253,7 @@ if num := 9; num < 0 { #### switch case -Switch cases helps organize multiple condition statements. The following example shows a simple switch case statement: +Switch cases 有助于组织多个条件语句。下面的例子显示了一个简单的 siwtch 语句: ```go i := 2 @@ -267,7 +269,7 @@ default: ### Looping -Go has a single keyword for the loop. A sngle for loop command help achieve different kinds of loops: +Go 有一个循环的关键词 `for`。for循环命令用于实现不同种类的循环: ```go i := 0 @@ -279,7 +281,9 @@ for i < 10 { fmt.Println(sum) ``` -The above example is similar to a while loop in C. The same for statement can be used for a normal for loop: +上面的例子类似于C语言中的while循环。 + +Go 中的 for 语句也可以用于普通的for循环: ```go sum := 0 @@ -289,7 +293,7 @@ for i := 0; i < 10; i++ { fmt.Println(sum) ``` -Infinite loop in Go: +Go 中的死循环: ```go for { @@ -298,32 +302,32 @@ for { ### Pointers -Go provides pointers. Pointers are the place to hold the address of a value. A pointer is defined by \*. A pointer is defined according to the type of data. Example: +Go提供了指针。指针是用来保存一个值的地址的地方。指针是由 \* 定义的。指针是根据数据的类型来定义的。 例如: ```go var ap *int ``` -Here `ap` is the pointer to an integer type. The `&` operator can be used to get the address of a variable. +`ap` 是指向一个整数类型的指针。 `&` 操作符可以用来获取一个变量的地址。 ```go a := 12 ap = &a ``` -The value pointed by the pointer can be accessed using the `*` operator: +指针所指向的值可以使用 `*` 操作符来访问: ```go fmt.Println(*ap) // => 12 ``` -Pointers are usually preferred while passing a struct as an argument or while declaring a method for a defined type. +在传递结构体作为参数时,或者在为定义的类型声明方法时,通常倾向于使用指针。 -1. While passing value the value is actually copied which means more memory -2. With the pointer passed, the value changed by the function is reflected back in the method/function caller. +1. 传递值时,实际上是在复制值,这意味着更多的内存。 +2. 通过指针,函数改变的值会反映在 方法/函数 调用者身上 -Example: +例如: ```go func increment(i *int) { @@ -337,11 +341,11 @@ func main() { //=> 11 ``` -Note: While you are trying out the example code in the blog, do not forget to include it with package main and import fmt or other packages when needed as shown in the first main.go example above. +注意:当你在尝试博客中的示例代码时,不要忘记用 `package main` 包含它,并在需要时导入 fmt 或其他包,如上面第一个 main.go 例子中所示。 ### Functions -The main function defined in the main package is the entry point for a go program to execute. More functions can be defined and used. Let’s look into a simple example: +在 main package 中定义的 main 函数是 go 程序执行的入口。更多的函数可以被定义和使用。让我们来看看一个简单的例子。: ```go func add(a int, b int) int { @@ -354,9 +358,9 @@ func main() { //=> 3 ``` -As we can see in the above example, a Go function is defined using the **func** keyword followed by the function name. The **arguments** a function takes needs to be defined according to its data type, and finally the data type of the return. +在上面的例子中我们可以看到,Go 函数是用 **func** 关键字来定义的,后面是函数名称。一个函数的 **参数** 需要根据其数据类型来定义,最后是返回的数据类型。 -The return of a function can be predefined in function as well: +一个函数的返回值也可以在函数中预先定义: ```go func add(a int, b int) (c int) { @@ -369,9 +373,9 @@ func main() { //=> 3 ``` -Here c is defined as the return variable. So the variable c defined would be automatically returned without needing to be defined at the return statement at the end. +这里c被定义为返回变量。所以定义的变量c会自动返回,而不需要在最后的返回语句中定义。 -You can also return multiple return values from a single function separating return values with a comma. +你也可以从一个函数中返回多个返回值,用逗号来分隔返回值。 ```go func add(a int, b int) (int, string) { @@ -387,11 +391,11 @@ func main() { ### Method, Structs, and Interfaces -Go is not a completely object-oriented language, but with structs, interfaces, and methods it has a lot of object-oriented support and feel. +Go并不是一种完全面向对象的语言,但通过结构体(Struct)、接口(Interface)和方法(Method),它有很多面向对象的支持和感觉。 #### Struct -A struct is a typed, collection of different fields. A struct is used to group data together. For example, if we want to group data of a Person type, we define a person’s attribute which could include name, age, gender. A struct can be defined using the following syntax: +结构体是一种类型化的、不同字段的集合。结构体用于将数据分组。例如,如果我们想对 Person 类型的数据进行分组,我们可以定义一个人的属性,其中可能包括姓名、年龄、性别。可以使用以下语法来定义一个结构体: ```go type person struct { @@ -401,7 +405,7 @@ type person struct { } ``` -With a person type struct defined, now let’s create a person: +在定义了一个人的类型结构后,现在让我们来创建一个 person: ```go //way 1: specifying attribute and value @@ -410,7 +414,7 @@ p = person{name: "Bob", age: 42, gender: "Male"} person{"Bob", 42, "Male"} ``` -We can easily access these data with a dot(.) +我们可以很容易地用一个点(.)来访问这些数据。 ```go p.name @@ -421,7 +425,7 @@ p.gender //=> Male ``` -You can also access attributes of a struct directly with its pointer: +你也可以用结构的指针直接访问其属性: ```go pp = &person{name: "Bob", age: 42, gender: "Male"} @@ -431,7 +435,7 @@ pp.name #### Methods -Methods are a special type of function with a _receiver._ A receiver can be both a value or a pointer. Let’s create a method called describe which has a receiver type person we created in the above example: +方法(Method)是一种特殊的函数类型,它有一个 _receiver_ 。 _receiver_ 可以是一个值或一个指针。让我们创建一个名为 describe 的方法(Method),它有一个我们在上面的例子中创建的接收器类型的 person: ```go package main @@ -469,9 +473,9 @@ func main() { } ``` -As we can see in the above example, the method now can be called using a dot operator as `pp.describe`. Note that the receiver is a pointer. With the pointer we are passing a reference to the value, so if we make any changes in the method it will be reflected in the receiver pp. It also does not create a new copy of the object, which saves memory. +正如我们在上面的例子中看到的,现在可以使用点运算符来调用该方法,如 `pp.describe`。请注意,_receiver_ 是一个指针。使用指针,我们传递的是一个值的引用,所以如果我们在方法中做任何改变,都会反映在 _receiver_ pp中。它也不会创建一个新的对象的副本,这就节省了内存。 -Note that in the above example the value of age is changed, whereas the value of name is not changed because the method setName is of the receiver type whereas setAge is of type pointer. +请注意,在上面的例子中,年龄的值被改变了,而名字的值没有改变,因为setName方法是 _receiver_ 类型的 ,而 setAge 是指针类型的。 #### Interfaces From eeda6b20442f7660be5b24285fd423c4fa93a781 Mon Sep 17 00:00:00 2001 From: luojiyin Date: Tue, 19 Apr 2022 11:21:07 +0800 Subject: [PATCH 05/15] save and backup --- .../articles/learning-go-from-zero-to-hero.md | 122 +++++++++--------- 1 file changed, 61 insertions(+), 61 deletions(-) diff --git a/chinese/articles/learning-go-from-zero-to-hero.md b/chinese/articles/learning-go-from-zero-to-hero.md index 5f81804af..b68bd2d56 100644 --- a/chinese/articles/learning-go-from-zero-to-hero.md +++ b/chinese/articles/learning-go-from-zero-to-hero.md @@ -479,7 +479,7 @@ func main() { #### Interfaces -Go interfaces are a collection of methods. Interfaces help group together the properties of a type. Let’s take the example of an interface animal: +Go 接口(interfaces)是一个方法(methods)的集合。接口有助于将一个类型的属性组合在一起。让我们以一个接口 animal 为例: ```go type animal interface { @@ -487,7 +487,7 @@ type animal interface { } ``` -Here animal is an interface type. Now let’s create 2 different type of animals which implement the animal interface type: +animal 是一个接口(interface)类型。现在让我们创建两个不同类型的 animal,它们都实现了 animal 接口类型: ```go package main @@ -530,43 +530,43 @@ func main() { //=> Sound: Meow!!! ``` -In the main function, we create a variable `a` of type animal. We assign a snake and a cat type to the animal and use Println to print a.description. Since we have implemented the method describe in both of the types (cat and snake) in a different way we get the description of the animal printed. +type cat struct { +在主函数中,我们创建一个动物类型的变量 `a`。我们给动物分配一个 snake 和一个 cat 的类型,并使用 Println 来打印 a.description。由于我们在两种类型(cat 和snake)中都以不同的方式实现了 describe 方法,我们得到了打印的动物描述。 ### Packages -We write all code in Go in a package. The **main** package is the entry point for the program execution. There are lots of built-in packages in Go. The most famous one we have been using is the **fmt** package. - -> “Go packages in the main mechanism for programming in the large that go provides and they make possible to divvy up a large project into smaller pieces.” +我们把Go的所有代码都写在一个包里。**main** package 是程序执行的入口点。Go中有很多内置包。我们一直在使用的最著名的是**fmt**包。 +> "Go软件包是Go提供的大型编程的主要机制,它们使得将一个大型项目分割成小块成为可能。" > — Robert Griesemer #### Installing a package -``` +```shell go get // example go get github.com/satori/go.uuid ``` -The packages we installed are saved inside the GOPATH env which is our work directory. You can see the packages by going inside the pkg folder inside our work directory `cd $GOPATH/pkg`. +我们安装的软件包被保存在 GOPATH 环境变量设置的工作目录。你可以通过进入我们工作目录下的pkg文件夹 `cd $GOPATH/pkg` 来查看这些软件包。 #### Creating a custom package -Let’s start by creating a folder custom\_package: +让我们先创建一个文件夹 custom_package: -``` +```shell > mkdir custom_package > cd custom_package ``` -To create a custom package we need to first create a folder with the package name we need. Let’s say we are building a package `person`. For that let’s create a folder named `person` inside `custom_package` folder: +要创建一个自定义包,我们需要首先创建一个文件夹,并加上我们需要的包名。比方说,我们要建立一个 `person` 包。为此,让我们在 `custom_package` 文件夹中创建一个名为 `person` 的文件夹。: -``` +```shell > mkdir person > cd person ``` -Now let’s create a file person.go inside this folder. +现在让我们在这个文件夹中创建一个文件person.go。 ```go package person @@ -578,13 +578,13 @@ func secretName(name string) string { } ``` -We now need to install the package so that it can be imported and used. So let’s install it: +我们现在需要安装这个包,以便它可以被导入和使用。因此,让我们来安装它: -``` +```shell > go install ``` -Now let’s go back to the custom\_package folder and create a main.go file +现在让我们回到custom_package文件夹,创建一个main.go文件 ```go package main @@ -599,35 +599,35 @@ func main(){ // => The person name is: Milap ``` -Here we can now import the package `person` we created and use the function Description. Note that the function `secretName` we created in the package will not be accessible. In Go, the method name starting without a capital letter will be private. +在这里,我们现在可以导入我们创建的包 `person` 并使用函数 Description。注意,我们在包中创建的函数 `secretName` 将不能被访问。在 Go 中,没有大写字母开头的方法名称将是私有的。 #### **Packages Documentation** -Go has built-in support for documentation for packages. Run the following command to generate documentation: +Go内置了对包的文档支持。运行以下命令来生成文档: -``` +```shell godoc person Description ``` -This will generate documentation for the Description function inside our package person. To see the documentation run a web server using the following command: +这将为我们的包 person 里面的描述函数生成文档。要看到这些文档,请使用以下命令运行一个网络服务器: -``` +```shell godoc -http=":8080" ``` -Now go to the URL [http://localhost:8080/pkg/](http://localhost:6060/pkg/) and see the documentation of the package we just created. +现在去URL [http://localhost:8080/pkg/](http://localhost:6060/pkg/),看看我们刚刚创建的包的文档。 #### Some built-in packages in Go **fmt** -The package implements formatted I/O functions. We have already used the package for printing out to stdout. +该包实现了格式化的 I/O 函数。我们已经用这个包实现了向 stdout 打印的功能。 **json** -Another useful package in Go is the json package. This helps to encode/decode the JSON. Let’s take an example to encode/decode some json: +Go中另一个有用的包是json包。这有助于对JSON进行编码/解码。让我们举个例子,对一些JSON进行编码/解码: -Encode +编码 ```go package main @@ -644,7 +644,7 @@ func main(){ } ``` -Decode +解码 ```go package main @@ -668,17 +668,17 @@ func main(){ //=> 1 ``` -While decoding the json byte using unmarshal, the first argument is the json byte and the second argument is the address of the response type struct where we want the json to be mapped to. Note that the `json:”page”` maps page key to PageNumber key in the struct. +当使用 unmarshal 解码 json 字节时,第一个参数是 json 字节,第二个参数是我们希望 json 被映射到的响应类型结构的地址。注意,`json: "page"`将页面键映射到结构中的 PageNumber 键。 ### Error Handling -Errors are the undesired and unexpected result of a program. Let’s say we are making an API call to an external service. This API call may be successful or could fail. An error in a Go program can be recognized when an error type is present. Let’s see the example: +错误是指程序中不想要的和意外的结果。比方说,我们正在对一个外部服务进行 API 调用。这个 API 调用可能是成功的,也可能是失败的。当错误类型出现时,Go 程序中的错误可以被识别。让我们看看这个例子: ```go resp, err := http.Get("http://example.com/") ``` -Here the API call to the error object may pass or could fail. We can check if the error is nil or present and handle the response accordingly: +在这里,对错误对象的 API 调用可能通过也可能失败。我们可以检查错误是否为零或存在,并相应地处理响应: ```go package main @@ -700,7 +700,7 @@ func main(){ #### Returning custom error from a function -When we are writing a function of our own, there are cases when we have errors. These errors can be returned with the help of the error object: +当我们在编写自己的函数时,有些情况下会出现错误。这些错误可以在错误对象的帮助下返回: ```go func Increment(n int) (int, error) { @@ -721,11 +721,11 @@ func main() { } ``` -Most of the packages that are built in Go, or external packages we use, have a mechanism for error handling. So any function we call could have possible errors. These errors should never be ignored and always handled gracefully in the place we call these functions, as we have done in the above example. +大多数 Go 中内置的包,或者我们使用的外部包,都有一个错误处理的机制。所以我们调用的任何函数都有可能出现错误。这些错误绝不应该被忽视,总是在我们调用这些函数的地方优雅地处理,正如我们在上面的例子中所做的那样。 #### Panic -Panic is something that is unhandled and is suddenly encountered during a program execution. In Go, panic is not the ideal way to handle exceptions in a program. It is recommended to use an error object instead. When a panic occurs, the program execution get’s halted. The thing that gets executed after a panic is the defer. +Panic 是指在程序执行过程中突然遇到的未被处理的东西。在Go中,Panic 不是处理程序中异常的理想方式。建议使用一个错误对象来代替。当 Panic 发生时,程序的执行会被停止。Panic 发生后被执行的东西是 defer。 ```go //Go @@ -762,17 +762,17 @@ func g(i int) { #### Defer -Defer is something that will always get executed at the end of a function. +Defer 是指总是在函数的末尾被执行的东西。 -In the above example, we panic the execution of the program using panic(). As you notice, there is a defer statement which will make the program execute the line at the end of the execution of the program. Defer can also be used when we need something to be executed at the end of the function, for example closing a file. +在上面的例子中,我们用 panic() 使程序的执行陷入 panic。正如你所注意到的,这里有一个 defer 语句,它将使程序在最后执行这一行。当我们需要在函数结束时执行一些东西时也可以使用 defer,例如关闭一个文件。 ### Concurrency -Go is built with concurrency in mind. Concurrency in Go can be achieved by Go routines which are lightweight threads. +Go 是在考虑到并发性的情况下建立的。Go 中的并发性可以通过 Go 协程实现,它是轻量级的线程。 **Go routine** -Go routines are the function which can run in parallel or concurrently with another function. Creating a Go routine is very simple. Simply by adding a keyword Go in front of a function, we can make it execute in parallel. Go routines are very lightweight, so we can create thousands of them. Let’s look into a simple example: +Go 协程是可以与另一个函数并行或同时运行的函数。创建一个 Go 协程非常简单。只需在一个函数前面加上关键字 Go,我们就可以让它并行执行。Go 协程是非常轻量级的,所以我们可以创建成千上万的协程。让我们来看看一个简单的例子: ```go package main @@ -793,17 +793,17 @@ func c() { //=> I am concurrent ``` -As you can see in the above example, the function c is a Go routine which executes in parallel with the main Go thread. There are times we want to share resources between multiple threads. Go prefers not sharing the variables of one thread with another because this adds a chance of deadlock and resource waiting. There is another way to share resources between Go routines: via go channels. +正如你在上面的例子中所看到的,函数 c 是一个 Go 例程,与 Go 主线程并行执行。有些时候,我们希望在多个线程之间共享资源。Go 倾向于不将一个线程的变量与另一个线程共享,因为这样会增加死锁和资源等待的可能性。还有一种方法可以在 Go 协程之间共享资源:通过Go channels。 **Channels** -We can pass data between two Go routines using channels. While creating a channel it is necessary to specify what kind of data the channel receives. Let’s create a simple channel with string type as follows: +我们可以使用通道在两个 Go 协程之间传递数据。在创建 channel 时,有必要指定该 channel 接收什么样的数据。让我们创建一个简单的字符串类型的 channel,如下所示: ```go c := make(chan string) ``` -With this channel, we can send string type data. We can both send and receive data in this channel: +通过这个 channel,我们可以发送字符串类型的数据。我们可以在这个 channel 中发送和接收数据: ```go package main @@ -819,11 +819,11 @@ func main(){ //=>"hello" ``` -The receiver Channels wait until the sender sends data to the channel. +接收方 channel 等待,直到发送方发送数据到 channel。 **One way channel** -There are cases where we want a Go routine to receive data via the channel but not send data, and also vice versa. For this, we can also create a **one-way channel**. Let’s look into a simple example: +有些情况下,我们希望 Go 程序通过 channel 接收数据,但不发送数据,反之亦然。为此,我们也可以创建一个**单向 channel**。让我们来看看一个简单的例子: ```go package main @@ -848,7 +848,7 @@ In the above example, `sc` is a Go routine which can only send messages to the c ### Organizing multiple channels for a Go routine using select -There may be multiple channels that a function is waiting on. For this, we can use a select statement. Let us take a look at an example for more clarity: +一个函数可能有多个 channel 在等待。为此,我们可以使用一个选择(seleect)语句。让我们看一个例子,以了解更清楚的情况: ```go package main @@ -883,11 +883,11 @@ func speed2(ch chan string) { } ``` -In the above example, the main is waiting on two channels, c1 and c2. With select case statement the main function prints, the message sends from the channel whichever it receives first. +在上面的例子中,main正在等待两个 channel,c1和c2。通过 select case 语句,main函数打印出,信息从它先收到的 channel 中发送出来。 **Buffered channel** -You can create a buffered channel in go. With a buffered channel, the messages send to the channel will be blocked if the buffer is full. Let’s take a look at the example: +你可以在go中创建一个缓冲 channel。有了缓冲 channel,如果缓冲区满了,发送到该 channel 的消息就会被阻断。让我们看一下这个例子: ```go package main @@ -902,37 +902,37 @@ func main(){ fmt.Println(<-ch) } -# => fatal error: all goroutines are asleep - deadlock! +// => fatal error: all goroutines are asleep - deadlock! ``` -As we see in above no more than 2 messages are accepted by a channel. +正如我们在上面看到的,一个 channel 接受的信息不超过2条。 #### Why is Golang Successful? -> Simplicity… — Rob-pike +> 简洁性… — Rob-pike ### Great -We learned some of the major components and features of Go. +我们学习了Go的一些主要组成部分和特点。 -1. Variables, Datatypes -2. Array slices and maps -3. Functions -4. Looping and conditional statements -5. Pointers -6. Packages -7. Method, Structs, and Interfaces -8. Error Handling -9. Concurrency — Go routines and channels +1. 变量、数据类型 +2. 数组 切片 和 maps +3. 函数 +4. 循环和条件语句 +5. 指针 +6. 软件包 +7. 方法、结构体和接口 +8. 错误处理 +9. 并发 - Go 协程和通道 -Congratulations, you now have a decent understanding of Go. +恭喜你,你现在对 Go 有了相当的了解。 -> One of my most productive days was throwing away 1,000 lines of code. +> 我最有成效的一天是减少了1000行代码。 > — Ken Thompson -Do not stop here. Keep moving forward. Think about a small application and start building. +不要停在这里。继续向前推进。思考一个小的应用并开始创建。 [LinkedIn](https://www.linkedin.com/in/milap-neupane-99a4b565/), [Github](http://github.com/milap-neupane), [Twitter](https://twitter.com/_milap) -Also Posted on Milap Neupane Blog: [Learning Go-from zero to hero](https://milapneupane.com.np/2019/07/06/learning-golang-from-zero-to-hero/) +也发布在Milap Neupane博客: [学习Go,从0到1](https://milapneupane.com.np/2019/07/06/learning-golang-from-zero-to-hero/) From 549fbe28557174fde711be3cafa3ffd678c1657f Mon Sep 17 00:00:00 2001 From: luojiyin Date: Tue, 19 Apr 2022 11:37:20 +0800 Subject: [PATCH 06/15] translate finish --- .../articles/learning-go-from-zero-to-hero.md | 59 +++++++++---------- 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/chinese/articles/learning-go-from-zero-to-hero.md b/chinese/articles/learning-go-from-zero-to-hero.md index b68bd2d56..e21c3563c 100644 --- a/chinese/articles/learning-go-from-zero-to-hero.md +++ b/chinese/articles/learning-go-from-zero-to-hero.md @@ -21,7 +21,7 @@ Go 却相信用较少的功能--只有一种正确的方式来解决问题。 最近发表的新的 golang 标志: [https://blog.golang.org/go-brand](https://blog.golang.org/go-brand) -### Getting Started +### 入门 Go是由 packages(包) 组成的。package main 告诉Go编译器,该程序被编译为可执行文件,而不是共享库。它是一个应用程序的入口点。package main 的定义如下: @@ -88,7 +88,7 @@ go run main.go **_注意_** : _要尝试本博客中提到的代码,你可以使用 [https://play.golang.org](https://play.golang.org/)_ -### Variables +### Variables(变量) Go 中的变量是明确声明的。Go 是一种静态类型的语言。这意味着在声明变量的时候会检查变量的类型。一个变量可以被声明: @@ -114,11 +114,11 @@ message := "hello world" var b, c int = 2, 3 ``` -### Data types +### Data types(数据类型) 像其他编程语言一样,Go支持各种不同的数据结构。让我们来探索其中: -#### **Number, String, and Boolean** +#### **Number, String, and Boolean (整型 字符串和布尔值)** 支持的整型包括 int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr(无符号整型,长度跟平台相关,它的长度可以用来保存一个指针地址) 等 @@ -137,7 +137,7 @@ var d float32 = 1.222 var x complex128 = cmplx.Sqrt(-5 + 12i) ``` -#### **Arrays, Slices, and Maps** +#### **Arrays, Slices, and Maps( 数组、切片和Maps)** 数组是由相同数据类型的元素组成的一个序列。数组在声明时有一个固定的长度,所以它不能被扩大到超过这个长度。一个数组声明: @@ -222,7 +222,7 @@ fmt.Println(m['clearity']) // -> 2 fmt.Println(m['simplicity']) // -> 3 ``` -### **Typecasting** +### **Typecasting (类型转换)** 一种类型的数据类型可以通过类型转换转换为另一种类型。让我们看看一个简单的类型转换: @@ -235,7 +235,7 @@ fmt.Println(b) 不是所有类型的数据类型都可以转换为另一种类型。请确保数据类型与转换的内容相匹配。 -### Conditional Statements +### Conditional Statements (条件语句) #### if else @@ -267,7 +267,7 @@ default: } ``` -### Looping +### Looping (循环) Go 有一个循环的关键词 `for`。for循环命令用于实现不同种类的循环: @@ -300,7 +300,7 @@ for { } ``` -### Pointers +### Pointers (指针) Go提供了指针。指针是用来保存一个值的地址的地方。指针是由 \* 定义的。指针是根据数据的类型来定义的。 例如: @@ -343,7 +343,7 @@ func main() { 注意:当你在尝试博客中的示例代码时,不要忘记用 `package main` 包含它,并在需要时导入 fmt 或其他包,如上面第一个 main.go 例子中所示。 -### Functions +### Functions (函数) 在 main package 中定义的 main 函数是 go 程序执行的入口。更多的函数可以被定义和使用。让我们来看看一个简单的例子。: @@ -389,11 +389,11 @@ func main() { } ``` -### Method, Structs, and Interfaces +### Method, Structs, and Interfaces (方法,结构体,接口) Go并不是一种完全面向对象的语言,但通过结构体(Struct)、接口(Interface)和方法(Method),它有很多面向对象的支持和感觉。 -#### Struct +#### Struct (结构体) 结构体是一种类型化的、不同字段的集合。结构体用于将数据分组。例如,如果我们想对 Person 类型的数据进行分组,我们可以定义一个人的属性,其中可能包括姓名、年龄、性别。可以使用以下语法来定义一个结构体: @@ -433,7 +433,7 @@ pp.name //=> Bob ``` -#### Methods +#### Methods (方法) 方法(Method)是一种特殊的函数类型,它有一个 _receiver_ 。 _receiver_ 可以是一个值或一个指针。让我们创建一个名为 describe 的方法(Method),它有一个我们在上面的例子中创建的接收器类型的 person: @@ -477,7 +477,7 @@ func main() { 请注意,在上面的例子中,年龄的值被改变了,而名字的值没有改变,因为setName方法是 _receiver_ 类型的 ,而 setAge 是指针类型的。 -#### Interfaces +#### Interfaces (接口) Go 接口(interfaces)是一个方法(methods)的集合。接口有助于将一个类型的属性组合在一起。让我们以一个接口 animal 为例: @@ -533,14 +533,14 @@ func main() { type cat struct { 在主函数中,我们创建一个动物类型的变量 `a`。我们给动物分配一个 snake 和一个 cat 的类型,并使用 Println 来打印 a.description。由于我们在两种类型(cat 和snake)中都以不同的方式实现了 describe 方法,我们得到了打印的动物描述。 -### Packages +### Packages (包) 我们把Go的所有代码都写在一个包里。**main** package 是程序执行的入口点。Go中有很多内置包。我们一直在使用的最著名的是**fmt**包。 > "Go软件包是Go提供的大型编程的主要机制,它们使得将一个大型项目分割成小块成为可能。" > — Robert Griesemer -#### Installing a package +#### Installing a package (安装一个包) ```shell go get @@ -550,7 +550,7 @@ go get github.com/satori/go.uuid 我们安装的软件包被保存在 GOPATH 环境变量设置的工作目录。你可以通过进入我们工作目录下的pkg文件夹 `cd $GOPATH/pkg` 来查看这些软件包。 -#### Creating a custom package +#### Creating a custom package (创建自定义包) 让我们先创建一个文件夹 custom_package: @@ -601,7 +601,7 @@ func main(){ 在这里,我们现在可以导入我们创建的包 `person` 并使用函数 Description。注意,我们在包中创建的函数 `secretName` 将不能被访问。在 Go 中,没有大写字母开头的方法名称将是私有的。 -#### **Packages Documentation** +#### **Packages Documentation (包文档)** Go内置了对包的文档支持。运行以下命令来生成文档: @@ -617,7 +617,7 @@ godoc -http=":8080" 现在去URL [http://localhost:8080/pkg/](http://localhost:6060/pkg/),看看我们刚刚创建的包的文档。 -#### Some built-in packages in Go +#### Some built-in packages in Go (Go内置包) **fmt** @@ -670,7 +670,7 @@ func main(){ 当使用 unmarshal 解码 json 字节时,第一个参数是 json 字节,第二个参数是我们希望 json 被映射到的响应类型结构的地址。注意,`json: "page"`将页面键映射到结构中的 PageNumber 键。 -### Error Handling +### Error Handling (错误处理) 错误是指程序中不想要的和意外的结果。比方说,我们正在对一个外部服务进行 API 调用。这个 API 调用可能是成功的,也可能是失败的。当错误类型出现时,Go 程序中的错误可以被识别。让我们看看这个例子: @@ -698,7 +698,7 @@ func main(){ } ``` -#### Returning custom error from a function +#### Returning custom error from a function (从函数返回自定义错误) 当我们在编写自己的函数时,有些情况下会出现错误。这些错误可以在错误对象的帮助下返回: @@ -766,11 +766,11 @@ Defer 是指总是在函数的末尾被执行的东西。 在上面的例子中,我们用 panic() 使程序的执行陷入 panic。正如你所注意到的,这里有一个 defer 语句,它将使程序在最后执行这一行。当我们需要在函数结束时执行一些东西时也可以使用 defer,例如关闭一个文件。 -### Concurrency +### Concurrency (并发) Go 是在考虑到并发性的情况下建立的。Go 中的并发性可以通过 Go 协程实现,它是轻量级的线程。 -**Go routine** +**Go routine (Go 协程)** Go 协程是可以与另一个函数并行或同时运行的函数。创建一个 Go 协程非常简单。只需在一个函数前面加上关键字 Go,我们就可以让它并行执行。Go 协程是非常轻量级的,所以我们可以创建成千上万的协程。让我们来看看一个简单的例子: @@ -795,7 +795,7 @@ func c() { 正如你在上面的例子中所看到的,函数 c 是一个 Go 例程,与 Go 主线程并行执行。有些时候,我们希望在多个线程之间共享资源。Go 倾向于不将一个线程的变量与另一个线程共享,因为这样会增加死锁和资源等待的可能性。还有一种方法可以在 Go 协程之间共享资源:通过Go channels。 -**Channels** +**Channels (通道)** 我们可以使用通道在两个 Go 协程之间传递数据。在创建 channel 时,有必要指定该 channel 接收什么样的数据。让我们创建一个简单的字符串类型的 channel,如下所示: @@ -821,7 +821,7 @@ func main(){ 接收方 channel 等待,直到发送方发送数据到 channel。 -**One way channel** +**One way channel (单向通道)** 有些情况下,我们希望 Go 程序通过 channel 接收数据,但不发送数据,反之亦然。为此,我们也可以创建一个**单向 channel**。让我们来看看一个简单的例子: @@ -846,9 +846,9 @@ func sc(ch chan<- string) { In the above example, `sc` is a Go routine which can only send messages to the channel but cannot receive messages. -### Organizing multiple channels for a Go routine using select +### Organizing multiple channels for a Go routine using select (使用 select 为 Go 例程组织多个通道) -一个函数可能有多个 channel 在等待。为此,我们可以使用一个选择(seleect)语句。让我们看一个例子,以了解更清楚的情况: +一个函数可能有多个 channel 在等待。为此,我们可以使用一个选择(select)语句。让我们看一个例子,以了解更清楚的情况: ```go package main @@ -885,7 +885,7 @@ func speed2(ch chan string) { 在上面的例子中,main正在等待两个 channel,c1和c2。通过 select case 语句,main函数打印出,信息从它先收到的 channel 中发送出来。 -**Buffered channel** +**Buffered channel(带缓冲的通道)** 你可以在go中创建一个缓冲 channel。有了缓冲 channel,如果缓冲区满了,发送到该 channel 的消息就会被阻断。让我们看一下这个例子: @@ -907,7 +907,7 @@ func main(){ 正如我们在上面看到的,一个 channel 接受的信息不超过2条。 -#### Why is Golang Successful? +#### 为什么Golang会成功? > 简洁性… — Rob-pike @@ -928,7 +928,6 @@ func main(){ 恭喜你,你现在对 Go 有了相当的了解。 > 我最有成效的一天是减少了1000行代码。 - > — Ken Thompson 不要停在这里。继续向前推进。思考一个小的应用并开始创建。 From 4fd2570352507dbde9c8e7858a6b4ad5c302184c Mon Sep 17 00:00:00 2001 From: luojiyin Date: Tue, 19 Apr 2022 15:29:08 +0800 Subject: [PATCH 07/15] chore: code clear --- .../articles/learning-go-from-zero-to-hero.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/chinese/articles/learning-go-from-zero-to-hero.md b/chinese/articles/learning-go-from-zero-to-hero.md index e21c3563c..ac3dd92c3 100644 --- a/chinese/articles/learning-go-from-zero-to-hero.md +++ b/chinese/articles/learning-go-from-zero-to-hero.md @@ -23,7 +23,7 @@ Go 却相信用较少的功能--只有一种正确的方式来解决问题。 ### 入门 -Go是由 packages(包) 组成的。package main 告诉Go编译器,该程序被编译为可执行文件,而不是共享库。它是一个应用程序的入口点。package main 的定义如下: +Go 是由 packages(包) 组成的。package main 告诉 Go 编译器,该程序被编译为可执行文件,而不是共享库。它是一个应用程序的入口点。package main 的定义如下: ```go package main @@ -35,7 +35,7 @@ package main Go中的 workspace 是由环境变量 `GOPATH` 定义的。 -你写的任何代码都要写在 workspace 里面。Go将搜索 `GOPATH` 目录内的任何软件包,或者 `GOROOT` 目录,该目录在安装 Go时 默认设置。`GOROOT` 是安装 Go 的路径。 +你写的任何代码都要写在 workspace 里面。Go 将搜索 `GOPATH` 目录内的任何软件包,或者 `GOROOT` 目录,该目录在安装 Go 时默认设置。`GOROOT` 是安装 Go 的路径。 设置 `GOPATH` 到你想要的目录。现在,让我们把它添加到 `~/workspace` 文件夹内。 @@ -66,7 +66,7 @@ func main(){ 我们通过使用 `import` 关键字在Go中导入一个包。`func main` 是代码被执行的主入口点。`Println` 是包 `fmt` 中的一个函数,它为我们打印出 "hello world"。 -让我们通过运行这个文件来看看。我们有两种方法可以运行Go命令。正如我们所知,Go是一种编译语言,所以我们首先需要在执行之前编译它。 +让我们通过运行这个文件来看看。我们有两种方法可以运行Go命令。正如我们所知,Go 是一种编译语言,所以我们首先需要在执行之前编译它。 ```shell > go build main.go @@ -535,9 +535,9 @@ type cat struct { ### Packages (包) -我们把Go的所有代码都写在一个包里。**main** package 是程序执行的入口点。Go中有很多内置包。我们一直在使用的最著名的是**fmt**包。 +我们把Go的所有代码都写在一个包里。**main** package 是程序执行的入口点。Go 中有很多内置包。我们一直在使用的最著名的是**fmt**包。 -> "Go软件包是Go提供的大型编程的主要机制,它们使得将一个大型项目分割成小块成为可能。" +> "Go 软件包是 Go 提供的大型编程的主要机制,它们使得将一个大型项目分割成小块成为可能。" > — Robert Griesemer #### Installing a package (安装一个包) @@ -548,7 +548,7 @@ go get go get github.com/satori/go.uuid ``` -我们安装的软件包被保存在 GOPATH 环境变量设置的工作目录。你可以通过进入我们工作目录下的pkg文件夹 `cd $GOPATH/pkg` 来查看这些软件包。 +我们安装的软件包被保存在 GOPATH 环境变量设置的工作目录。你可以通过进入我们工作目录下的 pkg 文件夹 `cd $GOPATH/pkg` 来查看这些软件包。 #### Creating a custom package (创建自定义包) @@ -566,7 +566,7 @@ go get github.com/satori/go.uuid > cd person ``` -现在让我们在这个文件夹中创建一个文件person.go。 +现在让我们在这个文件夹中创建一个文件 person.go。 ```go package person @@ -584,7 +584,7 @@ func secretName(name string) string { > go install ``` -现在让我们回到custom_package文件夹,创建一个main.go文件 +现在让我们回到custom_package文件夹,创建一个 main.go 文件 ```go package main @@ -625,7 +625,7 @@ godoc -http=":8080" **json** -Go中另一个有用的包是json包。这有助于对JSON进行编码/解码。让我们举个例子,对一些JSON进行编码/解码: +Go中另一个有用的包是json包。这有助于对JSON进行编码/解码。让我们举个例子,对一些 JSON 进行编码/解码: 编码 From a0a4e706647d983783fbce80f2c3e0c60135892d Mon Sep 17 00:00:00 2001 From: luojiyin1987 Date: Mon, 13 May 2024 03:40:45 +0000 Subject: [PATCH 08/15] Auto Format --- ...generators-as-an-alternative-to-state-management.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/chinese/articles/async-generators-as-an-alternative-to-state-management.md b/chinese/articles/async-generators-as-an-alternative-to-state-management.md index 27439cdf9..4fd9ac197 100644 --- a/chinese/articles/async-generators-as-an-alternative-to-state-management.md +++ b/chinese/articles/async-generators-as-an-alternative-to-state-management.md @@ -42,7 +42,7 @@ Redux and other state management tools are mostly focusing on restricting or con All the common state management techniques can be split into two big classes. -The first class maintaining data dependencies graph to propagate changes through handlers — React Component State, MobX, RxJS. Maintaining these dependencies is a complex task. The underlying libraries are taking charge of part of this complexity by managing subscriptions, optimizing the order of handlers execution, batching them, but it is still confusing to use sometimes, often requires hard fine-tuning, e.g., with `shouldComponentUpdate`method. +The first class maintaining data dependencies graph to propagate changes through handlers—React Component State, MobX, RxJS. Maintaining these dependencies is a complex task. The underlying libraries are taking charge of part of this complexity by managing subscriptions, optimizing the order of handlers execution, batching them, but it is still confusing to use sometimes, often requires hard fine-tuning, e.g., with `shouldComponentUpdate`method. Another approach limits mutation to only a single cell (storage) (e.g., Redux). This needs much smaller libraries, with less magic in them. It is more a pattern than a library. Unfortunately, the programs are more verbose, and this breaks data encapsulation. There are many patterns, wrappers to solve this though, but they make a single cell approach to be more similar to the graph based one. @@ -54,7 +54,7 @@ Let’s first port [Redux VanillaJS counters][5] example to illustrate the idea. The original reducer is replaced with async generator function. The function calculates and stores its state in a local variable. It also yields the calculated value, the new value is stored in the singleton storage, and it is visible from event handlers. I’ll remove that singleton storage in the next steps. -This version doesn’t look much different from Redux. The async generator there could be Redux storage middleware. This violates one of Redux [principles][6] though, namely storing all application state only in the storage. Even if the generator doesn’t have any local variables, it still has its execution state — the position in the code where the execution is suspended in `yield` or `await`. +This version doesn’t look much different from Redux. The async generator there could be Redux storage middleware. This violates one of Redux [principles][6] though, namely storing all application state only in the storage. Even if the generator doesn’t have any local variables, it still has its execution state—the position in the code where the execution is suspended in `yield` or `await`. #### Turning components inside-out @@ -90,7 +90,7 @@ Async generators overhead is much smaller than for state management libraries. B In the former example, there are useless calls to `ReactDom.render`. This is obviously a performance problem, and there is a simple solution. Solving it quickly by sending another message with type “FLUSH” after each dispatched event. React render runs only after it receives this message. The intermediate steps can yield whatever they need in between. -Another awesome side of this approach is you may not worry about performance until it is a problem. Everything is structured in small autonomous stages. They are easy to refactor, or even without refactoring — many performance problems can be solved by adding another generic state in the pipe of steps, e.g., batching, prioritizing, saving intermediate data, etc. +Another awesome side of this approach is you may not worry about performance until it is a problem. Everything is structured in small autonomous stages. They are easy to refactor, or even without refactoring—many performance problems can be solved by adding another generic state in the pipe of steps, e.g., batching, prioritizing, saving intermediate data, etc. For example, in the demo constructed React elements are saved in local variables and React can re-use them. Changes are propagated from the root towards leaves, so optimizations like overriding`shouldComponentUpdate` aren’t needed. @@ -117,7 +117,7 @@ If you prefer unit-tests as documentation policy, there are many ways to make a #### Persistent state -There is another motivation for Redux described in [You Might Not Need Redux][8] article by Dan Abramov — namely providing access to the state and it can be serialized, cloned, diffed, patched, etc. This can be used for time travel, hot reloading, universal applications and more. +There is another motivation for Redux described in [You Might Not Need Redux][8] article by Dan Abramov—namely providing access to the state and it can be serialized, cloned, diffed, patched, etc. This can be used for time travel, hot reloading, universal applications and more. For this to work, the whole application state should be kept in Redux storage. Many Redux applications(even Redux samples) have some part of state stored outside of their store. These are components state, closures, generators or async functions state. Redux based tools can not persist this state. @@ -165,7 +165,7 @@ Some generator can also reorder messages to give animation a bigger priority tha Commonly used state management tools have FP background. The code from the article doesn’t look like FP in JavaScript because of imperative `for-of/switch/break`statements. It has a corresponding concept in FP too. It is so called Monads do-notation. For example one of their use in Haskell is to resolve problems like React components property drilling. -To keep this story practical I don’t digress from the main subject here, there is another article — [Using Generators as syntax sugar for side effects][10]. +To keep this story practical I don’t digress from the main subject here, there is another article—[Using Generators as syntax sugar for side effects][10]. #### Effectful.js From 606edcd2999b42ace3e83c74f540a17ad75d89dd Mon Sep 17 00:00:00 2001 From: luojiyin1987 Date: Fri, 28 Jun 2024 03:35:19 +0000 Subject: [PATCH 09/15] Auto Format --- chinese/articles/coding-bootcamp-handbook.md | 2 +- chinese/articles/javascript-class-handbook.md | 2 +- chinese/articles/learn-git-basics.md | 54 +++++++++---------- chinese/articles/procedural-macros-in-rust.md | 6 +-- 4 files changed, 32 insertions(+), 32 deletions(-) diff --git a/chinese/articles/coding-bootcamp-handbook.md b/chinese/articles/coding-bootcamp-handbook.md index bfa58bf89..62d9aff9b 100644 --- a/chinese/articles/coding-bootcamp-handbook.md +++ b/chinese/articles/coding-bootcamp-handbook.md @@ -389,7 +389,7 @@ Surprisingly, there are a few bootcamps that are for-profit but still free. And 要了解参加编码训练营的真实成本,你应该考虑机会成本。 -**例子**:你现在每个月赚$3000美元。你搬到旧金山,在那$2,000 美元只能租到一个卧室。你参加 12 周的训练营费用是\$15,00 0美元。 +**例子**:你现在每个月赚$3000美元。你搬到旧金山,在那$2,000 美元只能租到一个卧室。你参加 12 周的训练营费用是\$15,00 0美元。 这是你的真实成本,假设加上你在 6 个月的时间内找到工作并领取第一份薪水: diff --git a/chinese/articles/javascript-class-handbook.md b/chinese/articles/javascript-class-handbook.md index 7e6c52391..b2d575470 100644 --- a/chinese/articles/javascript-class-handbook.md +++ b/chinese/articles/javascript-class-handbook.md @@ -1666,7 +1666,7 @@ In this article, we discussed what a JavaScript class object is. We also used ex Thanks for reading! -### And here’s a useful React.JS resource: +### And here’s a useful React.JS resource I wrote a book about [Creating NPM Packages][113]! diff --git a/chinese/articles/learn-git-basics.md b/chinese/articles/learn-git-basics.md index 5c6bdfd5c..773968121 100644 --- a/chinese/articles/learn-git-basics.md +++ b/chinese/articles/learn-git-basics.md @@ -28,11 +28,11 @@ In this tutorial, I'll take you through the fundamentals of Git, covering everyt By the end of this guide, you'll have a solid understanding of Git's core concepts and be confident and well equipped with the skills to effectively use it in your development workflow. -## Prerequisites: +## Prerequisites All you need to bring to the table is a curious and eager-to-learn mindset. This guide is crafted with beginners in mind, so no prior knowledge of version control systems or programming is required. Whether you're a complete novice or have some experience with coding, you'll find this tutorial accessible and easy to follow. -## **Table of Contents:** +## **Table of Contents** 1. [What is Git?][3] – [Difference from other version control systems][4] @@ -67,21 +67,21 @@ Git is a distributed version control system that helps you and your team collabo ### What makes Git different from other Version Control Systems? -#### Conceptual Difference: +#### Conceptual Difference The big thing that sets Git apart from other tools is how it thinks about data. Instead of storing changes to files, Git thinks of its data as a series of snapshots of your project, means, every time you make a change and save it (commit), Git takes a snapshot of all your files at that moment. If a file hasn't changed, Git just keeps a link to the previous identical file. -#### Local Operations: +#### Local Operations With Git, most things you do don't need a connection to a server. Because you have the entire project history on your computer, operations are super fast. You can browse project history or see changes between versions without waiting for a server. -#### Data Integrity: +#### Data Integrity Git makes sure nothing gets lost or corrupted. Every file and directory is checksummed, and Git knows if anything changes. Git uses a SHA-1 hash, a unique code for each version of a file. If any changes are made to the content, even a single character, it will result in a different SHA-1 hash. -#### Append-Only Model: +#### Append-Only Model In Git, almost everything adds data to the project, making it hard to accidentally lose information. Once you commit changes, they are safely stored. Experimenting is less risky with Git. @@ -122,7 +122,7 @@ To view all configuration settings and their sources/origins: $ git config --list --show-origin ``` -#### How to Configure your identity in Git: +#### How to Configure your identity in Git Identity in Git is used for attributing commits properly. Let's set up your user name and email address. @@ -153,7 +153,7 @@ Make sure you provide the correct path to the executable file of your text edito By the way, these – `"-multiInst -notabbar -nosession -noPlugin"` – are options used to customize the behavior of Notepad++ when it is launched by Git. -#### How to Change default branch name in Git (optional): +#### How to Change default branch name in Git (optional) By default, when you initialize a new repository with `git init`, Git creates a branch named `master`. But from Git version 2.28 onwards, you have the option to set a different name for the initial branch. @@ -163,7 +163,7 @@ $ git config --global init.defaultBranch main changes the default branch name to 'main' globally -#### How to Check Configuration/settings in Git: +#### How to Check Configuration/settings in Git You can view your Git configuration using: @@ -224,7 +224,7 @@ $ git commit -m 'Initial commit' `git add` adds files to the staging area indicating that you want to include them in the next commit, and then commit the changes. The `-m` flag allows you to add a descriptive message to the commit. -### 2\. How to Clone an Existing Repository in Git: +### 2. How to Clone an Existing Repository in Git The second way to obtain a Git repository is by cloning an existing one. This is useful when you want to work on a project that already exists elsewhere (for example, a project you'd like to contribute to). @@ -256,7 +256,7 @@ Now that you have a Git repository set up, you'll often need to make changes and pic credit - https://git-scm.com/ -### 1\. How to Check the Status of Your Files in Git: +### 1. How to Check the Status of Your Files in Git When working with a Git repository, it's crucial to understand the status of your files. @@ -327,7 +327,7 @@ Here are some patterns you can use to work more effectively in Git. - ****Target individual files or file extensions precisely:**** For example, `test.txt` ignores only that specific file, while `*.log` ignores all files ending with `.log`. - ****Wildcards for broader matches:**** The asterisk (`*`) wildcard matches any number of characters. For example, `*.doc` ignores all files with the `.doc` extension, regardless of their name. -### 5\. How to View Changes in Git: +### 5. How to View Changes in Git If you want to see the exact changes you've made to your files before committing, you can use the `git diff` command. @@ -345,7 +345,7 @@ $ git diff --cached README.md `git diff` provides a detailed view of the actual modifications. Use `git diff ` to focus on changes within a particular file. -### 6\. How to Commit Changes: +### 6. How to Commit Changes When you are ready to commit your changes, use the `git commit` command. This opens your text editor for you to provide a commit message. Alternatively, you can use the `-m` flag to add a commit message directly: @@ -355,7 +355,7 @@ Once you have staged the changes you want to include in the commit, you can comm $ git commit -m "Your commit message here" ``` -### 7\. How to Remove Files in Git: +### 7. How to Remove Files in Git If you need to remove a file from Git's tracking, you can use `git rm`. It remove the file from both the repository and working directory. Suppose you want to remove a file named `temp.txt`: @@ -369,7 +369,7 @@ If you only want to remove it from the repository but keep it in the working dir $ git rm --cached temp.txt ``` -### 8\. How to Move (or Rename) Files in Git: +### 8. How to Move (or Rename) Files in Git Git doesn't explicitly track file movements. But you can use `git mv` to rename or move files within your repository. For example, to rename `old_file.txt` to `new_file.txt`: @@ -390,7 +390,7 @@ After creating multiple commits or cloning a repository, the `git log` command a By default, it lists commits in reverse chronological order, displaying each commit with its SHA-1 checksum, author's name and email, date, and commit message. Now let's see how can we enhance this output: -### How to View Commit Differences in Git: +### How to View Commit Differences in Git To view the difference introduced in each commit, you can use the `-p` or `--patch` option: @@ -398,7 +398,7 @@ To view the difference introduced in each commit, you can use the `-p` or `--pat $ git log -p -2 # -2 is used to view the differences introduced in each of the last two commits ``` -### How to Display Statistics in Git: +### How to Display Statistics in Git The `--stat` option provides summarized statistics for each commit, including the modified files, lines added/deleted, and a summary. @@ -406,7 +406,7 @@ The `--stat` option provides summarized statistics for each commit, including th $ git log --stat ``` -### How to Customize Git Log Output Format: +### How to Customize Git Log Output Format The `--pretty` option allows you to alter the log output format. Various options are available for different formats: @@ -440,7 +440,7 @@ Using `--graph`, you can also visualize branch and merge history. $ git log --pretty=format:"%h %s" --graph ``` -### How to Limit Git Log Output: +### How to Limit Git Log Output In addition to formatting options, `git log` offers various limiting options to refine the displayed commit history. @@ -790,7 +790,7 @@ A branch is a lightweight, movable pointer to a commit. The default branch name Creating and switching between branches allows you to work on different features simultaneously. -### How to Create a New Branch in Git: +### How to Create a New Branch in Git When you want to start working on a new feature or experiment with an idea, you can create a new branch in Git. This new branch serves as a separate line of development, allowing you to make changes without affecting the main branch. @@ -816,7 +816,7 @@ This will display a list of branches with an asterisk (\*) indicating the curren $ git branch -v ``` -### How to Switch to Another Branch in Git: +### How to Switch to Another Branch in Git To switch to an existing different branch, use `git checkout`. @@ -837,7 +837,7 @@ In Git version 2.23 onwards, you can use `git switch` instead of `git checkout`. - Switch to an existing branch: `git switch existing-branch`. - Create and switch to new branch: `git switch -c new-branch`. -### How to Visualize Branches in Git: +### How to Visualize Branches in Git After creating and switching branches, you can visualize the branch structure using: @@ -936,11 +936,11 @@ This is **different from `$ git config --global init.defaultBranch main`** that Let's understand branches in more detail and look at a common branching workflow that is used in large projects. -### Long-Running Branches: +### Long-Running Branches In Git, long-running branches are branches that remain open over an extended period. -### Topic Branches: +### Topic Branches `Topic`/`Feature` branches are short-lived branches created for specific features or pieces of work. Unlike long-running branches, which persist over time, topic branches are created, used, and often deleted once the work is complete. @@ -966,7 +966,7 @@ In Git, when you're working with branches, there are two primary ways to integra Unlike merging, which can create a cluttered history with multiple merge commits, rebasing produces a linear history, making it easier to understand the sequence of changes made over time. -### Basic Rebase Example: +### Basic Rebase Example Imagine you're working on a project with two branches: "feature" and "master". You've made some commits on the "feature" branch and now want to integrate these changes into the "master" branch using rebasing. @@ -1006,12 +1006,12 @@ Now, your project history appears linear, reflecting the sequential integration ### Rebasing vs Merging: Which is Better? -#### Rebasing Use Cases: +#### Rebasing Use Cases - Suitable for feature branches that need a clean integration into the mainline branch. - Preferred for open-source contributions where a clean commit history is valued. -#### Merging Use Cases: +#### Merging Use Cases - Appropriate for collaborative environments where transparency in the project's development process is crucial. - Useful for projects where maintaining an accurate historical record is a priority. diff --git a/chinese/articles/procedural-macros-in-rust.md b/chinese/articles/procedural-macros-in-rust.md index 27fd7aa90..2d10047aa 100644 --- a/chinese/articles/procedural-macros-in-rust.md +++ b/chinese/articles/procedural-macros-in-rust.md @@ -296,9 +296,9 @@ This does create a problem though. You need to be able to make sense of this "st We can, however, rely on great open source work done by many developers to ease this for us. You need to add a few dependencies to help with this problem: -- `syn` — A syntax parser for Rust. This helps you to parse the input token stream as Rust AST. AST is a concept that you mostly run into when trying to write your own interpreter or compiler, but a basic understanding is essential for working with macros. Macros, after all, are just extensions that you write for the compiler in a sense. If you’re interested in learning more about what ASTs are, [check out this very helpful introduction][57]. -- `quote` — quote is, and this is a huge generalisation, a crate that helps us perform the reverse operation of what `syn` does. It helps us convert Rust source code into a stream of tokens that we can output from our macro. -- `proc-macro2` — The standard library provides a `proc-macro` crate, but the types it provides cannot exist outside of procedural macros. `proc-macro2` is a wrapper around the standard library that makes all of the internal types usable outside of the context of macros. This, for example, allows both `syn` and `quote` to not only be used for procedural macros, but in regular Rust code as well, should you ever have such a need. And we will indeed be using that extensively if we ever want to unit test our macros or their expansions. +- `syn`—A syntax parser for Rust. This helps you to parse the input token stream as Rust AST. AST is a concept that you mostly run into when trying to write your own interpreter or compiler, but a basic understanding is essential for working with macros. Macros, after all, are just extensions that you write for the compiler in a sense. If you’re interested in learning more about what ASTs are, [check out this very helpful introduction][57]. +- `quote`—quote is, and this is a huge generalisation, a crate that helps us perform the reverse operation of what `syn` does. It helps us convert Rust source code into a stream of tokens that we can output from our macro. +- `proc-macro2`—The standard library provides a `proc-macro` crate, but the types it provides cannot exist outside of procedural macros. `proc-macro2` is a wrapper around the standard library that makes all of the internal types usable outside of the context of macros. This, for example, allows both `syn` and `quote` to not only be used for procedural macros, but in regular Rust code as well, should you ever have such a need. And we will indeed be using that extensively if we ever want to unit test our macros or their expansions. - `darling`–It facilitates parsing and working with macro arguments, which is otherwise a tedious process due to having to manually parse it from the syntax tree. `darling` provides us with `serde`\-like ability to automatically parse input argument tree into our arguments struct. It also helps us in error handling around invalid arguments, required arguments, and so on. While these projects are contributed to by many developers, I want to give special thanks to [David Tolnay][58]. He's a legend in the Rust community and is the creator of most of these projects, and many many more open source crates in Rust. From a9e6301eeabc90b1892c69a7d3c2ca50b0abaa9f Mon Sep 17 00:00:00 2001 From: luojiyin Date: Fri, 28 Jun 2024 12:02:18 +0800 Subject: [PATCH 10/15] fix from review --- .../articles/learning-go-from-zero-to-hero.md | 88 +++++++++---------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/chinese/articles/learning-go-from-zero-to-hero.md b/chinese/articles/learning-go-from-zero-to-hero.md index ac3dd92c3..2eeca0e0a 100644 --- a/chinese/articles/learning-go-from-zero-to-hero.md +++ b/chinese/articles/learning-go-from-zero-to-hero.md @@ -5,15 +5,15 @@ ![Learning Go — from zero to hero](https://cdn-media-1.freecodecamp.org/images/1*30aoNxlSnaYrLhBT0O1lzw.png) -让我们先对 Go(或称 Golang )做一个小小的介绍。Go 是由谷歌工程师 Robert Griesemer、Rob Pike 和 Ken Thompson 设计的。它是一种静态类型的、编译的语言。第一个版本于2012年3月作为开源版本发布。 +让我们先对 Go(或称 Golang )做一个小小的介绍。Go 是由谷歌工程师 Robert Griesemer、Rob Pike 和 Ken Thompson 设计的。它是一种静态类型的、编译的语言。第一个版本于 2012 年 3 月作为开源版本发布。 -> "Go是一种开源的编程语言,它使人们能够轻松地构建简单、可靠和高效的软件"。- GoLang +> "Go 是一种开源的编程语言,它使人们能够轻松地构建简单、可靠和高效的软件"。- GoLang 在许多编程语言中,有许多方法来解决一个特定的问题。程序员要花很多时间去思考解决它的最佳方法。 Go 却相信用较少的功能--只有一种正确的方式来解决问题。 -这为开发人员节省了时间,并使大型代码库易于维护。 Go中没有像 `maps` 和 `filters` 这样的 "表达性 "功能。 +这为开发人员节省了时间,并使大型代码库易于维护。 Go 中没有像 `maps` 和 `filters` 这样的 "表达性 "功能。 > "当你有增加表现力的功能时,通常会增加系统开销。"--Rob Pike @@ -33,7 +33,7 @@ package main #### **Workspace** -Go中的 workspace 是由环境变量 `GOPATH` 定义的。 +Go 中的 workspace 是由环境变量 `GOPATH` 定义的。 你写的任何代码都要写在 workspace 里面。Go 将搜索 `GOPATH` 目录内的任何软件包,或者 `GOROOT` 目录,该目录在安装 Go 时默认设置。`GOROOT` 是安装 Go 的路径。 @@ -62,11 +62,11 @@ func main(){ } ``` -在上面的例子中,`fmt`是Go中的一个内置包,它实现了用于格式化 I/O 输出的函数。 +在上面的例子中,`fmt`是 Go 中的一个内置包,它实现了用于格式化 I/O 输出的函数。 -我们通过使用 `import` 关键字在Go中导入一个包。`func main` 是代码被执行的主入口点。`Println` 是包 `fmt` 中的一个函数,它为我们打印出 "hello world"。 +我们通过使用 `import` 关键字在 Go 中导入一个包。`func main` 是代码被执行的主入口点。`Println` 是包 `fmt` 中的一个函数,它为我们打印出 "hello world"。 -让我们通过运行这个文件来看看。我们有两种方法可以运行Go命令。正如我们所知,Go 是一种编译语言,所以我们首先需要在执行之前编译它。 +让我们通过运行这个文件来看看。我们有两种方法可以运行 Go 命令。正如我们所知,Go 是一种编译语言,所以我们首先需要在执行之前编译它。 ```shell > go build main.go @@ -90,19 +90,19 @@ go run main.go ### Variables(变量) -Go 中的变量是明确声明的。Go 是一种静态类型的语言。这意味着在声明变量的时候会检查变量的类型。一个变量可以被声明: +Go 中的变量是明确声明的。Go 是一种静态类型的语言。这意味着在声明变量的时候会检查变量的类型。一个变量: ```go var a int ``` -在这种情况下,值将被设置为0。 使用下面的语法来声明和初始化一个具有不同值的变量: +在这种情况下,值将被设置为 0。 使用下面的语法来声明和初始化一个具有不同值的变量: ```go var a = 1 ``` -这里的变量被自动分配为int。 我们可以对变量的声明使用一个简短定义,即: +这里的变量被自动分配为`int`。 我们可以对变量的声明使用一个简短定义,即: ```go message := "hello world" @@ -116,7 +116,7 @@ var b, c int = 2, 3 ### Data types(数据类型) -像其他编程语言一样,Go支持各种不同的数据结构。让我们来探索其中: +像其他编程语言一样,Go 支持各种不同的数据结构。让我们来探索其中: #### **Number, String, and Boolean (整型 字符串和布尔值)** @@ -137,9 +137,9 @@ var d float32 = 1.222 var x complex128 = cmplx.Sqrt(-5 + 12i) ``` -#### **Arrays, Slices, and Maps( 数组、切片和Maps)** +#### **Arrays, Slices, and Maps( 数组、切片和映射)** -数组是由相同数据类型的元素组成的一个序列。数组在声明时有一个固定的长度,所以它不能被扩大到超过这个长度。一个数组声明: +数组是由相同数据类型的元素组成的一个序列。数组在声明时有一个固定的长度,所以它不能被扩大到超过这个长度。声明一个数组: ```go var a [5]int @@ -151,7 +151,7 @@ var a [5]int var multiD [2][3]int ``` -数组会限制数组的值发生变化,当代码运行时。数组也没有提供获取子数组的能力。 为此,Go有一种数据类型,叫做切片(slices)。 +在运行时更改数组是受限的。数组也没有提供获取子数组的能力。 为此,Go 有一种数据类型,叫做切片(slices)。 切片存储了一连串的元素,并且可以在任何时候扩展。切片声明与数组声明类似--但没有定义容量: @@ -167,7 +167,7 @@ var b []int numbers := make([]int,5,10) ``` -这里,切片的初始长度为5,容量为10。 +这里,切片的初始长度为 5,容量为 10。 分片是对数组的一种抽象。切片使用一个数组作为底层结构。一个片断包含三个部分:容量、长度和一个指向底层数组的指针,如下图所示: @@ -205,7 +205,7 @@ slice3 := number2[1:4] fmt.Println(slice3) // -> [2 3 4] ``` -Maps 是 Go中的一种数据类型,它将键映射到值。我们可以使用以下命令来定义一个 map: +Maps 是 Go 中的一种数据类型,它将键映射到值。我们可以使用以下命令来定义一个 map: ```go var m map[string]int @@ -269,7 +269,7 @@ default: ### Looping (循环) -Go 有一个循环的关键词 `for`。for循环命令用于实现不同种类的循环: +Go 有一个循环的关键词 `for`。for 循环命令用于实现不同种类的循环: ```go i := 0 @@ -281,9 +281,9 @@ for i < 10 { fmt.Println(sum) ``` -上面的例子类似于C语言中的while循环。 +上面的例子类似于 C 语言中的 while 循环。 -Go 中的 for 语句也可以用于普通的for循环: +Go 中的 for 语句也可以用于普通的 for 循环: ```go sum := 0 @@ -302,7 +302,7 @@ for { ### Pointers (指针) -Go提供了指针。指针是用来保存一个值的地址的地方。指针是由 \* 定义的。指针是根据数据的类型来定义的。 例如: +Go 提供了指针。指针是用来保存一个变量的地址的地方。指针是由 \* 定义的。指针是根据数据的类型来定义的。 例如: ```go var ap *int @@ -341,7 +341,7 @@ func main() { //=> 11 ``` -注意:当你在尝试博客中的示例代码时,不要忘记用 `package main` 包含它,并在需要时导入 fmt 或其他包,如上面第一个 main.go 例子中所示。 +注意:当你在尝试博客中的示例代码时,不要忘记包含 `package main`,并在需要时导入 `fmt` 或其他包,如上面第一个 main.go 例子中所示。 ### Functions (函数) @@ -373,7 +373,7 @@ func main() { //=> 3 ``` -这里c被定义为返回变量。所以定义的变量c会自动返回,而不需要在最后的返回语句中定义。 +这里 c 被定义为返回变量。所以定义的变量 c 会自动返回,而不需要在最后的返回语句中定义。 你也可以从一个函数中返回多个返回值,用逗号来分隔返回值。 @@ -391,7 +391,7 @@ func main() { ### Method, Structs, and Interfaces (方法,结构体,接口) -Go并不是一种完全面向对象的语言,但通过结构体(Struct)、接口(Interface)和方法(Method),它有很多面向对象的支持和感觉。 +Go 并不是一种完全面向对象的语言,但通过结构体(Struct)、接口(Interface)和方法(Method),它有很多面向对象的支持和感觉。 #### Struct (结构体) @@ -473,9 +473,9 @@ func main() { } ``` -正如我们在上面的例子中看到的,现在可以使用点运算符来调用该方法,如 `pp.describe`。请注意,_receiver_ 是一个指针。使用指针,我们传递的是一个值的引用,所以如果我们在方法中做任何改变,都会反映在 _receiver_ pp中。它也不会创建一个新的对象的副本,这就节省了内存。 +正如我们在上面的例子中看到的,现在可以使用点运算符来调用该方法,如 `pp.describe`。请注意,_receiver_ 是一个指针。使用指针,我们传递的是一个值的引用,所以如果我们在方法中做任何改变,都会反映在 _receiver_ pp 中。它也不会创建一个新的对象的副本,这就节省了内存。 -请注意,在上面的例子中,年龄的值被改变了,而名字的值没有改变,因为setName方法是 _receiver_ 类型的 ,而 setAge 是指针类型的。 +请注意,在上面的例子中,年龄的值被改变了,而名字的值没有改变,因为 setName 方法是 _receiver_ 类型是值类型,而 setAge 是指针类型的。 #### Interfaces (接口) @@ -531,11 +531,11 @@ func main() { ``` type cat struct { -在主函数中,我们创建一个动物类型的变量 `a`。我们给动物分配一个 snake 和一个 cat 的类型,并使用 Println 来打印 a.description。由于我们在两种类型(cat 和snake)中都以不同的方式实现了 describe 方法,我们得到了打印的动物描述。 +在主函数中,我们创建一个动物类型的变量 `a`。我们给动物分配一个 snake 和一个 cat 的类型,并使用 Println 来打印 a.description。由于我们在两种类型(cat 和 snake)中都以不同的方式实现了 describe 方法,我们得到了打印的动物描述。 ### Packages (包) -我们把Go的所有代码都写在一个包里。**main** package 是程序执行的入口点。Go 中有很多内置包。我们一直在使用的最著名的是**fmt**包。 +我们把 Go 的所有代码都写在一个包里。**main** package 是程序执行的入口点。Go 中有很多内置包。我们一直在使用的最著名的是**fmt**包。 > "Go 软件包是 Go 提供的大型编程的主要机制,它们使得将一个大型项目分割成小块成为可能。" > — Robert Griesemer @@ -584,7 +584,7 @@ func secretName(name string) string { > go install ``` -现在让我们回到custom_package文件夹,创建一个 main.go 文件 +现在让我们回到 custom_package 文件夹,创建一个 main.go 文件 ```go package main @@ -603,7 +603,7 @@ func main(){ #### **Packages Documentation (包文档)** -Go内置了对包的文档支持。运行以下命令来生成文档: +Go 内置了对包的文档支持。运行以下命令来生成文档: ```shell godoc person Description @@ -615,9 +615,9 @@ godoc person Description godoc -http=":8080" ``` -现在去URL [http://localhost:8080/pkg/](http://localhost:6060/pkg/),看看我们刚刚创建的包的文档。 +现在去 URL [http://localhost:8080/pkg/](http://localhost:6060/pkg/),看看我们刚刚创建的包的文档。 -#### Some built-in packages in Go (Go内置包) +#### Some built-in packages in Go (Go 内置包) **fmt** @@ -625,7 +625,7 @@ godoc -http=":8080" **json** -Go中另一个有用的包是json包。这有助于对JSON进行编码/解码。让我们举个例子,对一些 JSON 进行编码/解码: +Go 中另一个有用的包是 json 包。这有助于对 JSON 进行编码/解码。让我们举个例子,对一些 JSON 进行编码/解码: 编码 @@ -678,7 +678,7 @@ func main(){ resp, err := http.Get("http://example.com/") ``` -在这里,对错误对象的 API 调用可能通过也可能失败。我们可以检查错误是否为零或存在,并相应地处理响应: +在这里,API 调用可能通过也可能失败。我们可以检查错误是否为 `nil`或存在,并相应地处理响应: ```go package main @@ -725,7 +725,7 @@ func main() { #### Panic -Panic 是指在程序执行过程中突然遇到的未被处理的东西。在Go中,Panic 不是处理程序中异常的理想方式。建议使用一个错误对象来代替。当 Panic 发生时,程序的执行会被停止。Panic 发生后被执行的东西是 defer。 +Panic 是指在程序执行过程中突然遇到的未被处理的东西。在 Go 中,Panic 不是处理程序中异常的理想方式。建议使用一个错误对象来代替。当 Panic 发生时,程序的执行会被停止。Panic 发生后被执行的东西是 defer。 ```go //Go @@ -793,7 +793,7 @@ func c() { //=> I am concurrent ``` -正如你在上面的例子中所看到的,函数 c 是一个 Go 例程,与 Go 主线程并行执行。有些时候,我们希望在多个线程之间共享资源。Go 倾向于不将一个线程的变量与另一个线程共享,因为这样会增加死锁和资源等待的可能性。还有一种方法可以在 Go 协程之间共享资源:通过Go channels。 +正如你在上面的例子中所看到的,函数 c 是一个 Go 例程,与 Go 主线程并行执行。有些时候,我们希望在多个线程之间共享资源。Go 倾向于不将一个线程的变量与另一个线程共享,因为这样会增加死锁和资源等待的可能性。还有一种方法可以在 Go 协程之间共享资源:通过 Go channels。 **Channels (通道)** @@ -844,7 +844,7 @@ func sc(ch chan<- string) { } ``` -In the above example, `sc` is a Go routine which can only send messages to the channel but cannot receive messages. +在上面的例子中,`sc` 是一个只用于发送消息到通道但不能接受消息的 go 协程。 ### Organizing multiple channels for a Go routine using select (使用 select 为 Go 例程组织多个通道) @@ -883,11 +883,11 @@ func speed2(ch chan string) { } ``` -在上面的例子中,main正在等待两个 channel,c1和c2。通过 select case 语句,main函数打印出,信息从它先收到的 channel 中发送出来。 +在上面的例子中,main 正在等待两个 channel,c1 和 c2。通过 select case 语句,main 函数打印出,信息从它先收到的 channel 中发送出来。 **Buffered channel(带缓冲的通道)** -你可以在go中创建一个缓冲 channel。有了缓冲 channel,如果缓冲区满了,发送到该 channel 的消息就会被阻断。让我们看一下这个例子: +你可以在 go 中创建一个缓冲 channel。有了缓冲 channel,如果缓冲区满了,发送到该 channel 的消息就会被阻断。让我们看一下这个例子: ```go package main @@ -905,15 +905,15 @@ func main(){ // => fatal error: all goroutines are asleep - deadlock! ``` -正如我们在上面看到的,一个 channel 接受的信息不超过2条。 +正如我们在上面看到的,一个 channel 接受的信息不超过 2 条。 -#### 为什么Golang会成功? +#### 为什么 Golang 会成功? -> 简洁性… — Rob-pike +> 简洁性…… — Rob-pike ### Great -我们学习了Go的一些主要组成部分和特点。 +我们学习了 Go 的一些主要组成部分和特点。 1. 变量、数据类型 2. 数组 切片 和 maps @@ -927,11 +927,11 @@ func main(){ 恭喜你,你现在对 Go 有了相当的了解。 -> 我最有成效的一天是减少了1000行代码。 +> 我最有成效的一天是减少了 1000 行代码。 > — Ken Thompson 不要停在这里。继续向前推进。思考一个小的应用并开始创建。 [LinkedIn](https://www.linkedin.com/in/milap-neupane-99a4b565/), [Github](http://github.com/milap-neupane), [Twitter](https://twitter.com/_milap) -也发布在Milap Neupane博客: [学习Go,从0到1](https://milapneupane.com.np/2019/07/06/learning-golang-from-zero-to-hero/) +也发布在 Milap Neupane 博客: [学习 Go,从 0 到 1](https://milapneupane.com.np/2019/07/06/learning-golang-from-zero-to-hero/) From 0f727ea1830347f16958c87b0b3f7fffd59d779d Mon Sep 17 00:00:00 2001 From: luojiyin Date: Fri, 28 Jun 2024 12:06:42 +0800 Subject: [PATCH 11/15] fix from review --- chinese/articles/learning-go-from-zero-to-hero.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/chinese/articles/learning-go-from-zero-to-hero.md b/chinese/articles/learning-go-from-zero-to-hero.md index 2eeca0e0a..b3f0bd5d6 100644 --- a/chinese/articles/learning-go-from-zero-to-hero.md +++ b/chinese/articles/learning-go-from-zero-to-hero.md @@ -846,7 +846,7 @@ func sc(ch chan<- string) { 在上面的例子中,`sc` 是一个只用于发送消息到通道但不能接受消息的 go 协程。 -### Organizing multiple channels for a Go routine using select (使用 select 为 Go 例程组织多个通道) +### Organizing multiple channels for a Go routine using select (使用 select 为 Go 协程组织多个通道) 一个函数可能有多个 channel 在等待。为此,我们可以使用一个选择(select)语句。让我们看一个例子,以了解更清楚的情况: @@ -898,7 +898,7 @@ func main(){ ch := make(chan string, 2) ch <- "hello" ch <- "world" - ch <- "!" # extra message in buffer + ch <- "!" // extra message in buffer fmt.Println(<-ch) } @@ -916,7 +916,7 @@ func main(){ 我们学习了 Go 的一些主要组成部分和特点。 1. 变量、数据类型 -2. 数组 切片 和 maps +2. 数组 切片 和 映射 3. 函数 4. 循环和条件语句 5. 指针 From 444b51fd643db049b9985430ba41157fc0754366 Mon Sep 17 00:00:00 2001 From: luojiyin Date: Fri, 28 Jun 2024 12:16:17 +0800 Subject: [PATCH 12/15] fix from review --- chinese/articles/learning-go-from-zero-to-hero.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/chinese/articles/learning-go-from-zero-to-hero.md b/chinese/articles/learning-go-from-zero-to-hero.md index 9d8f6dc0c..875249c0d 100644 --- a/chinese/articles/learning-go-from-zero-to-hero.md +++ b/chinese/articles/learning-go-from-zero-to-hero.md @@ -169,7 +169,7 @@ numbers := make([]int,5,10) 这里,切片的初始长度为 5,容量为 10。 -分片是对数组的一种抽象。切片使用一个数组作为底层结构。一个片断包含三个部分:容量、长度和一个指向底层数组的指针,如下图所示: +切片是对数组的一种抽象。切片使用一个数组作为底层结构。一个切片包含三个部分:容量、长度和一个指向底层数组的指针,如下图所示: ![1*P0lNCO0sQwIYHLEX_mfSOQ](https://cdn-media-1.freecodecamp.org/images/1*P0lNCO0sQwIYHLEX_mfSOQ.png) @@ -181,7 +181,7 @@ numbers := make([]int,5,10) numbers = append(numbers, 1, 2, 3, 4) ``` -另一种增加切片容量的方法是使用 copy 函数。简单地创建另一个容量更大的片断,并将原来的切片复制到新创建的切片上: +另一种增加切片容量的方法是使用 copy 函数。简单地创建另一个容量更大的切片,并将原来的切片复制到新创建的切片上: ```go // create a new slice @@ -205,7 +205,7 @@ slice3 := number2[1:4] fmt.Println(slice3) // -> [2 3 4] ``` -Maps 是 Go 中的一种数据类型,它将键映射到值。我们可以使用以下命令来定义一个 map: +映射是 Go 中的一种数据类型,它将键映射到值。我们可以使用以下命令来定义一个 map: ```go var m map[string]int From 8f1dc092d3dd00538b66e8b2c35604a06f4233bb Mon Sep 17 00:00:00 2001 From: luojiyin Date: Fri, 28 Jun 2024 12:19:51 +0800 Subject: [PATCH 13/15] fix from review --- chinese/articles/learning-go-from-zero-to-hero.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chinese/articles/learning-go-from-zero-to-hero.md b/chinese/articles/learning-go-from-zero-to-hero.md index 875249c0d..8fc0613c6 100644 --- a/chinese/articles/learning-go-from-zero-to-hero.md +++ b/chinese/articles/learning-go-from-zero-to-hero.md @@ -325,7 +325,7 @@ fmt.Println(*ap) 在传递结构体作为参数时,或者在为定义的类型声明方法时,通常倾向于使用指针。 1. 传递值时,实际上是在复制值,这意味着更多的内存。 -2. 通过指针,函数改变的值会反映在 方法/函数 调用者身上 +2. 传递指针,函数改变的值会反映在 方法/函数 调用者身上 例如: From d11a207b1ed76c5e2427674de177676ccb36f734 Mon Sep 17 00:00:00 2001 From: luojiyin1987 Date: Fri, 28 Jun 2024 04:21:07 +0000 Subject: [PATCH 14/15] Auto Format --- chinese/articles/coding-bootcamp-handbook.md | 2 +- chinese/articles/javascript-class-handbook.md | 2 +- chinese/articles/learn-git-basics.md | 54 +++++++++---------- .../articles/learning-go-from-zero-to-hero.md | 2 +- chinese/articles/procedural-macros-in-rust.md | 6 +-- 5 files changed, 33 insertions(+), 33 deletions(-) diff --git a/chinese/articles/coding-bootcamp-handbook.md b/chinese/articles/coding-bootcamp-handbook.md index bfa58bf89..62d9aff9b 100644 --- a/chinese/articles/coding-bootcamp-handbook.md +++ b/chinese/articles/coding-bootcamp-handbook.md @@ -389,7 +389,7 @@ Surprisingly, there are a few bootcamps that are for-profit but still free. And 要了解参加编码训练营的真实成本,你应该考虑机会成本。 -**例子**:你现在每个月赚$3000美元。你搬到旧金山,在那$2,000 美元只能租到一个卧室。你参加 12 周的训练营费用是\$15,00 0美元。 +**例子**:你现在每个月赚$3000美元。你搬到旧金山,在那$2,000 美元只能租到一个卧室。你参加 12 周的训练营费用是\$15,00 0美元。 这是你的真实成本,假设加上你在 6 个月的时间内找到工作并领取第一份薪水: diff --git a/chinese/articles/javascript-class-handbook.md b/chinese/articles/javascript-class-handbook.md index 7e6c52391..b2d575470 100644 --- a/chinese/articles/javascript-class-handbook.md +++ b/chinese/articles/javascript-class-handbook.md @@ -1666,7 +1666,7 @@ In this article, we discussed what a JavaScript class object is. We also used ex Thanks for reading! -### And here’s a useful React.JS resource: +### And here’s a useful React.JS resource I wrote a book about [Creating NPM Packages][113]! diff --git a/chinese/articles/learn-git-basics.md b/chinese/articles/learn-git-basics.md index 5c6bdfd5c..773968121 100644 --- a/chinese/articles/learn-git-basics.md +++ b/chinese/articles/learn-git-basics.md @@ -28,11 +28,11 @@ In this tutorial, I'll take you through the fundamentals of Git, covering everyt By the end of this guide, you'll have a solid understanding of Git's core concepts and be confident and well equipped with the skills to effectively use it in your development workflow. -## Prerequisites: +## Prerequisites All you need to bring to the table is a curious and eager-to-learn mindset. This guide is crafted with beginners in mind, so no prior knowledge of version control systems or programming is required. Whether you're a complete novice or have some experience with coding, you'll find this tutorial accessible and easy to follow. -## **Table of Contents:** +## **Table of Contents** 1. [What is Git?][3] – [Difference from other version control systems][4] @@ -67,21 +67,21 @@ Git is a distributed version control system that helps you and your team collabo ### What makes Git different from other Version Control Systems? -#### Conceptual Difference: +#### Conceptual Difference The big thing that sets Git apart from other tools is how it thinks about data. Instead of storing changes to files, Git thinks of its data as a series of snapshots of your project, means, every time you make a change and save it (commit), Git takes a snapshot of all your files at that moment. If a file hasn't changed, Git just keeps a link to the previous identical file. -#### Local Operations: +#### Local Operations With Git, most things you do don't need a connection to a server. Because you have the entire project history on your computer, operations are super fast. You can browse project history or see changes between versions without waiting for a server. -#### Data Integrity: +#### Data Integrity Git makes sure nothing gets lost or corrupted. Every file and directory is checksummed, and Git knows if anything changes. Git uses a SHA-1 hash, a unique code for each version of a file. If any changes are made to the content, even a single character, it will result in a different SHA-1 hash. -#### Append-Only Model: +#### Append-Only Model In Git, almost everything adds data to the project, making it hard to accidentally lose information. Once you commit changes, they are safely stored. Experimenting is less risky with Git. @@ -122,7 +122,7 @@ To view all configuration settings and their sources/origins: $ git config --list --show-origin ``` -#### How to Configure your identity in Git: +#### How to Configure your identity in Git Identity in Git is used for attributing commits properly. Let's set up your user name and email address. @@ -153,7 +153,7 @@ Make sure you provide the correct path to the executable file of your text edito By the way, these – `"-multiInst -notabbar -nosession -noPlugin"` – are options used to customize the behavior of Notepad++ when it is launched by Git. -#### How to Change default branch name in Git (optional): +#### How to Change default branch name in Git (optional) By default, when you initialize a new repository with `git init`, Git creates a branch named `master`. But from Git version 2.28 onwards, you have the option to set a different name for the initial branch. @@ -163,7 +163,7 @@ $ git config --global init.defaultBranch main changes the default branch name to 'main' globally -#### How to Check Configuration/settings in Git: +#### How to Check Configuration/settings in Git You can view your Git configuration using: @@ -224,7 +224,7 @@ $ git commit -m 'Initial commit' `git add` adds files to the staging area indicating that you want to include them in the next commit, and then commit the changes. The `-m` flag allows you to add a descriptive message to the commit. -### 2\. How to Clone an Existing Repository in Git: +### 2. How to Clone an Existing Repository in Git The second way to obtain a Git repository is by cloning an existing one. This is useful when you want to work on a project that already exists elsewhere (for example, a project you'd like to contribute to). @@ -256,7 +256,7 @@ Now that you have a Git repository set up, you'll often need to make changes and pic credit - https://git-scm.com/ -### 1\. How to Check the Status of Your Files in Git: +### 1. How to Check the Status of Your Files in Git When working with a Git repository, it's crucial to understand the status of your files. @@ -327,7 +327,7 @@ Here are some patterns you can use to work more effectively in Git. - ****Target individual files or file extensions precisely:**** For example, `test.txt` ignores only that specific file, while `*.log` ignores all files ending with `.log`. - ****Wildcards for broader matches:**** The asterisk (`*`) wildcard matches any number of characters. For example, `*.doc` ignores all files with the `.doc` extension, regardless of their name. -### 5\. How to View Changes in Git: +### 5. How to View Changes in Git If you want to see the exact changes you've made to your files before committing, you can use the `git diff` command. @@ -345,7 +345,7 @@ $ git diff --cached README.md `git diff` provides a detailed view of the actual modifications. Use `git diff ` to focus on changes within a particular file. -### 6\. How to Commit Changes: +### 6. How to Commit Changes When you are ready to commit your changes, use the `git commit` command. This opens your text editor for you to provide a commit message. Alternatively, you can use the `-m` flag to add a commit message directly: @@ -355,7 +355,7 @@ Once you have staged the changes you want to include in the commit, you can comm $ git commit -m "Your commit message here" ``` -### 7\. How to Remove Files in Git: +### 7. How to Remove Files in Git If you need to remove a file from Git's tracking, you can use `git rm`. It remove the file from both the repository and working directory. Suppose you want to remove a file named `temp.txt`: @@ -369,7 +369,7 @@ If you only want to remove it from the repository but keep it in the working dir $ git rm --cached temp.txt ``` -### 8\. How to Move (or Rename) Files in Git: +### 8. How to Move (or Rename) Files in Git Git doesn't explicitly track file movements. But you can use `git mv` to rename or move files within your repository. For example, to rename `old_file.txt` to `new_file.txt`: @@ -390,7 +390,7 @@ After creating multiple commits or cloning a repository, the `git log` command a By default, it lists commits in reverse chronological order, displaying each commit with its SHA-1 checksum, author's name and email, date, and commit message. Now let's see how can we enhance this output: -### How to View Commit Differences in Git: +### How to View Commit Differences in Git To view the difference introduced in each commit, you can use the `-p` or `--patch` option: @@ -398,7 +398,7 @@ To view the difference introduced in each commit, you can use the `-p` or `--pat $ git log -p -2 # -2 is used to view the differences introduced in each of the last two commits ``` -### How to Display Statistics in Git: +### How to Display Statistics in Git The `--stat` option provides summarized statistics for each commit, including the modified files, lines added/deleted, and a summary. @@ -406,7 +406,7 @@ The `--stat` option provides summarized statistics for each commit, including th $ git log --stat ``` -### How to Customize Git Log Output Format: +### How to Customize Git Log Output Format The `--pretty` option allows you to alter the log output format. Various options are available for different formats: @@ -440,7 +440,7 @@ Using `--graph`, you can also visualize branch and merge history. $ git log --pretty=format:"%h %s" --graph ``` -### How to Limit Git Log Output: +### How to Limit Git Log Output In addition to formatting options, `git log` offers various limiting options to refine the displayed commit history. @@ -790,7 +790,7 @@ A branch is a lightweight, movable pointer to a commit. The default branch name Creating and switching between branches allows you to work on different features simultaneously. -### How to Create a New Branch in Git: +### How to Create a New Branch in Git When you want to start working on a new feature or experiment with an idea, you can create a new branch in Git. This new branch serves as a separate line of development, allowing you to make changes without affecting the main branch. @@ -816,7 +816,7 @@ This will display a list of branches with an asterisk (\*) indicating the curren $ git branch -v ``` -### How to Switch to Another Branch in Git: +### How to Switch to Another Branch in Git To switch to an existing different branch, use `git checkout`. @@ -837,7 +837,7 @@ In Git version 2.23 onwards, you can use `git switch` instead of `git checkout`. - Switch to an existing branch: `git switch existing-branch`. - Create and switch to new branch: `git switch -c new-branch`. -### How to Visualize Branches in Git: +### How to Visualize Branches in Git After creating and switching branches, you can visualize the branch structure using: @@ -936,11 +936,11 @@ This is **different from `$ git config --global init.defaultBranch main`** that Let's understand branches in more detail and look at a common branching workflow that is used in large projects. -### Long-Running Branches: +### Long-Running Branches In Git, long-running branches are branches that remain open over an extended period. -### Topic Branches: +### Topic Branches `Topic`/`Feature` branches are short-lived branches created for specific features or pieces of work. Unlike long-running branches, which persist over time, topic branches are created, used, and often deleted once the work is complete. @@ -966,7 +966,7 @@ In Git, when you're working with branches, there are two primary ways to integra Unlike merging, which can create a cluttered history with multiple merge commits, rebasing produces a linear history, making it easier to understand the sequence of changes made over time. -### Basic Rebase Example: +### Basic Rebase Example Imagine you're working on a project with two branches: "feature" and "master". You've made some commits on the "feature" branch and now want to integrate these changes into the "master" branch using rebasing. @@ -1006,12 +1006,12 @@ Now, your project history appears linear, reflecting the sequential integration ### Rebasing vs Merging: Which is Better? -#### Rebasing Use Cases: +#### Rebasing Use Cases - Suitable for feature branches that need a clean integration into the mainline branch. - Preferred for open-source contributions where a clean commit history is valued. -#### Merging Use Cases: +#### Merging Use Cases - Appropriate for collaborative environments where transparency in the project's development process is crucial. - Useful for projects where maintaining an accurate historical record is a priority. diff --git a/chinese/articles/learning-go-from-zero-to-hero.md b/chinese/articles/learning-go-from-zero-to-hero.md index 8fc0613c6..5a46402fd 100644 --- a/chinese/articles/learning-go-from-zero-to-hero.md +++ b/chinese/articles/learning-go-from-zero-to-hero.md @@ -1,4 +1,4 @@ -> - 原文地址:[Learning Go — from zero to hero](https://www.freecodecamp.org/news/learning-go-from-zero-to-hero-d2a3223b3d86/) +> - 原文地址:[Learning Go—from zero to hero](https://www.freecodecamp.org/news/learning-go-from-zero-to-hero-d2a3223b3d86/) > - 原文作者:[Milap Neupane](https://www.freecodecamp.org/news/author/milapneupane/) > - 译者:[luojiyin](https://github.com/luojiyin1987) > - 校对者: diff --git a/chinese/articles/procedural-macros-in-rust.md b/chinese/articles/procedural-macros-in-rust.md index 27fd7aa90..2d10047aa 100644 --- a/chinese/articles/procedural-macros-in-rust.md +++ b/chinese/articles/procedural-macros-in-rust.md @@ -296,9 +296,9 @@ This does create a problem though. You need to be able to make sense of this "st We can, however, rely on great open source work done by many developers to ease this for us. You need to add a few dependencies to help with this problem: -- `syn` — A syntax parser for Rust. This helps you to parse the input token stream as Rust AST. AST is a concept that you mostly run into when trying to write your own interpreter or compiler, but a basic understanding is essential for working with macros. Macros, after all, are just extensions that you write for the compiler in a sense. If you’re interested in learning more about what ASTs are, [check out this very helpful introduction][57]. -- `quote` — quote is, and this is a huge generalisation, a crate that helps us perform the reverse operation of what `syn` does. It helps us convert Rust source code into a stream of tokens that we can output from our macro. -- `proc-macro2` — The standard library provides a `proc-macro` crate, but the types it provides cannot exist outside of procedural macros. `proc-macro2` is a wrapper around the standard library that makes all of the internal types usable outside of the context of macros. This, for example, allows both `syn` and `quote` to not only be used for procedural macros, but in regular Rust code as well, should you ever have such a need. And we will indeed be using that extensively if we ever want to unit test our macros or their expansions. +- `syn`—A syntax parser for Rust. This helps you to parse the input token stream as Rust AST. AST is a concept that you mostly run into when trying to write your own interpreter or compiler, but a basic understanding is essential for working with macros. Macros, after all, are just extensions that you write for the compiler in a sense. If you’re interested in learning more about what ASTs are, [check out this very helpful introduction][57]. +- `quote`—quote is, and this is a huge generalisation, a crate that helps us perform the reverse operation of what `syn` does. It helps us convert Rust source code into a stream of tokens that we can output from our macro. +- `proc-macro2`—The standard library provides a `proc-macro` crate, but the types it provides cannot exist outside of procedural macros. `proc-macro2` is a wrapper around the standard library that makes all of the internal types usable outside of the context of macros. This, for example, allows both `syn` and `quote` to not only be used for procedural macros, but in regular Rust code as well, should you ever have such a need. And we will indeed be using that extensively if we ever want to unit test our macros or their expansions. - `darling`–It facilitates parsing and working with macro arguments, which is otherwise a tedious process due to having to manually parse it from the syntax tree. `darling` provides us with `serde`\-like ability to automatically parse input argument tree into our arguments struct. It also helps us in error handling around invalid arguments, required arguments, and so on. While these projects are contributed to by many developers, I want to give special thanks to [David Tolnay][58]. He's a legend in the Rust community and is the creator of most of these projects, and many many more open source crates in Rust. From aa22d9717990086ae91d33b69177bddc26d3e25f Mon Sep 17 00:00:00 2001 From: luojiyin1987 Date: Fri, 28 Jun 2024 04:24:24 +0000 Subject: [PATCH 15/15] Auto Format --- chinese/articles/coding-bootcamp-handbook.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chinese/articles/coding-bootcamp-handbook.md b/chinese/articles/coding-bootcamp-handbook.md index 62d9aff9b..d6766fa51 100644 --- a/chinese/articles/coding-bootcamp-handbook.md +++ b/chinese/articles/coding-bootcamp-handbook.md @@ -389,7 +389,7 @@ Surprisingly, there are a few bootcamps that are for-profit but still free. And 要了解参加编码训练营的真实成本,你应该考虑机会成本。 -**例子**:你现在每个月赚$3000美元。你搬到旧金山,在那$2,000 美元只能租到一个卧室。你参加 12 周的训练营费用是\$15,00 0美元。 +**例子**:你现在每个月赚$3000美元。你搬到旧金山,在那$2,000 美元只能租到一个卧室。你参加 12 周的训练营费用是\$15,00 0美元。 这是你的真实成本,假设加上你在 6 个月的时间内找到工作并领取第一份薪水: